From d4045fbcbfa8208ec31539744417f315f1f6fad8 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Tue, 21 Nov 2023 19:01:18 +0100
Subject: refactor(components): split Layout component in smaller components

The previous component was too long and hardly readable. So I splitted
it in different part and added tests.
---
 .../organisms/forms/search-form/search-form.tsx    | 119 +++++++++++----------
 1 file changed, 61 insertions(+), 58 deletions(-)

(limited to 'src/components/organisms/forms/search-form/search-form.tsx')

diff --git a/src/components/organisms/forms/search-form/search-form.tsx b/src/components/organisms/forms/search-form/search-form.tsx
index 3d0efa2..a803d8c 100644
--- a/src/components/organisms/forms/search-form/search-form.tsx
+++ b/src/components/organisms/forms/search-form/search-form.tsx
@@ -4,17 +4,11 @@ import {
   useId,
   useImperativeHandle,
   useRef,
+  type HTMLAttributes,
 } from 'react';
 import { useIntl } from 'react-intl';
 import { type FormSubmitHandler, useForm } from '../../../../utils/hooks';
-import {
-  Button,
-  Form,
-  type FormProps,
-  Icon,
-  Input,
-  Label,
-} from '../../../atoms';
+import { Button, Form, Icon, Input, Label, Notice } from '../../../atoms';
 import { LabelledField } from '../../../molecules';
 import styles from './search-form.module.scss';
 
@@ -22,7 +16,10 @@ export type SearchFormData = { query: string };
 
 export type SearchFormSubmit = FormSubmitHandler<SearchFormData>;
 
-export type SearchFormProps = Omit<FormProps, 'children' | 'onSubmit'> & {
+export type SearchFormProps = Omit<
+  HTMLAttributes<HTMLDivElement>,
+  'children' | 'onSubmit'
+> & {
   /**
    * Should the label be visually hidden?
    *
@@ -45,19 +42,18 @@ export type SearchFormRef = {
 const SearchFormWithRef: ForwardRefRenderFunction<
   SearchFormRef,
   SearchFormProps
-> = ({ className = '', isLabelHidden = false, onSubmit, ...props }, ref) => {
+> = ({ isLabelHidden = false, onSubmit, ...props }, ref) => {
   const intl = useIntl();
-  const { values, submit, submitStatus, update } = useForm<SearchFormData>({
-    initialValues: { query: '' },
-    submitHandler: onSubmit,
-  });
+  const { messages, submit, submitStatus, update, values } =
+    useForm<SearchFormData>({
+      initialValues: { query: '' },
+      submitHandler: onSubmit,
+    });
   const id = useId();
   const inputRef = useRef<HTMLInputElement>(null);
-  const formClass = [
-    styles.wrapper,
-    styles[isLabelHidden ? 'wrapper--no-label' : 'wrapper--has-label'],
-    className,
-  ].join(' ');
+  const formClass = `${styles.form} ${
+    styles[isLabelHidden ? 'form--no-label' : 'form--has-label']
+  }`;
   const labels = {
     button: intl.formatMessage({
       defaultMessage: 'Search',
@@ -84,48 +80,55 @@ const SearchFormWithRef: ForwardRefRenderFunction<
   );
 
   return (
-    <Form {...props} className={formClass} onSubmit={submit}>
-      <LabelledField
-        className={styles.field}
-        field={
-          <Input
-            className={styles.input}
-            id={id}
+    <div {...props}>
+      <Form className={formClass} onSubmit={submit}>
+        <LabelledField
+          className={styles.field}
+          field={
+            <Input
+              className={styles.input}
+              id={id}
+              // eslint-disable-next-line react/jsx-no-literals
+              name="query"
+              onChange={update}
+              ref={inputRef}
+              // eslint-disable-next-line react/jsx-no-literals
+              type="search"
+              value={values.query}
+            />
+          }
+          label={
+            <Label htmlFor={id} isHidden={isLabelHidden}>
+              {labels.field}
+            </Label>
+          }
+        />
+        <Button
+          aria-label={labels.button}
+          className={styles.btn}
+          isLoading={submitStatus === 'PENDING'}
+          // eslint-disable-next-line react/jsx-no-literals
+          kind="neutral"
+          // eslint-disable-next-line react/jsx-no-literals
+          shape="initial"
+          type="submit"
+        >
+          <Icon
+            aria-hidden
+            className={styles.icon}
             // eslint-disable-next-line react/jsx-no-literals
-            name="query"
-            onChange={update}
-            ref={inputRef}
+            shape="magnifying-glass"
             // eslint-disable-next-line react/jsx-no-literals
-            type="search"
-            value={values.query}
+            size="lg"
           />
-        }
-        label={
-          <Label htmlFor={id} isHidden={isLabelHidden}>
-            {labels.field}
-          </Label>
-        }
-      />
-      <Button
-        aria-label={labels.button}
-        className={styles.btn}
-        isLoading={submitStatus === 'PENDING'}
-        // eslint-disable-next-line react/jsx-no-literals
-        kind="neutral"
-        // eslint-disable-next-line react/jsx-no-literals
-        shape="initial"
-        type="submit"
-      >
-        <Icon
-          aria-hidden
-          className={styles.icon}
-          // eslint-disable-next-line react/jsx-no-literals
-          shape="magnifying-glass"
-          // eslint-disable-next-line react/jsx-no-literals
-          size="lg"
-        />
-      </Button>
-    </Form>
+        </Button>
+      </Form>
+      {messages?.error && submitStatus === 'FAILED' ? (
+        <Notice className={styles.notice} kind="error">
+          {messages.error}
+        </Notice>
+      ) : null}
+    </div>
   );
 };
 
-- 
cgit v1.2.3

