'use client'; import * as React from 'react'; import { cva, type VariantProps } from '@/lib/cva'; import { cn } from '@/lib/utils'; import { Label } from '@/components/label/label'; const fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-destructive', { variants: { orientation: { /** Label above the control. The default for most forms. */ vertical: 'flex-col [&>*]:w-full [&>.sr-only]:w-auto', /** Label beside the control — suits checkboxes and switches. */ horizontal: 'flex-row items-center gap-3 [&>[data-slot=field-label]]:flex-auto', }, }, defaultVariants: { orientation: 'vertical', }, }); export interface FieldProps extends React.ComponentProps<'div'>, VariantProps { /** Marks the whole group invalid, tinting the label and error text. */ invalid?: boolean; } /** * Layout for one form control and its supporting text, without a form library. * * Use this when you manage state yourself; use the `form` subpath instead when * you are on react-hook-form, since that version also wires up `aria-invalid` * and `aria-describedby` from the validation state. * * You still own the accessible wiring here: give the control an `id` and point * `FieldLabel`'s `htmlFor` at it. * * ```tsx * * Email * * We never share it. * * ``` */ function Field({ className, orientation, invalid, ...props }: FieldProps) { return (
); } export interface FieldLabelProps extends React.ComponentProps { /** * Draws CBAR's required marker after the text — its `.isRequired?` slot. * * The marker is `aria-hidden`: an asterisk read aloud is noise, and the fact * that the field is required belongs on the control. Set `required` (or * `aria-required`) there as well — this prop only draws. */ required?: boolean; } function FieldLabel({ className, required, children, ...props }: FieldLabelProps) { return ( ); } /** Hint shown under the control. Reference its `id` from the input. */ function FieldDescription({ className, ...props }: React.ComponentProps<'p'>) { return (

); } /** Validation message. Announced live, so it is heard when it appears. */ function FieldError({ className, children, ...props }: React.ComponentProps<'p'>) { if (!children) return null; return (

{children}

); } /** Groups several fields into one titled section. Renders a real `
`. */ function FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) { return (
[data-slot=radio-group]]:gap-3 has-[>[data-slot=checkbox-group]]:gap-3', className )} {...props} /> ); } export interface FieldLegendProps extends React.ComponentProps<'legend'> { /** `label` renders at control-label size instead of section-heading size. */ variant?: 'legend' | 'label'; } function FieldLegend({ className, variant = 'legend', ...props }: FieldLegendProps) { return ( ); } /** Vertical stack of fields with consistent rhythm. */ function FieldGroup({ className, ...props }: React.ComponentProps<'div'>) { return (
[data-slot=field-group]]:gap-4', className)} {...props} /> ); } export { Field, FieldLabel, FieldDescription, FieldError, FieldSet, FieldLegend, FieldGroup, fieldVariants, };