diff --git a/apps/docs/src/remix-hook-form/context-debug-comparison.stories.tsx b/apps/docs/src/remix-hook-form/context-debug-comparison.stories.tsx new file mode 100644 index 00000000..ffa1a937 --- /dev/null +++ b/apps/docs/src/remix-hook-form/context-debug-comparison.stories.tsx @@ -0,0 +1,197 @@ +import { zodResolver } from '@hookform/resolvers/zod'; +import { Textarea } from '@lambdacurry/forms/remix-hook-form/textarea'; +import { Button } from '@lambdacurry/forms/ui/button'; +import type { Meta, StoryObj } from '@storybook/react-vite'; +import * as React from 'react'; +import { useEffect } from 'react'; +import { type ActionFunctionArgs, useFetcher } from 'react-router'; +import { RemixFormProvider, getValidatedFormData, useRemixForm, useRemixFormContext } from 'remix-hook-form'; +import { z } from 'zod'; +import { withReactRouterStubDecorator } from '../lib/storybook/react-router-stub'; + +const formSchema = z.object({ + message: z.string().min(10, 'Message must be at least 10 characters'), +}); + +type FormData = z.infer; + +// Context monitoring component +const ContextMonitor = ({ label }: { label: string }) => { + const [status, setStatus] = React.useState('Checking...'); + const context = useRemixFormContext(); + + useEffect(() => { + try { + if (context) { + setStatus(`✅ ${label}: Context OK`); + console.log(`[${label}] Context available:`, context); + } else { + setStatus(`❌ ${label}: Context NULL`); + console.log(`[${label}] Context is null:`, context); + } + } catch (error) { + setStatus(`🚨 ${label}: Error - ${error instanceof Error ? error.message : 'Unknown error'}`); + console.error(`[${label}] Context error:`, error); + } + }, [label, context]); + + return ( +
+ {status} +
+ ); +}; + +// Working pattern (like textarea-custom) +const WorkingPatternExample = () => { + const fetcher = useFetcher<{ message: string }>(); + const methods = useRemixForm({ + resolver: zodResolver(formSchema), + defaultValues: { message: '' }, + fetcher, + submitConfig: { action: '/', method: 'post' }, + }); + + const messageId = React.useId(); + + return ( + +
+

✅ Working Pattern (Direct DOM)

+ + + +
+ +