From 1b6dc5a7201e7848e08d3e6c36469ea775ca9a73 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sun, 8 Jun 2025 03:19:24 +0000 Subject: [PATCH 1/2] Update storybook test patterns to match modern standards - Update imports from 'storybook/test' to '@storybook/test' - Add 'within' import for canvas element querying - Update play function signatures to use destructured parameters - Add step-based test organization for better debugging - Preserve existing test logic while modernizing structure - Apply patterns from date-picker and calendar components Files updated: - checkbox.stories.tsx: Added step organization and modern patterns - switch.stories.tsx: Updated imports and step structure - checkbox-custom.stories.tsx: Updated imports - switch-custom.stories.tsx: Updated imports and type fixes - checkbox-list.stories.tsx: Updated imports and dependencies - radio-group.stories.tsx: Updated imports and streamlined dependencies - radio-group-custom.stories.tsx: Updated imports and type fixes - text-field.stories.tsx: Updated imports - text-field-custom.stories.tsx: Updated imports and type fixes - textarea.stories.tsx: Updated imports - textarea-custom.stories.tsx: Updated imports - dropdown-menu-select.stories.tsx: Updated imports and dependencies - otp-input.stories.tsx: Updated imports and dependencies --- .../checkbox-custom.stories.tsx | 2 +- .../remix-hook-form/checkbox-list.stories.tsx | 10 +-- .../src/remix-hook-form/checkbox.stories.tsx | 79 +++++++++++-------- .../dropdown-menu-select.stories.tsx | 4 +- .../src/remix-hook-form/otp-input.stories.tsx | 4 +- .../radio-group-custom.stories.tsx | 13 ++- .../remix-hook-form/radio-group.stories.tsx | 11 +-- .../remix-hook-form/switch-custom.stories.tsx | 48 +++++------ .../src/remix-hook-form/switch.stories.tsx | 45 ++++++++--- .../text-field-custom.stories.tsx | 8 +- .../remix-hook-form/text-field.stories.tsx | 2 +- .../textarea-custom.stories.tsx | 2 +- .../src/remix-hook-form/textarea.stories.tsx | 2 +- 13 files changed, 127 insertions(+), 103 deletions(-) diff --git a/apps/docs/src/remix-hook-form/checkbox-custom.stories.tsx b/apps/docs/src/remix-hook-form/checkbox-custom.stories.tsx index 223b49fa..4e2c59c5 100644 --- a/apps/docs/src/remix-hook-form/checkbox-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/checkbox-custom.stories.tsx @@ -4,7 +4,7 @@ import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/ import { Button } from '@lambdacurry/forms/ui/button'; import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import type * as React from 'react'; import type { ActionFunctionArgs } from 'react-router'; import { useFetcher } from 'react-router'; diff --git a/apps/docs/src/remix-hook-form/checkbox-list.stories.tsx b/apps/docs/src/remix-hook-form/checkbox-list.stories.tsx index d4f9e9b4..a7944822 100644 --- a/apps/docs/src/remix-hook-form/checkbox-list.stories.tsx +++ b/apps/docs/src/remix-hook-form/checkbox-list.stories.tsx @@ -1,12 +1,10 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Checkbox } from '@lambdacurry/forms/remix-hook-form/checkbox'; import { Button } from '@lambdacurry/forms/ui/button'; -import { FormMessage } from '@lambdacurry/forms/ui/form'; -import type { Meta, StoryContext, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent } from 'storybook/test'; -import type {} from '@testing-library/dom'; -import { type ActionFunctionArgs, Form, useFetcher } from 'react-router'; -import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { expect, userEvent, within } from '@storybook/test'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; +import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/checkbox.stories.tsx b/apps/docs/src/remix-hook-form/checkbox.stories.tsx index 01ba8ff2..74cf0797 100644 --- a/apps/docs/src/remix-hook-form/checkbox.stories.tsx +++ b/apps/docs/src/remix-hook-form/checkbox.stories.tsx @@ -1,8 +1,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Checkbox } from '@lambdacurry/forms/remix-hook-form/checkbox'; import { Button } from '@lambdacurry/forms/ui/button'; -import type { Meta, StoryContext, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent } from 'storybook/test'; +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { expect, userEvent, within } from '@storybook/test'; import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; @@ -84,34 +84,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -const testDefaultValues = ({ canvas }: StoryContext) => { - const termsCheckbox = canvas.getByLabelText('Accept terms and conditions'); - const marketingCheckbox = canvas.getByLabelText('Receive marketing emails'); - const requiredCheckbox = canvas.getByLabelText('This is a required checkbox'); - expect(termsCheckbox).not.toBeChecked(); - expect(marketingCheckbox).not.toBeChecked(); - expect(requiredCheckbox).not.toBeChecked(); -}; - -const testInvalidSubmission = async ({ canvas }: StoryContext) => { - const submitButton = canvas.getByRole('button', { name: 'Submit' }); - await userEvent.click(submitButton); - await expect(await canvas.findByText('You must accept the terms and conditions')).toBeInTheDocument(); - await expect(await canvas.findByText('This field is required')).toBeInTheDocument(); -}; - -const testValidSubmission = async ({ canvas }: StoryContext) => { - const termsCheckbox = canvas.getByLabelText('Accept terms and conditions'); - const requiredCheckbox = canvas.getByLabelText('This is a required checkbox'); - await userEvent.click(termsCheckbox); - await userEvent.click(requiredCheckbox); - - const submitButton = canvas.getByRole('button', { name: 'Submit' }); - await userEvent.click(submitButton); - - await expect(await canvas.findByText('Form submitted successfully')).toBeInTheDocument(); -}; - export const Default: Story = { parameters: { docs: { @@ -161,9 +133,48 @@ const ControlledCheckboxExample = () => { }, }, }, - play: async (storyContext) => { - testDefaultValues(storyContext); - await testInvalidSubmission(storyContext); - await testValidSubmission(storyContext); + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step('Verify initial state', async () => { + // Verify all checkboxes are unchecked initially + const termsCheckbox = canvas.getByLabelText('Accept terms and conditions'); + const marketingCheckbox = canvas.getByLabelText('Receive marketing emails'); + const requiredCheckbox = canvas.getByLabelText('This is a required checkbox'); + + expect(termsCheckbox).not.toBeChecked(); + expect(marketingCheckbox).not.toBeChecked(); + expect(requiredCheckbox).not.toBeChecked(); + + // Verify submit button is present + const submitButton = canvas.getByRole('button', { name: 'Submit' }); + expect(submitButton).toBeInTheDocument(); + }); + + await step('Test validation errors on invalid submission', async () => { + // Submit form without checking required checkboxes + const submitButton = canvas.getByRole('button', { name: 'Submit' }); + await userEvent.click(submitButton); + + // Verify validation error messages appear + await expect(canvas.findByText('You must accept the terms and conditions')).resolves.toBeInTheDocument(); + await expect(canvas.findByText('This field is required')).resolves.toBeInTheDocument(); + }); + + await step('Test successful form submission', async () => { + // Check required checkboxes + const termsCheckbox = canvas.getByLabelText('Accept terms and conditions'); + const requiredCheckbox = canvas.getByLabelText('This is a required checkbox'); + + await userEvent.click(termsCheckbox); + await userEvent.click(requiredCheckbox); + + // Submit form + const submitButton = canvas.getByRole('button', { name: 'Submit' }); + await userEvent.click(submitButton); + + // Verify success message + await expect(canvas.findByText('Form submitted successfully')).resolves.toBeInTheDocument(); + }); }, }; diff --git a/apps/docs/src/remix-hook-form/dropdown-menu-select.stories.tsx b/apps/docs/src/remix-hook-form/dropdown-menu-select.stories.tsx index 904e4c01..657f8674 100644 --- a/apps/docs/src/remix-hook-form/dropdown-menu-select.stories.tsx +++ b/apps/docs/src/remix-hook-form/dropdown-menu-select.stories.tsx @@ -3,8 +3,8 @@ import { DropdownMenuSelect } from '@lambdacurry/forms/remix-hook-form/dropdown- import { Button } from '@lambdacurry/forms/ui/button'; import { DropdownMenuSelectItem } from '@lambdacurry/forms/ui/dropdown-menu-select-field'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, screen, userEvent, within } from 'storybook/test'; -import { type ActionFunctionArgs, Form, useFetcher } from 'react-router'; +import { expect, screen, userEvent, within } from '@storybook/test'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/otp-input.stories.tsx b/apps/docs/src/remix-hook-form/otp-input.stories.tsx index 96035467..d5439574 100644 --- a/apps/docs/src/remix-hook-form/otp-input.stories.tsx +++ b/apps/docs/src/remix-hook-form/otp-input.stories.tsx @@ -2,8 +2,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { OTPInput } from '@lambdacurry/forms/remix-hook-form/otp-input'; import { Button } from '@lambdacurry/forms/ui/button'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; -import { type ActionFunctionArgs, Form, useFetcher } from 'react-router'; +import { expect, userEvent, within } from '@storybook/test'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/radio-group-custom.stories.tsx b/apps/docs/src/remix-hook-form/radio-group-custom.stories.tsx index 0002f4e5..97a2557b 100644 --- a/apps/docs/src/remix-hook-form/radio-group-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/radio-group-custom.stories.tsx @@ -1,15 +1,14 @@ import { zodResolver } from '@hookform/resolvers/zod'; -import { RadioGroup } from '@lambdacurry/forms/remix-hook-form/radio-group'; +import { RadioGroup, type RadioOption } from '@lambdacurry/forms/remix-hook-form/radio-group'; import { RadioGroupItem } from '@lambdacurry/forms/remix-hook-form/radio-group-item'; +import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form'; import { Button } from '@lambdacurry/forms/ui/button'; -import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form'; -import { cn } from '@lambdacurry/forms/ui/utils'; +import { Label } from '@lambdacurry/forms/ui/label'; import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; -import type * as React from 'react'; -import type { ActionFunctionArgs } from 'react-router'; -import { Form, useFetcher } from 'react-router'; +import { expect, userEvent, within } from '@storybook/test'; +import type { ComponentPropsWithoutRef, ComponentType } from 'react'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/radio-group.stories.tsx b/apps/docs/src/remix-hook-form/radio-group.stories.tsx index 5a34cc17..6e93348d 100644 --- a/apps/docs/src/remix-hook-form/radio-group.stories.tsx +++ b/apps/docs/src/remix-hook-form/radio-group.stories.tsx @@ -1,13 +1,10 @@ import { zodResolver } from '@hookform/resolvers/zod'; -import { RadioGroup, type RadioOption } from '@lambdacurry/forms/remix-hook-form/radio-group'; -import { RadioGroupItem } from '@lambdacurry/forms/remix-hook-form/radio-group-item'; +import { RadioGroup } from '@lambdacurry/forms/remix-hook-form/radio-group'; import { Button } from '@lambdacurry/forms/ui/button'; -import { Label } from '@lambdacurry/forms/ui/label'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; -import type { ComponentPropsWithoutRef, ComponentType } from 'react'; -import { type ActionFunctionArgs, Form, useFetcher } from 'react-router'; -import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; +import { expect, userEvent, within } from '@storybook/test'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; +import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/switch-custom.stories.tsx b/apps/docs/src/remix-hook-form/switch-custom.stories.tsx index 1a210894..131daa50 100644 --- a/apps/docs/src/remix-hook-form/switch-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/switch-custom.stories.tsx @@ -1,14 +1,14 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Switch } from '@lambdacurry/forms/remix-hook-form/switch'; +import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form'; import { Button } from '@lambdacurry/forms/ui/button'; -import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form'; -import * as SwitchPrimitives from '@radix-ui/react-switch'; +import * as SwitchPrimitive from '@radix-ui/react-switch'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import type * as React from 'react'; import type { ActionFunctionArgs } from 'react-router'; import { useFetcher } from 'react-router'; -import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; +import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; @@ -21,19 +21,19 @@ const formSchema = z.object({ type FormData = z.infer; // Custom Switch component -const PurpleSwitch = (props: React.ComponentPropsWithoutRef) => ( - ) => ( + {props.children} - + ); PurpleSwitch.displayName = 'PurpleSwitch'; // Custom Switch Thumb component -const PurpleSwitchThumb = (props: React.ComponentPropsWithoutRef) => ( - ) => ( + @@ -43,7 +43,7 @@ const PurpleSwitchThumb = (props: React.ComponentPropsWithoutRef OFF - + ); PurpleSwitchThumb.displayName = 'PurpleSwitchThumb'; @@ -60,19 +60,19 @@ const PurpleMessage = (props: React.ComponentPropsWithoutRef PurpleMessage.displayName = 'PurpleMessage'; // Green Switch component -const GreenSwitch = (props: React.ComponentPropsWithoutRef) => ( - ) => ( + {props.children} - + ); GreenSwitch.displayName = 'GreenSwitch'; // Green Switch Thumb component -const GreenSwitchThumb = (props: React.ComponentPropsWithoutRef) => ( - ) => ( + @@ -86,7 +86,7 @@ const GreenSwitchThumb = (props: React.ComponentPropsWithoutRefCheck mark - + ); GreenSwitchThumb.displayName = 'GreenSwitchThumb'; @@ -234,17 +234,17 @@ The \`components\` prop allows you to override any of the internal components us // APPROACH 2: Custom Switch with purple styling and ON/OFF text const PurpleSwitch = React.forwardRef((props, ref) => ( - {props.children} - + )); const PurpleSwitchThumb = React.forwardRef((props, ref) => ( - ( OFF - + )); ( // APPROACH 3: Fully customized switch with green styling, checkmark icon, and custom form components const GreenSwitch = React.forwardRef((props, ref) => ( - {props.children} - + )); const GreenSwitchThumb = React.forwardRef((props, ref) => ( - ( > - + )); const PurpleLabel = React.forwardRef((props, ref) => ( diff --git a/apps/docs/src/remix-hook-form/switch.stories.tsx b/apps/docs/src/remix-hook-form/switch.stories.tsx index b3f564eb..79cf3ff4 100644 --- a/apps/docs/src/remix-hook-form/switch.stories.tsx +++ b/apps/docs/src/remix-hook-form/switch.stories.tsx @@ -2,7 +2,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Switch } from '@lambdacurry/forms/remix-hook-form/switch'; import { Button } from '@lambdacurry/forms/ui/button'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; @@ -118,22 +118,41 @@ export const Default: Story = { }, }, }, - play: async ({ canvasElement }) => { + play: async ({ canvasElement, step }) => { const canvas = within(canvasElement); - // Toggle switches - const notificationsSwitch = canvas.getByLabelText('Enable notifications'); - const marketingSwitch = canvas.getByLabelText('Receive marketing emails'); + await step('Verify initial state', async () => { + // Verify switches are initially unchecked + const notificationsSwitch = canvas.getByLabelText('Enable notifications'); + const marketingSwitch = canvas.getByLabelText('Receive marketing emails'); + + expect(notificationsSwitch).not.toBeChecked(); + expect(marketingSwitch).not.toBeChecked(); + + // Verify submit button is present + const submitButton = canvas.getByRole('button', { name: 'Submit' }); + expect(submitButton).toBeInTheDocument(); + }); - await userEvent.click(notificationsSwitch); - expect(notificationsSwitch).toBeChecked(); + await step('Toggle switches and verify state', async () => { + // Toggle notifications switch + const notificationsSwitch = canvas.getByLabelText('Enable notifications'); + await userEvent.click(notificationsSwitch); + expect(notificationsSwitch).toBeChecked(); + + // Marketing switch should remain unchecked + const marketingSwitch = canvas.getByLabelText('Receive marketing emails'); + expect(marketingSwitch).not.toBeChecked(); + }); - // Submit the form - const submitButton = canvas.getByRole('button', { name: 'Submit' }); - await userEvent.click(submitButton); + await step('Submit form and verify results', async () => { + // Submit the form + const submitButton = canvas.getByRole('button', { name: 'Submit' }); + await userEvent.click(submitButton); - // Check if the submitted values are displayed - await expect(await canvas.findByText('Notifications: Enabled')).toBeInTheDocument(); - await expect(await canvas.findByText('Marketing emails: Disabled')).toBeInTheDocument(); + // Check if the submitted values are displayed correctly + await expect(canvas.findByText('Notifications: Enabled')).resolves.toBeInTheDocument(); + await expect(canvas.findByText('Marketing emails: Disabled')).resolves.toBeInTheDocument(); + }); }, }; diff --git a/apps/docs/src/remix-hook-form/text-field-custom.stories.tsx b/apps/docs/src/remix-hook-form/text-field-custom.stories.tsx index d0522c75..aeebe8cc 100644 --- a/apps/docs/src/remix-hook-form/text-field-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/text-field-custom.stories.tsx @@ -1,12 +1,12 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field'; +import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form'; import { Button } from '@lambdacurry/forms/ui/button'; -import { FormLabel, FormMessage } from '@lambdacurry/forms/ui/form'; +import { Input } from '@lambdacurry/forms/ui/input'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import type * as React from 'react'; -import type { ActionFunctionArgs } from 'react-router'; -import { useFetcher } from 'react-router'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/text-field.stories.tsx b/apps/docs/src/remix-hook-form/text-field.stories.tsx index 8c4afee3..07a03110 100644 --- a/apps/docs/src/remix-hook-form/text-field.stories.tsx +++ b/apps/docs/src/remix-hook-form/text-field.stories.tsx @@ -5,7 +5,7 @@ import type { Meta, StoryContext, StoryObj } from '@storybook/react-vite'; import { useRef } from 'react'; import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, getValidatedFormData, useRemixForm } from 'remix-hook-form'; -import { expect, userEvent } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; diff --git a/apps/docs/src/remix-hook-form/textarea-custom.stories.tsx b/apps/docs/src/remix-hook-form/textarea-custom.stories.tsx index ac8d5308..1395ecf4 100644 --- a/apps/docs/src/remix-hook-form/textarea-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/textarea-custom.stories.tsx @@ -3,7 +3,7 @@ import { Textarea } from '@lambdacurry/forms/remix-hook-form/textarea'; import { Button } from '@lambdacurry/forms/ui/button'; import { FormControl, FormItem, FormLabel, FormMessage } from '@lambdacurry/forms/ui/form'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import * as React from 'react'; import type { ActionFunctionArgs } from 'react-router'; import { useFetcher } from 'react-router'; diff --git a/apps/docs/src/remix-hook-form/textarea.stories.tsx b/apps/docs/src/remix-hook-form/textarea.stories.tsx index 7cfdfcf4..36f5d977 100644 --- a/apps/docs/src/remix-hook-form/textarea.stories.tsx +++ b/apps/docs/src/remix-hook-form/textarea.stories.tsx @@ -4,7 +4,7 @@ import { Button } from '@lambdacurry/forms/ui/button'; import type { Meta, StoryObj } from '@storybook/react-vite'; import { type ActionFunctionArgs, useFetcher } from 'react-router'; import { RemixFormProvider, createFormData, getValidatedFormData, useRemixForm } from 'remix-hook-form'; -import { expect, userEvent, within } from 'storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import { z } from 'zod'; import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; From fc4ba3629275f39db7a5ae6381947861c7d93742 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Sun, 8 Jun 2025 03:31:51 +0000 Subject: [PATCH 2/2] Fix FormLabel import error in switch-custom component - Change FormLabel and FormMessage from type-only imports to actual imports - This fixes the 'Can't find variable: FormLabel' runtime error - Components need to be imported as actual values, not just types --- apps/docs/src/remix-hook-form/switch-custom.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/src/remix-hook-form/switch-custom.stories.tsx b/apps/docs/src/remix-hook-form/switch-custom.stories.tsx index 131daa50..2a3246c3 100644 --- a/apps/docs/src/remix-hook-form/switch-custom.stories.tsx +++ b/apps/docs/src/remix-hook-form/switch-custom.stories.tsx @@ -1,6 +1,6 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Switch } from '@lambdacurry/forms/remix-hook-form/switch'; -import type { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form'; +import { FormLabel, FormMessage } from '@lambdacurry/forms/remix-hook-form/form'; import { Button } from '@lambdacurry/forms/ui/button'; import * as SwitchPrimitive from '@radix-ui/react-switch'; import type { Meta, StoryObj } from '@storybook/react-vite';