@@ -247,7 +247,143 @@ export const CustomCheckboxComponentExamples: Story = {
247247 parameters : {
248248 docs : {
249249 description : {
250- story : 'Examples of custom checkbox components with different styling options.' ,
250+ story : `
251+ ### Checkbox Component Customization
252+
253+ This example demonstrates three different approaches to customizing the Checkbox component with complete control over styling and behavior.
254+
255+ #### 1. Custom Checkbox Appearance
256+
257+ The first approach customizes the visual appearance of the checkbox itself:
258+
259+ \`\`\`tsx
260+ <Checkbox
261+ name="terms"
262+ label="Accept terms and conditions"
263+ description="You must accept our terms to continue"
264+ components={{
265+ Checkbox: PurpleCheckbox,
266+ CheckboxIndicator: PurpleIndicator,
267+ }}
268+ />
269+ \`\`\`
270+
271+ Where the custom components are defined as:
272+
273+ \`\`\`tsx
274+ // Custom checkbox component
275+ const PurpleCheckbox = React.forwardRef<
276+ HTMLButtonElement,
277+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
278+ >((props, ref) => (
279+ <CheckboxPrimitive.Root
280+ ref={ref}
281+ {...props}
282+ className="h-8 w-8 rounded-full border-4 border-purple-500 bg-white data-[state=checked]:bg-purple-500"
283+ >
284+ {props.children}
285+ </CheckboxPrimitive.Root>
286+ ));
287+
288+ // Custom indicator
289+ const PurpleIndicator = React.forwardRef<
290+ HTMLDivElement,
291+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Indicator>
292+ >((props, ref) => (
293+ <CheckboxPrimitive.Indicator
294+ ref={ref}
295+ {...props}
296+ className="flex h-full w-full items-center justify-center text-white"
297+ >
298+ ✓
299+ </CheckboxPrimitive.Indicator>
300+ ));
301+ \`\`\`
302+
303+ #### 2. Custom Form Elements
304+
305+ The second approach customizes the form elements (label and error message) while keeping the default checkbox:
306+
307+ \`\`\`tsx
308+ <Checkbox
309+ name="required"
310+ label="This is a required checkbox"
311+ components={{
312+ FormLabel: CustomLabel,
313+ FormMessage: CustomErrorMessage,
314+ }}
315+ />
316+ \`\`\`
317+
318+ With the custom form components defined as:
319+
320+ \`\`\`tsx
321+ // Custom form label component
322+ const CustomLabel = React.forwardRef<
323+ HTMLLabelElement,
324+ React.ComponentPropsWithoutRef<typeof FormLabel>
325+ >(({ className, htmlFor, ...props }, ref) => (
326+ <label
327+ ref={ref}
328+ htmlFor={htmlFor}
329+ className={\`custom-label text-purple-600 font-bold text-lg \${className}\`}
330+ {...props}
331+ >
332+ {props.children} ★
333+ </label>
334+ ));
335+
336+ // Custom error message component
337+ const CustomErrorMessage = React.forwardRef<
338+ HTMLParagraphElement,
339+ React.ComponentPropsWithoutRef<typeof FormMessage>
340+ >(({ className, ...props }, ref) => (
341+ <p
342+ ref={ref}
343+ className={\`custom-error flex items-center text-red-500 bg-red-100 p-2 rounded-md \${className}\`}
344+ {...props}
345+ >
346+ <span className="mr-1 text-lg">⚠️</span> {props.children}
347+ </p>
348+ ));
349+ \`\`\`
350+
351+ #### 3. Combining Custom Components
352+
353+ The third approach combines both custom checkbox and form elements:
354+
355+ \`\`\`tsx
356+ // Create component objects for reuse
357+ const customCheckboxComponents = {
358+ Checkbox: PurpleCheckbox,
359+ CheckboxIndicator: PurpleIndicator,
360+ };
361+
362+ const customLabelComponents = {
363+ FormLabel: CustomLabel,
364+ FormMessage: CustomErrorMessage,
365+ };
366+
367+ // Use spread operator to combine them
368+ <Checkbox
369+ name="terms"
370+ label="Accept terms and conditions"
371+ components={{
372+ ...customCheckboxComponents,
373+ ...customLabelComponents,
374+ }}
375+ />
376+ \`\`\`
377+
378+ ### Key Points
379+
380+ - Always use React.forwardRef when creating custom components
381+ - Make sure to spread the props to pass all necessary attributes
382+ - Include the ref to maintain form functionality
383+ - Add a displayName to your component for better debugging
384+ - The components prop accepts replacements for Checkbox, CheckboxIndicator, FormLabel, FormMessage, and FormDescription
385+ - You can mix and match different custom components as needed
386+ ` ,
251387 } ,
252388 source : {
253389 code : `
@@ -370,4 +506,4 @@ const CustomErrorMessage = React.forwardRef<
370506 expect ( successMessage ) . toBeInTheDocument ( ) ;
371507 }
372508 } ,
373- } ;
509+ } ;
0 commit comments