# Form

<figure><img src="https://raw.githubusercontent.com/akkshayTandon/react-hartan/main/images/form.png" alt="" width="188"><figcaption><p>Preview</p></figcaption></figure>

### Usage

> ```bash
> npm i react-hartan
> ```

```jsx
import { Form } from "react-hartan"

function App() {

  const [updateData, submit, submitted, returnValue] = useForm("");

  return (
    <>
      <Form updateData={updateData} submit={submit} submitted={submitted}></Form>
    </>
  )
}

export default App
```

### Customization With Props

* `fields`  -> Required to be sent by the user, accepts an **object,** of the following structure:

```javascript
{
    inputTag: [
        {
            inputType: "", // string
            inputId: "", // string
            inputName: "", // string
            inputLabel: "", // string
            required: true // boolean
        },
    ],
    textareaTag: [
        {
            textareaId: "", // string
            textareaName: "", // string
            textareaLabel: "", // string
            required: true // boolean
        }
    ]
}
```

{% hint style="info" %}
NOTE:  Keep the name of the keys same as above.
{% endhint %}

* `formTitle`  -> Accepts a string value, used as the form heading.
* `updateData`  -> Accepts a function provided by the [useForm](https://hartans-organization.gitbook.io/hartan-docs/hooks/useform) hook but it should be passed down from the user for updating form fields.
* `submit` -> Accepts a function provided by the [useForm](https://hartans-organization.gitbook.io/hartan-docs/hooks/useform) hook but it should be passed down from the user for submitting the form data.
* `submitted` -> Accepts a state value provided by the [useForm](https://hartans-organization.gitbook.io/hartan-docs/hooks/useform) hook but it should be passed down from the user to show the submitted animation.
* `id` -> The id prop is similar to the id attribute in HTML. It allows to provide overall component id.
* `userFormCardStyle`  -> Accepts class name(s) as string, custom styling prop for the fullthe full form card container.
* `userTitleStyle`  -> Accepts class name(s) as string, custom styling prop for the heading of the form inside form card.
* `userFormStyle`  -> Accepts class name(s) as string, custom styling prop for the form container inside form card.
* `userInputFieldStyle`  -> Accepts class name(s) as string, custom styling prop for the input fields container.
* `userSubmittedStyle`  -> Accepts class name(s) as string, custom styling prop for the submitted container.
* `userSubmittedSVGStyle`  -> Accepts class name(s) as string, custom styling prop for the submitted svg.

{% tabs %}
{% tab title="Default" %}
{% code overflow="wrap" %}

```jsx
import { Form } from "react-hartan"

function App() {

  const [updateData, submit, submitted, returnValue] = useForm("");
  
  return (
    <>
      <Form updateData={updateData} submit={submit} submitted={submitted}></Form>
    </>
  )
}

export default App
```

{% endcode %}
{% endtab %}

{% tab title="With Custom Props" %}
{% code overflow="wrap" %}

```jsx
// App.css
.m-2{
   margin: 2rem;
}

.bg-pink{
   background-color: pink;
}

.my-class{
   font-size: 2rem;
   background-color: red;
   padding: 1rem;
}


// App.jsx
import { Form } from "react-hartan"

export default function App() {

   const [updateData, submit, submitted, returnValue] = useForm("");

  return (
    <>
      <Form updateData={updateData} submit={submit} submitted={submitted} userFormCardStyle={"my-class"} userFormStyle={"bg-pink"} userInputFieldStyle={"m-2"}></Form>
    </>
  )
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Component Code

This is the code for Form component.

{% tabs %}
{% tab title="Form.jsx" %}
{% code overflow="wrap" %}

```jsx
import formStyle from "./Form.module.css"
import PropTypes from "prop-types"

const fieldsData = {
    inputTag: [
        {
            inputType: "text",
            inputId: "name",
            inputName: "name",
            inputLabel: "Name",
            required: true
        },
        {
            inputType: "email",
            inputId: "email",
            inputName: "email",
            inputLabel: "Email",
            required: true
        },
        {
            inputType: "number",
            inputId: "phoneNo",
            inputName: "phoneNo",
            inputLabel: "Contact Number",
            required: true
        }
    ],
    textareaTag: [
        {
            textareaId: "message",
            textareaName: "message",
            textareaLabel: "Message",
            required: true
        }
    ]
};


export default function Form({ fields = fieldsData, formTitle = "Leave a Comment", updateData, submit, submitted, id, userFormCardStyle, userTitleStyle, userFormStyle, userInputFieldStyle, userSubmittedStyle, userSubmittedSVGstyle }) {


    return (
        <div className={`${formStyle.formCard} ${userFormCardStyle}`}>
            <span className={`${formStyle.title} ${userTitleStyle}`}>{formTitle}</span>

            <form className={`${formStyle.form} ${userFormStyle}`} onSubmit={submit}>

                {
                    fields.inputTag.map((field, id) => {
                        return (
                            <div className={`${formStyle.group} ${userInputFieldStyle}`} key={id}>
                                <input placeholder="" type={field.inputType} name={field.inputName} id={field.inputId} required={field.required === true} onChange={updateData} />
                                <label htmlFor={field.inputId}>{field.inputLabel}</label>
                            </div>
                        )
                    })
                }

                {
                    fields.textareaTag.map((textarea, id) => {
                        return (
                            <div className={`${formStyle.group} ${userInputFieldStyle}`} key={id}>
                                <textarea placeholder="" id={textarea.textareaId} name={textarea.textareaName} required={textarea.required === true} onChange={updateData}></textarea>
                                <label htmlFor={textarea.textareaId}>{textarea.textareaLabel}</label>
                            </div>
                        )
                    })
                }

                <button type="submit">Submit</button>
            </form>

            {
                submitted &&
                <div className={`${formStyle.submitted} ${userSubmittedStyle}`}>
                    <svg className={`${formStyle.submittedSVG} ${userSubmittedSVGstyle}`} xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="100" height="100" viewBox="0 0 40 40">
                        <path fill="#98ccfd" d="M20,38.5C9.8,38.5,1.5,30.2,1.5,20S9.8,1.5,20,1.5S38.5,9.8,38.5,20S30.2,38.5,20,38.5z"></path><path fill="none" stroke="#4788c7" strokeMiterlimit="10" d="M20,38.5C9.8,38.5,1.5,30.2,1.5,20S9.8,1.5,20,1.5S38.5,9.8,38.5,20S30.2,38.5,20,38.5z"></path><path fill="none" stroke="#fff" strokeMiterlimit="10" strokeWidth="2" d="M11,20l6,6l13-13"></path>
                    </svg>
                </div>
            }
        </div>
    )
}

Form.propTypes = {
    fields: PropTypes.shape({
        inputTag: PropTypes.arrayOf(PropTypes.shape({
            inputType: PropTypes.string,
            inputId: PropTypes.string,
            inputName: PropTypes.string,
            inputLabel: PropTypes.string,
            required: PropTypes.bool
        })),
        textareaTag: PropTypes.arrayOf(PropTypes.shape({
            textareaId: PropTypes.string,
            textareaName: PropTypes.string,
            textareaLabel: PropTypes.string,
            required: PropTypes.bool
        }))
    }),
    formTitle: PropTypes.string,
    id: PropTypes.string,
    userFormCardStyle: PropTypes.string,
    userTitleStyle: PropTypes.string,
    userFormStyle: PropTypes.string,
    userInputFieldStyle: PropTypes.string,
    userSubmittedStyle: PropTypes.string,
    userSubmittedSVGstyle: PropTypes.string
};
```

{% endcode %}
{% endtab %}

{% tab title="Form.module.css" %}
{% code overflow="wrap" %}

```css
/* Form Styling */

/* the full form component container */
.formCard {
    background-color: #fff;
    border-radius: 1rem;
    padding: 2rem;
    width: 40rem;
    display: flex;
    flex-direction: column;
    box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;

}

/* the heading of the form inside form card */
.title {
    font-size: 2.5rem;
    font-weight: 600;
    text-align: center;
}

/* the form container inside form card */
.form {
    margin-top: 2rem;
    display: flex;
    flex-direction: column;
}

.group {
    position: relative;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.form .group label {
    font-size: 1.5rem;
    color: rgb(99, 102, 102);
    position: absolute;
    top: -1rem;
    left: 1rem;
    background-color: #fff;
    transition: all .3s ease;
}

.form .group input,
.form .group textarea {
    padding: 1rem;
    border-radius: .5rem;
    border: .1rem solid rgba(0, 0, 0, 0.2);
    margin-bottom: 2rem;
    outline: 0;
    width: 100%;
    background-color: transparent;
}

.form .group input:placeholder-shown+label,
.form .group textarea:placeholder-shown+label {
    top: 1rem;
    background-color: transparent;
}

.form .group input:focus,
.form .group textarea:focus {
    border-color: #1e90ff;
}

.form .group input:focus+label,
.form .group textarea:focus+label {
    top: -1rem;
    left: 1rem;
    background-color: #fff;
    color: #1e90ff;
    font-weight: 600;
    font-size: 1.5rem;
}

.form .group textarea {
    resize: none;
    height: 100px;
}

.form button {
    background-color: #1e90ff;
    color: #fff;
    border: none;
    border-radius: .5rem;
    padding: 1rem;
    font-size: 1.5rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
}

.form button:hover {
    background: linear-gradient(90deg, rgba(30, 144, 255, 1) 0%, rgba(0, 212, 255, 1) 100%);

}

/* the container shown  when user submits the form */
.submitted {
    display: flex;
    justify-content: center;
    align-items: center;
    position: fixed;
    background-color: #ffffff;
    height: 33rem;
    width: 36rem;
}

/* the suuccess logo inside the submitted container */
.submittedSVG {
    animation: slide-in .5s;
}

@keyframes slide-in {
    0% {
        transform: scale(0);
    }

    50% {
        transform: scale(1.3);
    }

    100% {
        transform: scale(1);
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
