Skip to content

Commit df3a3f0

Browse files
committed
feat: Enhance form stories with additional args and alert on submit
- Add args for various checkbox stories to improve usage examples - Update onSubmit functions in forms to alert submitted data for better feedback - Refactor handleSelectAll to improve type handling in MultipleCheckboxesForm - Introduce helper functions for file extraction in FileUpload component These changes enhance the documentation and usability of form components in the storybook, providing clearer examples and better user interaction.
1 parent 919e1ca commit df3a3f0

File tree

6 files changed

+63
-35
lines changed

6 files changed

+63
-35
lines changed

apps/docs/src/medusa-forms/ControlledCheckbox.stories.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const BasicCheckboxForm = () => {
3737
};
3838

3939
export const BasicUsage: Story = {
40+
args: { name: 'acceptTerms', label: 'I accept the terms and conditions' },
4041
render: () => <BasicCheckboxForm />,
4142
};
4243

@@ -59,6 +60,7 @@ const DefaultCheckedForm = () => {
5960
};
6061

6162
export const DefaultChecked: Story = {
63+
args: { name: 'newsletter', label: 'Subscribe to newsletter', checked: true },
6264
render: () => <DefaultCheckedForm />,
6365
};
6466

@@ -81,6 +83,7 @@ const DefaultUncheckedForm = () => {
8183
};
8284

8385
export const DefaultUnchecked: Story = {
86+
args: { name: 'marketing', label: 'Receive marketing emails' },
8487
render: () => <DefaultUncheckedForm />,
8588
};
8689

@@ -93,8 +96,9 @@ const RequiredValidationForm = () => {
9396
mode: 'onChange',
9497
});
9598

96-
const onSubmit = (data: any) => {
99+
const onSubmit = (data: Record<string, unknown>) => {
97100
// Form data processed successfully
101+
alert(`Form data submitted: ${JSON.stringify(data)}`);
98102
};
99103

100104
return (
@@ -121,6 +125,7 @@ const RequiredValidationForm = () => {
121125
};
122126

123127
export const RequiredValidation: Story = {
128+
args: { name: 'requiredField', label: 'This field is required' },
124129
render: () => <RequiredValidationForm />,
125130
};
126131

@@ -141,7 +146,7 @@ const CustomValidationForm = () => {
141146
label="I agree to the privacy policy"
142147
rules={{
143148
required: 'Please accept our privacy policy to continue',
144-
validate: (value) => value === true || 'You must agree to the privacy policy',
149+
validate: (value: boolean) => value === true || 'You must agree to the privacy policy',
145150
}}
146151
/>
147152
<div className="text-sm text-gray-600">Has errors: {form.formState.errors.agreement ? 'Yes' : 'No'}</div>
@@ -154,6 +159,7 @@ const CustomValidationForm = () => {
154159
};
155160

156161
export const CustomValidationMessage: Story = {
162+
args: { name: 'agreement', label: 'I agree to the privacy policy' },
157163
render: () => <CustomValidationForm />,
158164
};
159165

@@ -184,6 +190,7 @@ const ErrorStateForm = () => {
184190
};
185191

186192
export const ErrorState: Story = {
193+
args: { name: 'errorField', label: 'Checkbox with error state' },
187194
render: () => <ErrorStateForm />,
188195
};
189196

@@ -208,6 +215,7 @@ const DisabledStateForm = () => {
208215
};
209216

210217
export const DisabledState: Story = {
218+
args: { name: 'disabledExample', label: 'Disabled checkbox example' },
211219
render: () => <DisabledStateForm />,
212220
};
213221

@@ -230,11 +238,12 @@ const MultipleCheckboxesForm = () => {
230238
form.setValue('selectAll', allSelected);
231239
}, [allSelected, form]);
232240

233-
const handleSelectAll = (checked: boolean) => {
234-
form.setValue('option1', checked);
235-
form.setValue('option2', checked);
236-
form.setValue('option3', checked);
237-
form.setValue('selectAll', checked);
241+
const handleSelectAll = (checked: string | boolean) => {
242+
const isChecked = checked === true;
243+
form.setValue('option1', isChecked);
244+
form.setValue('option2', isChecked);
245+
form.setValue('option3', isChecked);
246+
form.setValue('selectAll', isChecked);
238247
};
239248

240249
return (
@@ -260,6 +269,7 @@ const MultipleCheckboxesForm = () => {
260269
};
261270

262271
export const MultipleCheckboxes: Story = {
272+
args: { name: 'selectAll', label: 'Select All' },
263273
render: () => <MultipleCheckboxesForm />,
264274
};
265275

@@ -276,25 +286,31 @@ const CompleteFormExampleComponent = () => {
276286
mode: 'onChange',
277287
});
278288

279-
const onSubmit = (data: any) => {
289+
const onSubmit = (data: Record<string, unknown>) => {
280290
alert(`Form submitted with data: ${JSON.stringify(data, null, 2)}`);
281291
};
282292

283293
return (
284294
<FormProvider {...form}>
285295
<form onSubmit={form.handleSubmit(onSubmit)} className="w-[400px] space-y-4">
286296
<div>
287-
<label className="block text-sm font-medium mb-1">Username</label>
297+
<label htmlFor="username" className="block text-sm font-medium mb-1">
298+
Username
299+
</label>
288300
<input
301+
id="username"
289302
{...form.register('username', { required: 'Username is required' })}
290303
className="w-full px-3 py-2 border border-gray-300 rounded-md"
291304
placeholder="Enter username"
292305
/>
293306
</div>
294307

295308
<div>
296-
<label className="block text-sm font-medium mb-1">Email</label>
309+
<label htmlFor="email" className="block text-sm font-medium mb-1">
310+
Email
311+
</label>
297312
<input
313+
id="email"
298314
{...form.register('email', {
299315
required: 'Email is required',
300316
pattern: {
@@ -342,5 +358,6 @@ const CompleteFormExampleComponent = () => {
342358
};
343359

344360
export const CompleteFormExample: Story = {
361+
args: { name: 'exampleForm', label: 'Complete form example' },
345362
render: () => <CompleteFormExampleComponent />,
346363
};

apps/docs/src/medusa-forms/ControlledDatePicker.stories.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const RequiredFieldValidationComponent = () => {
5050

5151
const onSubmit = (data: unknown) => {
5252
// Form data processed successfully
53+
alert(`Form data submitted: ${JSON.stringify(data)}`);
5354
};
5455

5556
return (

apps/docs/src/medusa-forms/ControlledTextArea.stories.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ const RequiredFieldForm = () => {
129129

130130
const onSubmit = (data: unknown) => {
131131
// Form data processed successfully
132+
alert(`Form data submitted: ${JSON.stringify(data)}`);
132133
};
133134

134135
return (
@@ -243,6 +244,7 @@ const ValidationErrorForm = () => {
243244

244245
const onSubmit = (data: unknown) => {
245246
// Form data processed successfully
247+
alert(`Form data submitted: ${JSON.stringify(data)}`);
246248
};
247249

248250
const hasError = !!form.formState.errors.message;
@@ -332,6 +334,7 @@ const ComprehensiveForm = () => {
332334

333335
const onSubmit = (data: unknown) => {
334336
// Form data processed successfully
337+
alert(`Form data submitted: ${JSON.stringify(data)}`);
335338
};
336339

337340
return (

packages/medusa-forms/src/ui/FieldCheckbox.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ export const FieldCheckbox: React.FC<FieldCheckboxProps> = ({
3636
{...fieldProps}
3737
ref={ref}
3838
checked={props.checked}
39-
onChange={(e) => {}}
39+
onChange={(_e) => {
40+
// this is a noop since we handle the onChange in the onCheckedChange handler,
41+
// but we need to pass a function to the onChange prop because the MedusaCheckbox component expects it
42+
}}
4043
onCheckedChange={(checked) => {
4144
onChange?.(checked);
4245
}}

packages/medusa-forms/src/ui/FileUpload.tsx

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,36 @@ const FileUpload: FC<FileUploadProps> = ({
3939
}
4040
};
4141

42-
const handleFileDrop = (e: DragEvent<HTMLDivElement>) => {
43-
setUploadError(false);
44-
e.preventDefault();
45-
42+
const extractFilesFromItems = (items: DataTransferItemList): File[] => {
4643
const files: File[] = [];
47-
48-
if (e.dataTransfer.items) {
49-
// use DataTransferItemList interface to access the file(s)
50-
for (let i = 0; i < e.dataTransfer.items.length; i += 1) {
51-
// if dropped items are not files, reject them
52-
if (e.dataTransfer.items[i].kind === 'file') {
53-
const file = e.dataTransfer.items[i].getAsFile();
54-
55-
if (file && filetypes.indexOf(file.type) > -1) {
56-
files.push(file);
57-
}
44+
for (const item of items) {
45+
if (item.kind === 'file') {
46+
const file = item.getAsFile();
47+
if (file && filetypes.indexOf(file.type) > -1) {
48+
files.push(file);
5849
}
5950
}
60-
} else {
61-
// use DataTransfer interface to access the file(s)
62-
for (let i = 0; i < e.dataTransfer.files.length; i += 1) {
63-
if (filetypes.indexOf(e.dataTransfer.files[i].type) > -1) {
64-
files.push(e.dataTransfer.files[i]);
65-
}
51+
}
52+
return files;
53+
};
54+
55+
const extractFilesFromFileList = (fileList: FileList): File[] => {
56+
const files: File[] = [];
57+
for (const file of fileList) {
58+
if (filetypes.indexOf(file.type) > -1) {
59+
files.push(file);
6660
}
6761
}
62+
return files;
63+
};
64+
65+
const handleFileDrop = (e: DragEvent<HTMLDivElement>) => {
66+
setUploadError(false);
67+
e.preventDefault();
68+
69+
const files = e.dataTransfer.items
70+
? extractFilesFromItems(e.dataTransfer.items)
71+
: extractFilesFromFileList(e.dataTransfer.files);
6872

6973
if (files.length === 1) {
7074
onFileChosen(files);

packages/medusa-forms/src/ui/types.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ type DatePickerValueProps = {
6161
className?: string;
6262
modal?: boolean;
6363
};
64-
interface DatePickerProps
64+
export interface DatePickerProps
6565
extends Omit<BaseDatePickerProps<CalendarDateTime | CalendarDate>, keyof DatePickerValueProps>,
6666
DatePickerValueProps {}
6767

@@ -89,7 +89,7 @@ export type SearchableSelectProps = Props<Option, IsMulti, Group> &
8989
export type CreatableSelectProps = CreatableProps<Option, IsMulti, Group> &
9090
RefAttributes<SelectInstance<Option, IsMulti, Group>>;
9191

92-
interface SelectProps extends React.ComponentPropsWithRef {
92+
export interface SelectProps extends React.ComponentPropsWithRef {
9393
size?: 'base' | 'small';
9494
children?: React.ReactNode;
9595
value?: string;
@@ -98,7 +98,7 @@ interface SelectProps extends React.ComponentPropsWithRef {
9898
open?: boolean;
9999
defaultOpen?: boolean;
100100
onOpenChange?(open: boolean): void;
101-
dir?: Direction;
101+
dir?: 'ltr' | 'rtl';
102102
name?: string;
103103
autoComplete?: string;
104104
disabled?: boolean;

0 commit comments

Comments
 (0)