From 5f1128e451e4451d1eec37d881cf3f8106fd6f5d Mon Sep 17 00:00:00 2001
From: jerembdn <work@jeremybdn.fr>
Date: Thu, 11 Jan 2024 15:53:17 +0100
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20add=20forwardref=20to=20input=20com?=
 =?UTF-8?q?ponent?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .changeset/moody-mirrors-itch.md              |  5 ++
 .../kitchen/src/components/Input/index.tsx    | 63 +++++++++++--------
 workshop/pages/input.tsx                      | 33 +++++++++-
 3 files changed, 71 insertions(+), 30 deletions(-)
 create mode 100644 .changeset/moody-mirrors-itch.md

diff --git a/.changeset/moody-mirrors-itch.md b/.changeset/moody-mirrors-itch.md
new file mode 100644
index 000000000..bd3a5b8d1
--- /dev/null
+++ b/.changeset/moody-mirrors-itch.md
@@ -0,0 +1,5 @@
+---
+"@tonightpass/kitchen": patch
+---
+
+Set forwardRef to Input component
diff --git a/packages/kitchen/src/components/Input/index.tsx b/packages/kitchen/src/components/Input/index.tsx
index b61a9d67f..5e4f255f8 100644
--- a/packages/kitchen/src/components/Input/index.tsx
+++ b/packages/kitchen/src/components/Input/index.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { forwardRef, useImperativeHandle } from "react";
 import { RiCloseCircleLine } from "react-icons/ri";
 import styled from "styled-components";
 
@@ -47,31 +47,34 @@ export type InputProps = KitchenComponent<
   React.InputHTMLAttributes<HTMLInputElement>
 >;
 
-const Input = styled(
-  ({
-    size = "normal",
-    prefix,
-    suffix,
-    disabled = false,
-    prefixContainer = true,
-    suffixContainer = true,
-    prefixStyling = true,
-    suffixStyling = true,
-    clearable = false,
-    value,
-    initialValue = "",
-    readOnly = false,
-    onChange,
-    width,
-    onClearClick,
-    onFocus,
-    onBlur,
-    error,
-    type,
-    label,
-    ...props
-  }: InputProps) => {
-    const inputRef = React.useRef<HTMLInputElement>();
+const ForwardedInput = forwardRef<HTMLInputElement, InputProps>(
+  (
+    {
+      size = "normal",
+      prefix,
+      suffix,
+      disabled = false,
+      prefixContainer = true,
+      suffixContainer = true,
+      prefixStyling = true,
+      suffixStyling = true,
+      clearable = false,
+      value,
+      initialValue = "",
+      readOnly = false,
+      onChange,
+      width,
+      onClearClick,
+      onFocus,
+      onBlur,
+      error,
+      type,
+      label,
+      ...props
+    }: InputProps,
+    ref: React.Ref<HTMLInputElement>,
+  ) => {
+    const inputRef = React.useRef<HTMLInputElement>(null);
     const [selfValue, setSelfValue] = React.useState<string>(initialValue);
     const [focus, setFocus] = React.useState<boolean>(false);
     const [clearIconHover, setClearIconHover] = React.useState<boolean>(false);
@@ -80,6 +83,8 @@ const Input = styled(
       [value],
     );
 
+    useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);
+
     const Wrapper = label ? "label" : React.Fragment;
 
     const controlledValue = isControlledComponent
@@ -223,7 +228,11 @@ const Input = styled(
       </Wrapper>
     );
   },
-)`
+);
+
+ForwardedInput.displayName = "Input";
+
+const Input = styled(ForwardedInput)`
   font: inherit;
   width: 100%;
   min-width: 0;
diff --git a/workshop/pages/input.tsx b/workshop/pages/input.tsx
index 58dcf3558..b898ffcba 100644
--- a/workshop/pages/input.tsx
+++ b/workshop/pages/input.tsx
@@ -9,9 +9,19 @@ type FormData = {
 };
 
 const InputPage: NextPage = () => {
-  const { control, handleSubmit } = useForm<FormData>();
+  const { control, handleSubmit: handleSubmitControl } = useForm<FormData>();
 
-  const onSubmit = handleSubmit((data) => {
+  const onSubmitControl = handleSubmitControl((data) => {
+    console.log(data);
+  });
+
+  const {
+    register,
+    handleSubmit: handleSubmitRegistered,
+    formState: { isValid: isValidRegistered },
+  } = useForm<FormData>();
+
+  const onSubmitRegistered = handleSubmitRegistered((data) => {
     console.log(data);
   });
 
@@ -305,11 +315,28 @@ const InputPage: NextPage = () => {
           </Container>
         </Container>
 
+        <Container gap={5}>
+          <Text>{"registered"}</Text>
+          <Text>{`is valid : ${isValidRegistered}`}</Text>
+          <Container row>
+            <Container align={"flex-start"}>
+              <form onSubmit={onSubmitRegistered}>
+                <Input
+                  {...register("name", {
+                    required: true,
+                    maxLength: 20,
+                  })}
+                />
+              </form>
+            </Container>
+          </Container>
+        </Container>
+
         <Container gap={5}>
           <Text>{"controlled"}</Text>
           <Container row>
             <Container align={"flex-start"}>
-              <form onSubmit={onSubmit}>
+              <form onSubmit={onSubmitControl}>
                 <ControlledInput name={"name"} control={control} />
               </form>
             </Container>