Skip to content

Commit fc8df8d

Browse files
committed
Update dependencies and refactor storybook decorators for React Router integration
- Upgraded from version 18 to 19 in and . - Replaced with in multiple story files to support React Router. - Adjusted import paths for components in CSS and story files for consistency. - Enhanced checkbox and radio group components with additional data attributes for better accessibility.
1 parent d17db52 commit fc8df8d

14 files changed

Lines changed: 81 additions & 86 deletions

ai/CustomInputsProject.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,8 @@ import { expect, userEvent } from '@storybook/test';
484484
import * as React from 'react';
485485
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
486486
import { z } from 'zod';
487-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
487+
488+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
488489

489490
// Custom checkbox component
490491
const CustomCheckbox = React.forwardRef<
@@ -597,6 +598,18 @@ const handleFormSubmission = async (request: Request) => {
597598
// Story definition
598599
export const CustomComponents: Story = {
599600
render: () => <CustomCheckboxExample />,
601+
decorators: [
602+
withReactRouterStubDecorator({
603+
routes: [
604+
{
605+
path: '/',
606+
action: async ({ request }: ActionFunctionArgs) => {
607+
return handleFormSubmission(request);
608+
},
609+
},
610+
],
611+
}),
612+
],
600613
parameters: {
601614
docs: {
602615
description: {

apps/docs/src/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@import 'tailwindcss';
2-
@source "../../../../packages/components";
2+
@source "../../../packages/components";
33

44
:root {
55
--background: hsl(0 0% 100%);

apps/docs/src/remix-hook-form/checkbox-custom.stories.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { Checkbox } from '@lambdacurry/forms/remix-hook-form/checkbox';
33
import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form';
44
import { Button } from '@lambdacurry/forms/ui/button';
55
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
6-
import type { ActionFunctionArgs } from '@remix-run/node';
7-
import { useFetcher } from '@remix-run/react';
86
import type { Meta, StoryObj } from '@storybook/react';
97
import { expect, userEvent, within } from '@storybook/test';
108
import * as React from 'react';
9+
import type { ActionFunctionArgs } from 'react-router';
10+
import { useFetcher } from 'react-router';
1111
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1212
import { z } from 'zod';
13-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
13+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1414

1515
const formSchema = z.object({
1616
terms: z.boolean().refine((val) => val === true, 'You must accept the terms and conditions'),
@@ -237,11 +237,14 @@ type Story = StoryObj<typeof meta>;
237237
export const CustomCheckboxComponentExamples: Story = {
238238
name: 'Custom Checkbox Component Examples',
239239
decorators: [
240-
withRemixStubDecorator({
241-
root: {
242-
Component: AllCustomComponentsExample,
243-
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
244-
},
240+
withReactRouterStubDecorator({
241+
routes: [
242+
{
243+
path: '/',
244+
Component: AllCustomComponentsExample,
245+
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
246+
},
247+
],
245248
}),
246249
],
247250
parameters: {
@@ -506,4 +509,4 @@ const CustomErrorMessage = React.forwardRef<
506509
expect(successMessage).toBeInTheDocument();
507510
}
508511
},
509-
};
512+
};

apps/docs/src/remix-hook-form/radio-group-custom.stories.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form';
55
import { RadioGroupItem } from '@lambdacurry/forms/ui/radio-group';
66
import { cn } from '@lambdacurry/forms/ui/utils';
77
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
8-
import type { ActionFunctionArgs } from '@remix-run/node';
9-
import { Form, useFetcher } from '@remix-run/react';
108
import type { Meta, StoryObj } from '@storybook/react';
119
import { expect, userEvent, within } from '@storybook/test';
1210
import * as React from 'react';
11+
import type { ActionFunctionArgs } from 'react-router';
12+
import { Form, useFetcher } from 'react-router';
1313
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1414
import { z } from 'zod';
15-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
15+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1616

1717
const formSchema = z.object({
1818
plan: z.enum(['starter', 'pro', 'enterprise'], {
@@ -397,11 +397,13 @@ type Story = StoryObj<typeof meta>;
397397
export const CustomComponents: Story = {
398398
render: () => <CustomRadioGroupExample />,
399399
decorators: [
400-
withRemixStubDecorator({
401-
root: {
402-
Component: CustomRadioGroupExample,
403-
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
404-
},
400+
withReactRouterStubDecorator({
401+
routes: [
402+
{
403+
path: '/',
404+
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
405+
},
406+
],
405407
}),
406408
],
407409
parameters: {

apps/docs/src/remix-hook-form/radio-group.stories.tsx

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { zodResolver } from '@hookform/resolvers/zod';
22
import { RadioGroup } from '@lambdacurry/forms/remix-hook-form/radio-group';
33
import { Button } from '@lambdacurry/forms/ui/button';
4-
import { FormMessage } from '@lambdacurry/forms/ui/form';
54
import { Label } from '@lambdacurry/forms/ui/label';
65
import { RadioGroupItem } from '@lambdacurry/forms/ui/radio-group';
76
import type { Meta, StoryObj } from '@storybook/react';
87
import { expect, userEvent, within } from '@storybook/test';
98
import { type ActionFunctionArgs, Form, useFetcher } from 'react-router';
10-
import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form';
9+
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1110
import { z } from 'zod';
1211
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1312

@@ -20,38 +19,22 @@ const AVAILABLE_SIZES = [
2019
] as const;
2120

2221
const formSchema = z.object({
23-
size: z.string({
22+
size: z.enum(['xs', 'sm', 'md', 'lg', 'xl'], {
2423
required_error: 'Please select a size',
2524
}),
2625
});
2726

2827
type FormData = z.infer<typeof formSchema>;
2928

3029
const ControlledRadioGroupExample = () => {
31-
const fetcher = useFetcher<{ message: string; selectedSize: string }>();
30+
const fetcher = useFetcher<{ message: string; selectedSize: string; errors?: Record<string, { message: string }> }>();
3231
const methods = useRemixForm<FormData>({
3332
resolver: zodResolver(formSchema),
34-
defaultValues: {
35-
size: '',
36-
},
3733
fetcher,
3834
submitConfig: {
3935
action: '/',
4036
method: 'post',
4137
},
42-
submitHandlers: {
43-
onValid: (data) => {
44-
fetcher.submit(
45-
createFormData({
46-
selectedSize: data.size,
47-
}),
48-
{
49-
method: 'post',
50-
action: '/',
51-
},
52-
);
53-
},
54-
},
5538
});
5639

5740
return (
@@ -66,7 +49,6 @@ const ControlledRadioGroupExample = () => {
6649
</div>
6750
))}
6851
</RadioGroup>
69-
<FormMessage error={methods.formState.errors.size?.message} />
7052
<Button type="submit" className="mt-4">
7153
Submit
7254
</Button>

apps/docs/src/remix-hook-form/switch-custom.stories.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { Switch } from '@lambdacurry/forms/remix-hook-form/switch';
33
import { Button } from '@lambdacurry/forms/ui/button';
44
import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form';
55
import * as SwitchPrimitives from '@radix-ui/react-switch';
6-
import type { ActionFunctionArgs } from '@remix-run/node';
7-
import { useFetcher } from '@remix-run/react';
86
import type { Meta, StoryObj } from '@storybook/react';
97
import { expect, userEvent, within } from '@storybook/test';
108
import * as React from 'react';
9+
import type { ActionFunctionArgs } from 'react-router';
10+
import { useFetcher } from 'react-router';
1111
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1212
import { z } from 'zod';
13-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
13+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1414

1515
const formSchema = z.object({
1616
notifications: z.boolean().default(false),
@@ -184,11 +184,13 @@ const meta: Meta<typeof Switch> = {
184184
parameters: { layout: 'centered' },
185185
tags: ['autodocs'],
186186
decorators: [
187-
withRemixStubDecorator({
188-
root: {
189-
Component: CustomSwitchExample,
190-
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
191-
},
187+
withReactRouterStubDecorator({
188+
routes: [
189+
{
190+
path: '/',
191+
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
192+
},
193+
],
192194
}),
193195
],
194196
} satisfies Meta<typeof Switch>;

apps/docs/src/remix-hook-form/text-field-custom.stories.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { zodResolver } from '@hookform/resolvers/zod';
22
import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field';
33
import { Button } from '@lambdacurry/forms/ui/button';
44
import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form';
5-
import type { ActionFunctionArgs } from '@remix-run/node';
6-
import { useFetcher } from '@remix-run/react';
75
import type { Meta, StoryObj } from '@storybook/react';
86
import { expect, userEvent, within } from '@storybook/test';
97
import * as React from 'react';
8+
import type { ActionFunctionArgs } from 'react-router';
9+
import { useFetcher } from 'react-router';
1010
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1111
import { z } from 'zod';
12-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
12+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1313

1414
const formSchema = z.object({
1515
username: z.string().min(3, 'Username must be at least 3 characters'),
@@ -138,11 +138,13 @@ const meta: Meta<typeof TextField> = {
138138
parameters: { layout: 'centered' },
139139
tags: ['autodocs'],
140140
decorators: [
141-
withRemixStubDecorator({
142-
root: {
143-
Component: CustomTextFieldExample,
144-
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
145-
},
141+
withReactRouterStubDecorator({
142+
routes: [
143+
{
144+
path: '/',
145+
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
146+
},
147+
],
146148
}),
147149
],
148150
} satisfies Meta<typeof TextField>;

apps/docs/src/remix-hook-form/textarea-custom.stories.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { zodResolver } from '@hookform/resolvers/zod';
22
import { Textarea } from '@lambdacurry/forms/remix-hook-form/textarea';
33
import { Button } from '@lambdacurry/forms/ui/button';
44
import { FormControl, FormItem, FormLabel, FormMessage } from '@lambdacurry/forms/ui/form';
5-
import type { ActionFunctionArgs } from '@remix-run/node';
6-
import { useFetcher } from '@remix-run/react';
75
import type { Meta, StoryObj } from '@storybook/react';
86
import { expect, userEvent, within } from '@storybook/test';
97
import * as React from 'react';
8+
import type { ActionFunctionArgs } from 'react-router';
9+
import { useFetcher } from 'react-router';
1010
import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form';
1111
import { z } from 'zod';
12-
import { withRemixStubDecorator } from '../lib/storybook/remix-stub';
12+
import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub';
1313

1414
const formSchema = z.object({
1515
feedback: z.string().min(10, 'Feedback must be at least 10 characters'),
@@ -184,11 +184,13 @@ const meta: Meta<typeof Textarea> = {
184184
parameters: { layout: 'centered' },
185185
tags: ['autodocs'],
186186
decorators: [
187-
withRemixStubDecorator({
188-
root: {
189-
Component: CustomTextareaExample,
190-
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
191-
},
187+
withReactRouterStubDecorator({
188+
routes: [
189+
{
190+
path: '/',
191+
action: async ({ request }: ActionFunctionArgs) => handleFormSubmission(request),
192+
},
193+
],
192194
}),
193195
],
194196
} satisfies Meta<typeof Textarea>;

packages/components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"devDependencies": {
7474
"@react-router/dev": "^7.0.0",
7575
"@types/glob": "^8.1.0",
76-
"@types/react": "^18.0.0",
76+
"@types/react": "^19.0.0",
7777
"@typescript-eslint/eslint-plugin": "^6.21.0",
7878
"@typescript-eslint/parser": "^6.21.0",
7979
"@vitejs/plugin-react": "^4.3.4",

packages/components/src/ui/checkbox-field.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ const CheckboxField = ({
7171
className={isCustomCheckbox ? undefined : defaultCheckboxClassName}
7272
checked={field.value}
7373
onCheckedChange={field.onChange}
74+
data-slot="checkbox"
7475
{...props}
7576
>
76-
<IndicatorComponent className={isCustomIndicator ? undefined : defaultIndicatorClassName}>
77+
<IndicatorComponent
78+
className={isCustomIndicator ? undefined : defaultIndicatorClassName}
79+
data-slot="checkbox-indicator"
80+
>
7781
<Check className={cn('h-4 w-4', checkClassName)} />
7882
</IndicatorComponent>
7983
</CheckboxComponent>

0 commit comments

Comments
 (0)