From ec5777f526368bb18d848a056c5cc6b42e296e25 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 6 Mar 2024 14:48:00 +0100 Subject: [PATCH 1/7] [TS migration] Migrate Composer and DragAndDrop story --- src/components/DragAndDrop/Provider/types.ts | 2 +- ...mposer.stories.js => Composer.stories.tsx} | 27 +++++++++---------- ...rop.stories.js => DragAndDrop.stories.tsx} | 16 +++++------ src/styles/utils/index.ts | 2 +- 4 files changed, 22 insertions(+), 25 deletions(-) rename src/stories/{Composer.stories.js => Composer.stories.tsx} (78%) rename src/stories/{DragAndDrop.stories.js => DragAndDrop.stories.tsx} (85%) diff --git a/src/components/DragAndDrop/Provider/types.ts b/src/components/DragAndDrop/Provider/types.ts index b4394056cac5..57d0fb47c637 100644 --- a/src/components/DragAndDrop/Provider/types.ts +++ b/src/components/DragAndDrop/Provider/types.ts @@ -8,7 +8,7 @@ type DragAndDropProviderProps = { isDisabled?: boolean; /** Indicate that users are dragging file or not */ - setIsDraggingOver: (value: boolean) => void; + setIsDraggingOver?: (value: boolean) => void; }; type SetOnDropHandlerCallback = (event: DragEvent) => void; diff --git a/src/stories/Composer.stories.js b/src/stories/Composer.stories.tsx similarity index 78% rename from src/stories/Composer.stories.js rename to src/stories/Composer.stories.tsx index e4051a4ab72a..8cb3f297684e 100644 --- a/src/stories/Composer.stories.js +++ b/src/stories/Composer.stories.tsx @@ -1,16 +1,16 @@ +import type {ComponentMeta} from '@storybook/react'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import React, {useState} from 'react'; import {Image, View} from 'react-native'; import Composer from '@components/Composer'; +import type {ComposerProps} from '@components/Composer/types'; import RenderHTML from '@components/RenderHTML'; import Text from '@components/Text'; import withNavigationFallback from '@components/withNavigationFallback'; import useStyleUtils from '@hooks/useStyleUtils'; // eslint-disable-next-line no-restricted-imports -import {defaultStyles} from '@styles/index'; -// eslint-disable-next-line no-restricted-imports import {defaultTheme} from '@styles/theme'; -import CONST from '@src/CONST'; +import {defaultStyles} from '@src/styles'; const ComposerWithNavigation = withNavigationFallback(Composer); @@ -19,25 +19,25 @@ const ComposerWithNavigation = withNavigationFallback(Composer); * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/Composer', component: ComposerWithNavigation, }; const parser = new ExpensiMark(); -function Default(args) { +function Default(props: ComposerProps) { const StyleUtils = useStyleUtils(); - const [pastedFile, setPastedFile] = useState(null); - const [comment, setComment] = useState(args.defaultValue); - const renderedHTML = parser.replace(comment); + const [pastedFile, setPastedFile] = useState(null); + const [comment, setComment] = useState(props.defaultValue); + const renderedHTML = parser.replace(comment ?? ''); return ( - + Entered Comment (Drop Enabled) {comment} Rendered Comment - {Boolean(renderedHTML) && } - {Boolean(pastedFile) && ( + {!!renderedHTML && } + {!!pastedFile && ( = { title: 'Components/DragAndDrop', component: DragAndDropConsumer, }; function Default() { const [fileURL, setFileURL] = useState(''); + return ( { - const file = lodashGet(e, ['dataTransfer', 'files', 0]); - if (file && file.type.includes('image')) { + onDrop={(event) => { + const file = event.dataTransfer?.files?.[0]; + if (file?.type.includes('image')) { const reader = new FileReader(); - reader.addEventListener('load', () => setFileURL(reader.result)); + reader.addEventListener('load', () => setFileURL(reader.result as string)); reader.readAsDataURL(file); } }} diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 21af5398232f..014a40da017a 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -453,7 +453,7 @@ function getBackgroundColorWithOpacityStyle(backgroundColor: string, opacity: nu return {}; } -function getWidthAndHeightStyle(width: number, height?: number): ViewStyle { +function getWidthAndHeightStyle(width: number, height?: number): Pick { return { width, height: height ?? width, From 12a6bc4261c43a56dc054712119ed4cf8b10257f Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 6 Mar 2024 15:38:16 +0100 Subject: [PATCH 2/7] [TS migration] Migrate RadioButtonWithLabel story --- src/components/RadioButtonWithLabel.tsx | 2 ++ ...ories.js => RadioButtonWithLabel.stories.tsx} | 16 +++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) rename src/stories/{RadioButtonWithLabel.stories.js => RadioButtonWithLabel.stories.tsx} (60%) diff --git a/src/components/RadioButtonWithLabel.tsx b/src/components/RadioButtonWithLabel.tsx index cfcd6acba41f..9b93d7900772 100644 --- a/src/components/RadioButtonWithLabel.tsx +++ b/src/components/RadioButtonWithLabel.tsx @@ -72,3 +72,5 @@ function RadioButtonWithLabel({LabelComponent, style, label = '', hasError = fal RadioButtonWithLabel.displayName = 'RadioButtonWithLabel'; export default RadioButtonWithLabel; + +export type {RadioButtonWithLabelProps}; diff --git a/src/stories/RadioButtonWithLabel.stories.js b/src/stories/RadioButtonWithLabel.stories.tsx similarity index 60% rename from src/stories/RadioButtonWithLabel.stories.js rename to src/stories/RadioButtonWithLabel.stories.tsx index af5d6ec15a8c..3280864b8fdb 100644 --- a/src/stories/RadioButtonWithLabel.stories.js +++ b/src/stories/RadioButtonWithLabel.stories.tsx @@ -1,35 +1,37 @@ +import type {ComponentMeta, ComponentStory} from '@storybook/react'; import React from 'react'; import RadioButtonWithLabel from '@components/RadioButtonWithLabel'; +import type {RadioButtonWithLabelProps} from '@components/RadioButtonWithLabel'; + +type RadioButtonWithLabelStory = ComponentStory; /** * We use the Component Story Format for writing stories. Follow the docs here: * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/RadioButtonWithLabel', component: RadioButtonWithLabel, }; -function Template(args) { +function Template(props: RadioButtonWithLabelProps) { // eslint-disable-next-line react/jsx-props-no-spreading - return ; + return ; } // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args -const Default = Template.bind({}); -const Checked = Template.bind({}); +const Default: RadioButtonWithLabelStory = Template.bind({}); +const Checked: RadioButtonWithLabelStory = Template.bind({}); Default.args = { isChecked: false, label: 'This radio button is unchecked', - onInputChange: () => {}, }; Checked.args = { isChecked: true, label: 'This radio button is checked', - onInputChange: () => {}, }; export default story; From 98cf7d72f5491b48d61bd686bdbd0f069dddf237 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 6 Mar 2024 17:43:30 +0100 Subject: [PATCH 3/7] [TS migration] Migrate Form story --- src/ONYXKEYS.ts | 3 + src/components/Form/FormProvider.tsx | 2 + .../{Form.stories.js => Form.stories.tsx} | 56 ++++++++++--------- src/types/form/TestForm.ts | 32 +++++++++++ src/types/form/index.ts | 1 + 5 files changed, 69 insertions(+), 25 deletions(-) rename src/stories/{Form.stories.js => Form.stories.tsx} (80%) create mode 100644 src/types/form/TestForm.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index f6b5c635e4ae..d9faaeefcc3f 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -399,6 +399,8 @@ const ONYXKEYS = { EXIT_SURVEY_REASON_FORM_DRAFT: 'exitSurveyReasonFormDraft', EXIT_SURVEY_RESPONSE_FORM: 'exitSurveyResponseForm', EXIT_SURVEY_RESPONSE_FORM_DRAFT: 'exitSurveyResponseFormDraft', + TEST_FORM: 'testForm', + TEST_FORM_DRAFT: 'testFormDraft', }, } as const; @@ -443,6 +445,7 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: FormTypes.ReimbursementAccountForm; [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: FormTypes.PersonalBankAccountForm; [ONYXKEYS.FORMS.WORKSPACE_DESCRIPTION_FORM]: FormTypes.WorkspaceDescriptionForm; + [ONYXKEYS.FORMS.TEST_FORM]: FormTypes.TestForm; }; type OnyxFormDraftValuesMapping = { diff --git a/src/components/Form/FormProvider.tsx b/src/components/Form/FormProvider.tsx index ad09b68a5f39..ee3b3607401e 100644 --- a/src/components/Form/FormProvider.tsx +++ b/src/components/Form/FormProvider.tsx @@ -394,3 +394,5 @@ export default withOnyx({ key: (props) => `${props.formID}Draft` as any, }, })(forwardRef(FormProvider)) as (props: Omit, keyof FormProviderOnyxProps>) => ReactNode; + +export type {FormProviderProps}; diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.tsx similarity index 80% rename from src/stories/Form.stories.js rename to src/stories/Form.stories.tsx index 62f9a35d89e2..6985fa38d147 100644 --- a/src/stories/Form.stories.js +++ b/src/stories/Form.stories.tsx @@ -1,27 +1,33 @@ +import type {ComponentMeta, Story} from '@storybook/react'; import React, {useState} from 'react'; import {View} from 'react-native'; import AddressSearch from '@components/AddressSearch'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; +import type {FormProviderProps} from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Picker from '@components/Picker'; import StatePicker from '@components/StatePicker'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import NetworkConnection from '@libs/NetworkConnection'; import * as ValidationUtils from '@libs/ValidationUtils'; -// eslint-disable-next-line no-restricted-imports -import {defaultStyles} from '@styles/index'; import * as FormActions from '@userActions/FormActions'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import {defaultStyles} from '@src/styles'; +import type {Errors} from '@src/types/onyx/OnyxCommon'; + +type FormStory = Story>; /** * We use the Component Story Format for writing stories. Follow the docs here: * * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format */ -const story = { +const story: ComponentMeta = { title: 'Components/Form', component: FormProvider, subcomponents: { @@ -35,11 +41,11 @@ const story = { }, }; -function Template(args) { +function Template(args: FormProviderProps) { // Form consumes data from Onyx, so we initialize Onyx with the necessary data here NetworkConnection.setOfflineStatus(false); - FormActions.setIsLoading(args.formID, args.formState.isLoading); - FormActions.setErrors(args.formID, args.formState.error); + FormActions.setIsLoading(args.formID, !!args.formState?.isLoading); + FormActions.setErrors(args.formID, args.formState?.error as unknown as Errors); FormActions.setDraftValues(args.formID, args.draftValues); return ( @@ -61,27 +67,28 @@ function Template(args) { label="Account number" accessibilityLabel="Account number" inputID="accountNumber" - containerStyles={[defaultStyles.mt4]} + containerStyles={defaultStyles.mt4} /> {}} + containerStyles={defaultStyles.mt4} shouldSaveDraft items={[ { @@ -103,7 +110,8 @@ function Template(args) { InputComponent={Picker} label="Another Fruit" inputID="pickAnotherFruit" - containerStyles={[defaultStyles.mt4]} + onInputChange={() => {}} + containerStyles={defaultStyles.mt4} items={[ { label: 'Select a Fruit', @@ -139,16 +147,14 @@ function Template(args) { /** * Story to exhibit the native event handlers for TextInput in the Form Component - * @param {Object} args - * @returns {JSX} */ -function WithNativeEventHandler(args) { +function WithNativeEventHandler(args: FormProviderProps) { const [log, setLog] = useState(''); // Form consumes data from Onyx, so we initialize Onyx with the necessary data here NetworkConnection.setOfflineStatus(false); - FormActions.setIsLoading(args.formID, args.formState.isLoading); - FormActions.setErrors(args.formID, args.formState.error); + FormActions.setIsLoading(args.formID, !!args.formState?.isLoading); + FormActions.setErrors(args.formID, args.formState?.error as unknown as Errors); FormActions.setDraftValues(args.formID, args.draftValues); return ( @@ -170,16 +176,16 @@ function WithNativeEventHandler(args) { // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args -const Default = Template.bind({}); -const Loading = Template.bind({}); -const ServerError = Template.bind({}); -const InputError = Template.bind({}); +const Default: FormStory = Template.bind({}); +const Loading: FormStory = Template.bind({}); +const ServerError: FormStory = Template.bind({}); +const InputError: FormStory = Template.bind({}); const defaultArgs = { - formID: 'TestForm', + formID: ONYXKEYS.FORMS.TEST_FORM, submitButtonText: 'Submit', - validate: (values) => { - const errors = {}; + validate: (values: FormOnyxValues) => { + const errors: FormInputErrors = {}; if (!ValidationUtils.isRequiredFulfilled(values.routingNumber)) { errors.routingNumber = 'Please enter a routing number'; } @@ -206,10 +212,10 @@ const defaultArgs = { } return errors; }, - onSubmit: (values) => { + onSubmit: (values: FormOnyxValues) => { setTimeout(() => { alert(`Form submitted!\n\nInput values: ${JSON.stringify(values, null, 4)}`); - FormActions.setIsLoading('TestForm', false); + FormActions.setIsLoading(ONYXKEYS.FORMS.TEST_FORM, false); }, 1000); }, formState: { diff --git a/src/types/form/TestForm.ts b/src/types/form/TestForm.ts new file mode 100644 index 000000000000..85992d39083a --- /dev/null +++ b/src/types/form/TestForm.ts @@ -0,0 +1,32 @@ +import type {ValueOf} from 'type-fest'; +import type Form from './Form'; + +const INPUT_IDS = { + ROUTING_NUMBER: 'routingNumber', + ACCOUNT_NUMBER: 'accountNumber', + STREET: 'street', + DATE_OF_BIRTH: 'dob', + PICK_FRUIT: 'pickFruit', + PICK_ANOTHER_FRUIT: 'pickAnotherFruit', + STATE: 'state', + CHECKBOX: 'checkbox', +} as const; + +type InputID = ValueOf; + +type TestForm = Form< + InputID, + { + [INPUT_IDS.ROUTING_NUMBER]: string; + [INPUT_IDS.ACCOUNT_NUMBER]: string; + [INPUT_IDS.STREET]: string; + [INPUT_IDS.STATE]: string; + [INPUT_IDS.DATE_OF_BIRTH]: string; + [INPUT_IDS.PICK_FRUIT]: string; + [INPUT_IDS.PICK_ANOTHER_FRUIT]: string; + [INPUT_IDS.CHECKBOX]: boolean; + } +>; + +export type {TestForm}; +export default INPUT_IDS; diff --git a/src/types/form/index.ts b/src/types/form/index.ts index 1ff8d0df2031..967eeb312b0e 100644 --- a/src/types/form/index.ts +++ b/src/types/form/index.ts @@ -37,4 +37,5 @@ export type {WorkspaceRateAndUnitForm} from './WorkspaceRateAndUnitForm'; export type {WorkspaceSettingsForm} from './WorkspaceSettingsForm'; export type {ReportPhysicalCardForm} from './ReportPhysicalCardForm'; export type {WorkspaceDescriptionForm} from './WorkspaceDescriptionForm'; +export type {TestForm} from './TestForm'; export type {default as Form} from './Form'; From 67022012e513afa0fdd1dedcdc3778ef0b10b3d2 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 7 Mar 2024 16:23:35 +0100 Subject: [PATCH 4/7] Code improvement --- src/stories/Form.stories.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/stories/Form.stories.tsx b/src/stories/Form.stories.tsx index 6985fa38d147..cdb361f1daf2 100644 --- a/src/stories/Form.stories.tsx +++ b/src/stories/Form.stories.tsx @@ -12,13 +12,13 @@ import Picker from '@components/Picker'; import StatePicker from '@components/StatePicker'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; +import {MaybePhraseKey} from '@libs/Localize'; import NetworkConnection from '@libs/NetworkConnection'; import * as ValidationUtils from '@libs/ValidationUtils'; import * as FormActions from '@userActions/FormActions'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {defaultStyles} from '@src/styles'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; type FormStory = Story>; @@ -45,9 +45,14 @@ function Template(args: FormProviderProps) { // Form consumes data from Onyx, so we initialize Onyx with the necessary data here NetworkConnection.setOfflineStatus(false); FormActions.setIsLoading(args.formID, !!args.formState?.isLoading); - FormActions.setErrors(args.formID, args.formState?.error as unknown as Errors); FormActions.setDraftValues(args.formID, args.draftValues); + if (args.formState?.error) { + FormActions.setErrors(args.formID, {error: args.formState.error as MaybePhraseKey}); + } else { + FormActions.clearErrors(args.formID); + } + return ( // eslint-disable-next-line react/jsx-props-no-spreading @@ -154,9 +159,14 @@ function WithNativeEventHandler(args: FormProviderProps From ff352a3943fb6ec734bbd6a7a99e3d6c30739b98 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 7 Mar 2024 16:24:39 +0100 Subject: [PATCH 5/7] Lint fix --- src/stories/Form.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stories/Form.stories.tsx b/src/stories/Form.stories.tsx index cdb361f1daf2..674e366a5085 100644 --- a/src/stories/Form.stories.tsx +++ b/src/stories/Form.stories.tsx @@ -12,7 +12,7 @@ import Picker from '@components/Picker'; import StatePicker from '@components/StatePicker'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; -import {MaybePhraseKey} from '@libs/Localize'; +import type {MaybePhraseKey} from '@libs/Localize'; import NetworkConnection from '@libs/NetworkConnection'; import * as ValidationUtils from '@libs/ValidationUtils'; import * as FormActions from '@userActions/FormActions'; From 763e62132b3d89b9e72f3cfcad1900237b9af769 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Fri, 8 Mar 2024 10:48:24 +0100 Subject: [PATCH 6/7] Update storybook form typing --- src/ONYXKEYS.ts | 3 --- src/stories/Form.stories.tsx | 34 ++++++++++++++++++++++++---------- src/types/form/TestForm.ts | 32 -------------------------------- src/types/form/index.ts | 1 - 4 files changed, 24 insertions(+), 46 deletions(-) delete mode 100644 src/types/form/TestForm.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index d9faaeefcc3f..f6b5c635e4ae 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -399,8 +399,6 @@ const ONYXKEYS = { EXIT_SURVEY_REASON_FORM_DRAFT: 'exitSurveyReasonFormDraft', EXIT_SURVEY_RESPONSE_FORM: 'exitSurveyResponseForm', EXIT_SURVEY_RESPONSE_FORM_DRAFT: 'exitSurveyResponseFormDraft', - TEST_FORM: 'testForm', - TEST_FORM_DRAFT: 'testFormDraft', }, } as const; @@ -445,7 +443,6 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: FormTypes.ReimbursementAccountForm; [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: FormTypes.PersonalBankAccountForm; [ONYXKEYS.FORMS.WORKSPACE_DESCRIPTION_FORM]: FormTypes.WorkspaceDescriptionForm; - [ONYXKEYS.FORMS.TEST_FORM]: FormTypes.TestForm; }; type OnyxFormDraftValuesMapping = { diff --git a/src/stories/Form.stories.tsx b/src/stories/Form.stories.tsx index 674e366a5085..e9b3dad4fc43 100644 --- a/src/stories/Form.stories.tsx +++ b/src/stories/Form.stories.tsx @@ -7,7 +7,6 @@ import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; import type {FormProviderProps} from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Picker from '@components/Picker'; import StatePicker from '@components/StatePicker'; import Text from '@components/Text'; @@ -17,10 +16,25 @@ import NetworkConnection from '@libs/NetworkConnection'; import * as ValidationUtils from '@libs/ValidationUtils'; import * as FormActions from '@userActions/FormActions'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; +import type {OnyxFormValuesMapping} from '@src/ONYXKEYS'; import {defaultStyles} from '@src/styles'; -type FormStory = Story>; +type FormStory = Story; + +type StorybookFormValues = { + routingNumber?: string; + accountNumber?: string; + street?: string; + dob?: string; + pickFruit?: string; + pickAnotherFruit?: string; + state?: string; + checkbox?: boolean; +}; + +type StorybookFormErrors = Partial>; + +const STORYBOOK_FORM_ID = 'TestForm' as keyof OnyxFormValuesMapping; /** * We use the Component Story Format for writing stories. Follow the docs here: @@ -41,7 +55,7 @@ const story: ComponentMeta = { }, }; -function Template(args: FormProviderProps) { +function Template(args: FormProviderProps) { // Form consumes data from Onyx, so we initialize Onyx with the necessary data here NetworkConnection.setOfflineStatus(false); FormActions.setIsLoading(args.formID, !!args.formState?.isLoading); @@ -153,7 +167,7 @@ function Template(args: FormProviderProps) { /** * Story to exhibit the native event handlers for TextInput in the Form Component */ -function WithNativeEventHandler(args: FormProviderProps) { +function WithNativeEventHandler(args: FormProviderProps) { const [log, setLog] = useState(''); // Form consumes data from Onyx, so we initialize Onyx with the necessary data here @@ -192,10 +206,10 @@ const ServerError: FormStory = Template.bind({}); const InputError: FormStory = Template.bind({}); const defaultArgs = { - formID: ONYXKEYS.FORMS.TEST_FORM, + formID: STORYBOOK_FORM_ID, submitButtonText: 'Submit', - validate: (values: FormOnyxValues) => { - const errors: FormInputErrors = {}; + validate: (values: StorybookFormValues) => { + const errors: StorybookFormErrors = {}; if (!ValidationUtils.isRequiredFulfilled(values.routingNumber)) { errors.routingNumber = 'Please enter a routing number'; } @@ -222,10 +236,10 @@ const defaultArgs = { } return errors; }, - onSubmit: (values: FormOnyxValues) => { + onSubmit: (values: StorybookFormValues) => { setTimeout(() => { alert(`Form submitted!\n\nInput values: ${JSON.stringify(values, null, 4)}`); - FormActions.setIsLoading(ONYXKEYS.FORMS.TEST_FORM, false); + FormActions.setIsLoading(STORYBOOK_FORM_ID, false); }, 1000); }, formState: { diff --git a/src/types/form/TestForm.ts b/src/types/form/TestForm.ts deleted file mode 100644 index 85992d39083a..000000000000 --- a/src/types/form/TestForm.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type {ValueOf} from 'type-fest'; -import type Form from './Form'; - -const INPUT_IDS = { - ROUTING_NUMBER: 'routingNumber', - ACCOUNT_NUMBER: 'accountNumber', - STREET: 'street', - DATE_OF_BIRTH: 'dob', - PICK_FRUIT: 'pickFruit', - PICK_ANOTHER_FRUIT: 'pickAnotherFruit', - STATE: 'state', - CHECKBOX: 'checkbox', -} as const; - -type InputID = ValueOf; - -type TestForm = Form< - InputID, - { - [INPUT_IDS.ROUTING_NUMBER]: string; - [INPUT_IDS.ACCOUNT_NUMBER]: string; - [INPUT_IDS.STREET]: string; - [INPUT_IDS.STATE]: string; - [INPUT_IDS.DATE_OF_BIRTH]: string; - [INPUT_IDS.PICK_FRUIT]: string; - [INPUT_IDS.PICK_ANOTHER_FRUIT]: string; - [INPUT_IDS.CHECKBOX]: boolean; - } ->; - -export type {TestForm}; -export default INPUT_IDS; diff --git a/src/types/form/index.ts b/src/types/form/index.ts index 967eeb312b0e..1ff8d0df2031 100644 --- a/src/types/form/index.ts +++ b/src/types/form/index.ts @@ -37,5 +37,4 @@ export type {WorkspaceRateAndUnitForm} from './WorkspaceRateAndUnitForm'; export type {WorkspaceSettingsForm} from './WorkspaceSettingsForm'; export type {ReportPhysicalCardForm} from './ReportPhysicalCardForm'; export type {WorkspaceDescriptionForm} from './WorkspaceDescriptionForm'; -export type {TestForm} from './TestForm'; export type {default as Form} from './Form'; From 42d69f10709f22784293abe44aefbb43c26de6eb Mon Sep 17 00:00:00 2001 From: VickyStash Date: Fri, 8 Mar 2024 11:18:08 +0100 Subject: [PATCH 7/7] Code improvements --- src/stories/Form.stories.tsx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/stories/Form.stories.tsx b/src/stories/Form.stories.tsx index e9b3dad4fc43..8eeab971ea88 100644 --- a/src/stories/Form.stories.tsx +++ b/src/stories/Form.stories.tsx @@ -55,21 +55,21 @@ const story: ComponentMeta = { }, }; -function Template(args: FormProviderProps) { +function Template(props: FormProviderProps) { // Form consumes data from Onyx, so we initialize Onyx with the necessary data here NetworkConnection.setOfflineStatus(false); - FormActions.setIsLoading(args.formID, !!args.formState?.isLoading); - FormActions.setDraftValues(args.formID, args.draftValues); + FormActions.setIsLoading(props.formID, !!props.formState?.isLoading); + FormActions.setDraftValues(props.formID, props.draftValues); - if (args.formState?.error) { - FormActions.setErrors(args.formID, {error: args.formState.error as MaybePhraseKey}); + if (props.formState?.error) { + FormActions.setErrors(props.formID, {error: props.formState.error as MaybePhraseKey}); } else { - FormActions.clearErrors(args.formID); + FormActions.clearErrors(props.formID); } return ( // eslint-disable-next-line react/jsx-props-no-spreading - + +