Skip to content

Commit 47379bc

Browse files
committed
refactor: Update form stories to enhance usability and consistency
- Refactored ControlledCurrencyInput, ControlledDatePicker, ControlledSelect, and ControlledTextArea stories to include necessary props and improve structure. - Added missing args for story configurations to ensure proper rendering and documentation. - Updated validation rules and error handling for better user experience across various form components. - Removed outdated README for controlled components as the documentation is now integrated within the stories. - Improved button usage in forms by utilizing the Button component from @medusajs/ui for consistent styling and functionality.
1 parent 2bc8ec3 commit 47379bc

8 files changed

Lines changed: 1003 additions & 1016 deletions

File tree

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ const CurrencyInputWithHookForm = ({
3636
currency?: string;
3737
symbol?: string;
3838
code?: string;
39-
schema?: z.ZodSchema<any>;
39+
schema?: z.ZodSchema<CurrencyFormData>;
4040
defaultValues?: CurrencyFormData;
41-
[key: string]: any;
41+
[key: string]: unknown;
4242
}) => {
4343
const form = useForm<CurrencyFormData>({
4444
resolver: schema ? zodResolver(schema) : undefined,
@@ -178,6 +178,7 @@ const requiredSchema = z.object({
178178

179179
export const RequiredFieldValidation: Story = {
180180
args: {
181+
name: 'price',
181182
symbol: '$',
182183
code: 'usd',
183184
},
@@ -202,6 +203,7 @@ const customValidationSchema = z.object({
202203

203204
export const CustomValidationMessage: Story = {
204205
args: {
206+
name: 'price',
205207
symbol: '$',
206208
code: 'usd',
207209
},
@@ -220,6 +222,7 @@ export const CustomValidationMessage: Story = {
220222
// 4. Different Currency Codes
221223
export const JPYCurrency: Story = {
222224
args: {
225+
name: 'price',
223226
symbol: '¥',
224227
code: 'jpy',
225228
},
@@ -236,6 +239,7 @@ export const JPYCurrency: Story = {
236239

237240
export const CADCurrency: Story = {
238241
args: {
242+
name: 'price',
239243
symbol: 'C$',
240244
code: 'cad',
241245
},

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

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@ const BasicDateSelectionComponent = () => {
2525
return (
2626
<FormProvider {...form}>
2727
<div className="w-[400px]">
28-
<ControlledDatePicker
29-
name="birthDate"
30-
label="Birth Date"
31-
placeholder="Select your birth date"
32-
/>
28+
<ControlledDatePicker name="birthDate" label="Birth Date" placeholder="Select your birth date" />
3329
</div>
3430
</FormProvider>
3531
);
3632
};
3733

3834
export const BasicDateSelection: Story = {
35+
args: {
36+
name: 'birthDate',
37+
label: 'Birth Date',
38+
placeholder: 'Select your birth date',
39+
},
3940
render: () => <BasicDateSelectionComponent />,
4041
};
4142

@@ -47,39 +48,39 @@ const RequiredFieldValidationComponent = () => {
4748
},
4849
});
4950

50-
const onSubmit = (data: any) => {
51+
const onSubmit = (data: unknown) => {
5152
console.log('Form submitted:', data);
5253
};
5354

5455
return (
5556
<FormProvider {...form}>
5657
<form onSubmit={form.handleSubmit(onSubmit)} className="w-[400px] space-y-4">
57-
<ControlledDatePicker
58-
name="requiredDate"
59-
label="Required Date"
58+
<ControlledDatePicker
59+
name="requiredDate"
60+
label="Required Date"
6061
placeholder="This field is required"
6162
required
6263
rules={{
63-
required: 'Date is required'
64+
required: 'Date is required',
6465
}}
6566
/>
66-
<button
67-
type="submit"
68-
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
69-
>
67+
<button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
7068
Submit
7169
</button>
7270
{form.formState.errors.requiredDate && (
73-
<p className="text-red-500 text-sm">
74-
{form.formState.errors.requiredDate.message}
75-
</p>
71+
<p className="text-red-500 text-sm">{form.formState.errors.requiredDate.message}</p>
7672
)}
7773
</form>
7874
</FormProvider>
7975
);
8076
};
8177

8278
export const RequiredFieldValidation: Story = {
79+
args: {
80+
name: 'requiredDate',
81+
label: 'Required Date',
82+
placeholder: 'This field is required',
83+
},
8384
render: () => <RequiredFieldValidationComponent />,
8485
};
8586

@@ -96,21 +97,21 @@ const DateFormatVariationsComponent = () => {
9697
return (
9798
<FormProvider {...form}>
9899
<div className="w-[400px] space-y-4">
99-
<ControlledDatePicker
100-
name="usFormat"
101-
label="US Format (MM/DD/YYYY)"
100+
<ControlledDatePicker
101+
name="usFormat"
102+
label="US Format (MM/DD/YYYY)"
102103
placeholder="MM/DD/YYYY"
103104
dateFormat="MM/dd/yyyy"
104105
/>
105-
<ControlledDatePicker
106-
name="euroFormat"
107-
label="European Format (DD/MM/YYYY)"
106+
<ControlledDatePicker
107+
name="euroFormat"
108+
label="European Format (DD/MM/YYYY)"
108109
placeholder="DD/MM/YYYY"
109110
dateFormat="dd/MM/yyyy"
110111
/>
111-
<ControlledDatePicker
112-
name="isoFormat"
113-
label="ISO Format (YYYY-MM-DD)"
112+
<ControlledDatePicker
113+
name="isoFormat"
114+
label="ISO Format (YYYY-MM-DD)"
114115
placeholder="YYYY-MM-DD"
115116
dateFormat="yyyy-MM-dd"
116117
/>
@@ -120,6 +121,11 @@ const DateFormatVariationsComponent = () => {
120121
};
121122

122123
export const DateFormatVariations: Story = {
124+
args: {
125+
name: 'usFormat',
126+
label: 'US Format (MM/DD/YYYY)',
127+
placeholder: 'MM/DD/YYYY',
128+
},
123129
render: () => <DateFormatVariationsComponent />,
124130
};
125131

@@ -142,32 +148,35 @@ const DisabledDatesComponent = () => {
142148
return (
143149
<FormProvider {...form}>
144150
<div className="w-[400px] space-y-4">
145-
<ControlledDatePicker
146-
name="noPastDates"
147-
label="No Past Dates"
151+
<ControlledDatePicker
152+
name="noPastDates"
153+
label="No Past Dates"
148154
placeholder="Future dates only"
149155
minDate={today}
150156
/>
151-
<ControlledDatePicker
152-
name="noFutureDates"
153-
label="No Future Dates"
157+
<ControlledDatePicker
158+
name="noFutureDates"
159+
label="No Future Dates"
154160
placeholder="Past dates only"
155161
maxDate={today}
156162
/>
157-
<ControlledDatePicker
158-
name="specificDisabled"
159-
label="Specific Date Range Disabled"
163+
<ControlledDatePicker
164+
name="specificDisabled"
165+
label="Specific Date Range Disabled"
160166
placeholder="Excludes last/next week"
161-
excludeDateIntervals={[
162-
{ start: oneWeekAgo, end: oneWeekFromNow }
163-
]}
167+
excludeDateIntervals={[{ start: oneWeekAgo, end: oneWeekFromNow }]}
164168
/>
165169
</div>
166170
</FormProvider>
167171
);
168172
};
169173

170174
export const DisabledDates: Story = {
175+
args: {
176+
name: 'noPastDates',
177+
label: 'No Past Dates',
178+
placeholder: 'Future dates only',
179+
},
171180
render: () => <DisabledDatesComponent />,
172181
};
173182

@@ -195,9 +204,9 @@ const MinMaxDateConstraintsComponent = () => {
195204
return (
196205
<FormProvider {...form}>
197206
<div className="w-[400px] space-y-4">
198-
<ControlledDatePicker
199-
name="constrainedDate"
200-
label="Date Range (Tomorrow to 30 days)"
207+
<ControlledDatePicker
208+
name="constrainedDate"
209+
label="Date Range (Tomorrow to 30 days)"
201210
placeholder="Select within range"
202211
minDate={minDate}
203212
maxDate={maxDate}
@@ -208,21 +217,21 @@ const MinMaxDateConstraintsComponent = () => {
208217
if (selectedDate < minDate) return 'Date must be tomorrow or later';
209218
if (selectedDate > maxDate) return 'Date must be within 30 days';
210219
return true;
211-
}
220+
},
212221
}}
213222
/>
214-
<ControlledDatePicker
215-
name="businessDays"
216-
label="Business Days Only"
223+
<ControlledDatePicker
224+
name="businessDays"
225+
label="Business Days Only"
217226
placeholder="Weekdays only"
218-
filterDate={(date) => {
227+
filterDate={(date: Date) => {
219228
const day = date.getDay();
220229
return day !== 0 && day !== 6; // Exclude Sunday (0) and Saturday (6)
221230
}}
222231
/>
223-
<ControlledDatePicker
224-
name="ageRestricted"
225-
label="Age Verification (18+)"
232+
<ControlledDatePicker
233+
name="ageRestricted"
234+
label="Age Verification (18+)"
226235
placeholder="Must be 18 or older"
227236
maxDate={eighteenYearsAgo}
228237
minDate={hundredYearsAgo}
@@ -233,32 +242,32 @@ const MinMaxDateConstraintsComponent = () => {
233242
const age = today.getFullYear() - selectedDate.getFullYear();
234243
const monthDiff = today.getMonth() - selectedDate.getMonth();
235244
const dayDiff = today.getDate() - selectedDate.getDate();
236-
245+
237246
let calculatedAge = age;
238247
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
239248
calculatedAge--;
240249
}
241-
250+
242251
return calculatedAge >= 18 || 'Must be 18 years or older';
243-
}
252+
},
244253
}}
245254
/>
246255
{form.formState.errors.constrainedDate && (
247-
<p className="text-red-500 text-sm">
248-
{form.formState.errors.constrainedDate.message}
249-
</p>
256+
<p className="text-red-500 text-sm">{form.formState.errors.constrainedDate.message}</p>
250257
)}
251258
{form.formState.errors.ageRestricted && (
252-
<p className="text-red-500 text-sm">
253-
{form.formState.errors.ageRestricted.message}
254-
</p>
259+
<p className="text-red-500 text-sm">{form.formState.errors.ageRestricted.message}</p>
255260
)}
256261
</div>
257262
</FormProvider>
258263
);
259264
};
260265

261266
export const MinMaxDateConstraints: Story = {
267+
args: {
268+
name: 'constrainedDate',
269+
label: 'Date Range (Tomorrow to 30 days)',
270+
placeholder: 'Select within range',
271+
},
262272
render: () => <MinMaxDateConstraintsComponent />,
263273
};
264-

0 commit comments

Comments
 (0)