aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/forms/search-form/search-form.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/organisms/forms/search-form/search-form.tsx')
-rw-r--r--src/components/organisms/forms/search-form/search-form.tsx98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/components/organisms/forms/search-form/search-form.tsx b/src/components/organisms/forms/search-form/search-form.tsx
new file mode 100644
index 0000000..826e6c8
--- /dev/null
+++ b/src/components/organisms/forms/search-form/search-form.tsx
@@ -0,0 +1,98 @@
+import { useRouter } from 'next/router';
+import {
+ ChangeEvent,
+ FormEvent,
+ forwardRef,
+ ForwardRefRenderFunction,
+ useId,
+ useState,
+} from 'react';
+import { useIntl } from 'react-intl';
+import { Button, Form, Input, Label, MagnifyingGlass } from '../../../atoms';
+import { LabelledField } from '../../../molecules';
+import styles from './search-form.module.scss';
+
+export type SearchFormProps = {
+ /**
+ * Should the label be visually hidden?
+ *
+ * @default false
+ */
+ isLabelHidden?: boolean;
+ /**
+ * The search page url.
+ */
+ searchPage: string;
+};
+
+const SearchFormWithRef: ForwardRefRenderFunction<
+ HTMLInputElement,
+ SearchFormProps
+> = ({ isLabelHidden = false, searchPage }, ref) => {
+ const intl = useIntl();
+ const fieldLabel = intl.formatMessage({
+ defaultMessage: 'Search for:',
+ description: 'SearchForm: field accessible label',
+ id: 'X8oujO',
+ });
+ const buttonLabel = intl.formatMessage({
+ defaultMessage: 'Search',
+ description: 'SearchForm: button accessible name',
+ id: 'WMqQrv',
+ });
+
+ const router = useRouter();
+ const [value, setValue] = useState<string>('');
+
+ const submitHandler = (e: FormEvent) => {
+ e.preventDefault();
+ router.push({ pathname: searchPage, query: { s: value } });
+ setValue('');
+ };
+
+ const updateForm = (e: ChangeEvent<HTMLInputElement>) => {
+ setValue(e.target.value);
+ };
+
+ const id = useId();
+
+ return (
+ <Form className={styles.wrapper} onSubmit={submitHandler}>
+ <LabelledField
+ className={styles.field}
+ field={
+ <Input
+ className={styles.field}
+ id={`search-form-${id}`}
+ name="search-form"
+ onChange={updateForm}
+ ref={ref}
+ type="search"
+ value={value}
+ />
+ }
+ label={
+ <Label htmlFor={`search-form-${id}`} isHidden={isLabelHidden}>
+ {fieldLabel}
+ </Label>
+ }
+ />
+ <Button
+ aria-label={buttonLabel}
+ className={styles.btn}
+ kind="neutral"
+ shape="initial"
+ type="submit"
+ >
+ <MagnifyingGlass className={styles.btn__icon} />
+ </Button>
+ </Form>
+ );
+};
+
+/**
+ * SearchForm component
+ *
+ * Render a search form.
+ */
+export const SearchForm = forwardRef(SearchFormWithRef);