Skip to content

Commit

Permalink
Add an auto submit form
Browse files Browse the repository at this point in the history
  • Loading branch information
gnoha committed Jan 31, 2025
1 parent 3f44f92 commit 5052831
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/components/autoSubmitForm/AutoSubmitForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Meta, StoryObj } from '@storybook/react'
import { AutoSubmitForm } from './AutoSubmitForm'
import { Select } from '../select'
import * as yup from 'yup'
import { FormikHelpers } from 'formik'
import { useState } from 'react'
const meta = {
title: 'Components/AutoSubmitForm',
component: AutoSubmitForm<FooValues>,
} satisfies Meta<typeof AutoSubmitForm<FooValues>>

export default meta
type Story = StoryObj<typeof meta>

type FooValues = {
plan_type: string
line_of_business: string
}

export const Default: Story = {
args: {
initialValues: { plan_type: '', line_of_business: '' },
validationSchema: yup.object({
plan_type: yup.string().required(),
line_of_business: yup.string().required(),
}),
onSubmit: (values) => console.log({ values }),
children: (
<div className="flex flex-col gap-4">
<Select
name="plan_type"
placeholder="Select a plan type"
allowClear={true}
options={[
{ label: 'HMO', value: 'hmo' },
{ label: 'HMO SNP', value: 'hmo_snp' },
{ label: 'HMO-POS', value: 'hmo_pos' },
{ label: 'HMO D-SNP', value: 'hmo_d_snp' },
{ label: 'PPO', value: 'ppo' },
{ label: 'PPO SNP', value: 'ppo_snp' },
{ label: 'PFFS', value: 'pffs' },
{ label: 'MSA', value: 'msa' },
{ label: 'Cost Plan', value: 'cost_plan' },
{ label: 'PACE', value: 'pace' },
]}
/>
<Select
name="line_of_business"
placeholder="Select a line of business"
allowClear={true}
options={[
{ label: 'Medicare Advantage', value: 'medicare_advantage' },
{ label: 'Affordable Care Act', value: 'affordable_care_act' },
]}
/>
</div>
),
},
render: (args) => {
const [formValues, setFormValues] = useState<FooValues>(args.initialValues)
const handleSubmit = (
values: FooValues,
formikHelpers: FormikHelpers<FooValues>
) => {
setFormValues(values)
args.onSubmit(values, formikHelpers)
}

return (
<div className="flex flex-col gap-4">
<AutoSubmitForm {...args} onSubmit={handleSubmit} />
<div>
<h3>Form Values</h3>
<pre>{JSON.stringify(formValues, null, 2)}</pre>
</div>
</div>
)
},
}
35 changes: 35 additions & 0 deletions src/components/autoSubmitForm/AutoSubmitForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react'
import { Formik, FormikConfig, FormikValues, useFormikContext } from 'formik'
import { ReactNode } from 'react'

type Props<T extends FormikValues> = FormikConfig<T> & {
children: ReactNode
}

export const AutoSubmitForm = <T extends FormikValues>({
children,
onSubmit,
initialValues,
...props
}: Props<T>) => {
return (
<Formik<T> initialValues={initialValues} onSubmit={onSubmit} {...props}>
<FormFieldsContainer>{children}</FormFieldsContainer>
</Formik>
)
}

type FormFieldsContainerProps = {
children: ReactNode
}
export const FormFieldsContainer = ({ children }: FormFieldsContainerProps) => {
const { values, isValid, dirty, submitForm } = useFormikContext()

React.useEffect(() => {
if (isValid && dirty) {
submitForm()
}
}, [isValid, dirty, JSON.stringify(values)])

return <>{children}</>
}
8 changes: 8 additions & 0 deletions src/components/autoSubmitForm/Form.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.ant-form-item .ant-form-item-label > label {
align-items: start;
padding-top: 8px;

&::before {
margin-top: 6px;
}
}
1 change: 1 addition & 0 deletions src/components/autoSubmitForm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AutoSubmitForm } from './AutoSubmitForm'

0 comments on commit 5052831

Please sign in to comment.