{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "dependencies": [
    "@base-ui/react",
    "react-aria-components"
  ],
  "files": [
    {
      "content": "export * from \"./field\";\nexport * as Field from \"./namespace\";\nexport * from \"./styles\";\n",
      "path": "src/registry/ui/field/index.ts",
      "type": "registry:ui"
    },
    {
      "content": "\"use client\";\n\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport type { VariantProps } from \"cva\";\nimport { use, useMemo } from \"react\";\nimport {\n  FieldError as AriaFieldError,\n  FieldErrorContext,\n  Text,\n} from \"react-aria-components\";\nimport { Label } from \"~/registry/ui/label\";\nimport { Separator } from \"~/registry/ui/separator\";\nimport { FieldStyles } from \"./styles\";\n\nexport interface FieldSetProps extends React.ComponentProps<\"fieldset\"> {}\n\nexport function FieldSet({ className, ...props }: FieldSetProps) {\n  return (\n    <fieldset\n      className={FieldStyles.Set({ className })}\n      data-slot=\"field-set\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldLegendProps\n  extends React.ComponentProps<\"legend\">,\n    VariantProps<typeof FieldStyles.Legend> {}\n\nexport function FieldLegend({\n  className,\n  variant = \"legend\",\n  ...props\n}: FieldLegendProps) {\n  return (\n    <legend\n      className={FieldStyles.Legend({ variant, className })}\n      data-slot=\"field-legend\"\n      data-variant={variant}\n      {...props}\n    />\n  );\n}\n\nexport interface FieldGroupProps extends React.ComponentProps<\"div\"> {}\n\nexport function FieldGroup({ className, ...props }: FieldGroupProps) {\n  return (\n    <div\n      className={FieldStyles.Group({ className })}\n      data-slot=\"field-group\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldRootProps\n  extends useRender.ComponentProps<\"div\">,\n    VariantProps<typeof FieldStyles.Root> {}\n\nexport function FieldRoot({\n  render,\n  className,\n  orientation = \"vertical\",\n  ...props\n}: FieldRootProps) {\n  const defaultProps: useRender.ElementProps<\"div\"> = {\n    className: FieldStyles.Root({ orientation, className }),\n    role: \"group\",\n  };\n\n  return useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(defaultProps, props),\n    state: {\n      orientation,\n      slot: \"field-root\",\n    },\n  });\n}\n\nexport interface FieldContentProps extends React.ComponentProps<\"div\"> {}\n\nexport function FieldContent({ className, ...props }: FieldContentProps) {\n  return (\n    <div\n      className={FieldStyles.Content({ className })}\n      data-slot=\"field-content\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldLabelProps extends React.ComponentProps<typeof Label> {}\n\nexport function FieldLabel({ className, ...props }: FieldLabelProps) {\n  return (\n    <Label\n      className={FieldStyles.Label({ className })}\n      data-slot=\"field-label\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldTitleProps extends React.ComponentProps<\"div\"> {}\n\nexport function FieldTitle({ className, ...props }: FieldTitleProps) {\n  return (\n    <div\n      className={FieldStyles.Title({ className })}\n      data-slot=\"field-title\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldDescriptionProps\n  extends React.ComponentProps<typeof Text> {}\n\nexport function FieldDescription({\n  className,\n  ...props\n}: FieldDescriptionProps) {\n  return (\n    <Text\n      className={FieldStyles.Description({ className })}\n      data-slot=\"field-description\"\n      slot=\"description\"\n      {...props}\n    />\n  );\n}\n\nexport interface FieldSeparatorProps extends React.ComponentProps<\"div\"> {\n  children?: React.ReactNode;\n}\n\nexport function FieldSeparator({\n  children,\n  className,\n  ...props\n}: FieldSeparatorProps) {\n  return (\n    <div\n      className={FieldStyles.Separator({ className })}\n      data-content={!!children}\n      data-slot=\"field-separator\"\n      {...props}\n    >\n      <Separator className=\"absolute inset-0 top-1/2\" />\n      {children && (\n        <span\n          className=\"relative mx-auto block w-fit bg-background px-2 text-muted-foreground\"\n          data-slot=\"field-separator-content\"\n        >\n          {children}\n        </span>\n      )}\n    </div>\n  );\n}\n\nexport interface FieldErrorProps\n  extends React.ComponentProps<typeof AriaFieldError> {\n  errors?: Array<{ message?: string } | undefined>;\n}\n\nexport function FieldError({\n  className,\n  children,\n  errors,\n  ...props\n}: FieldErrorProps) {\n  const fieldErrorCtx = use(FieldErrorContext);\n  const _errors =\n    errors ?? fieldErrorCtx?.validationErrors.map((message) => ({ message }));\n\n  const content = useMemo(() => {\n    if (children) {\n      return children;\n    }\n\n    if (!_errors?.length) {\n      return null;\n    }\n\n    const uniqueErrors = [\n      ...new Map(\n        _errors.map((error, index) => [error?.message, { ...error, id: index }])\n      ).values(),\n    ];\n\n    if (uniqueErrors.length === 1) {\n      return <span>{uniqueErrors.at(0)?.message}</span>;\n    }\n\n    return (\n      <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n        {uniqueErrors.map(\n          (error) => error?.message && <li key={error.id}>{error.message}</li>\n        )}\n      </ul>\n    );\n  }, [children, _errors]);\n\n  if (!content) {\n    return null;\n  }\n\n  const errorEl = (\n    <AriaFieldError\n      className={FieldStyles.Error({ className })}\n      data-slot=\"field-error\"\n      render={(props) => <div {...props} />}\n      {...props}\n    >\n      {content}\n    </AriaFieldError>\n  );\n\n  // When errors are passed explicitly and there's no React Aria field context,\n  // AriaFieldError returns null because validation?.isInvalid is falsy.\n  // Wrap with FieldErrorContext to provide the required isInvalid signal.\n  if (!fieldErrorCtx && _errors?.length) {\n    return (\n      <FieldErrorContext\n        value={{\n          isInvalid: true,\n          validationErrors: [],\n          validationDetails: {} as ValidityState,\n        }}\n      >\n        {errorEl}\n      </FieldErrorContext>\n    );\n  }\n\n  return errorEl;\n}\n",
      "path": "src/registry/ui/field/field.tsx",
      "type": "registry:ui"
    },
    {
      "content": "export {\n  FieldContent as Content,\n  FieldDescription as Description,\n  FieldError as Error,\n  FieldGroup as Group,\n  FieldLabel as Label,\n  FieldLegend as Legend,\n  FieldRoot as Root,\n  FieldSeparator as Separator,\n  FieldSet as Set,\n  FieldTitle as Title,\n} from \"./field\";\n",
      "path": "src/registry/ui/field/namespace.ts",
      "type": "registry:ui"
    },
    {
      "content": "import { cva } from \"~/registry/lib/cva\";\n\nexport const FieldStyles = {\n  Set: cva({\n    base: [\n      \"flex flex-col gap-6\",\n      \"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3\",\n    ],\n  }),\n  Legend: cva({\n    base: [\"mb-3 font-medium\"],\n    variants: {\n      variant: {\n        legend: \"text-base\",\n        label: \"text-sm\",\n      },\n    },\n    defaultVariants: {\n      variant: \"legend\",\n    },\n  }),\n  Group: cva({\n    base: [\n      \"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4\",\n    ],\n  }),\n  Root: cva({\n    base: \"group/field flex w-full gap-3 data-[invalid=true]:text-destructive\",\n\n    variants: {\n      orientation: {\n        vertical: [\"flex-col *:w-full [&>.sr-only]:w-auto\"],\n        horizontal: [\n          \"flex-row items-center\",\n          \"*:data-[slot=field-label]:flex-auto\",\n          \"has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n        ],\n        responsive: [\n          \"@md/field-group:flex-row flex-col @md/field-group:items-center *:w-full @md/field-group:*:w-auto [&>.sr-only]:w-auto\",\n          \"@md/field-group:*:data-[slot=field-label]:flex-auto\",\n          \"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n        ],\n      },\n    },\n    defaultVariants: {\n      orientation: \"vertical\",\n    },\n  }),\n  Content: cva({\n    base: [\"group/field-content flex flex-1 flex-col gap-1.5 leading-snug\"],\n  }),\n  Label: cva({\n    base: [\n      \"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50\",\n      \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border *:data-[slot=field]:p-4\",\n      \"has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary/5 dark:has-data-[state=checked]:bg-primary/10\",\n    ],\n  }),\n  Title: cva({\n    base: [\n      \"flex w-fit items-center gap-2 font-medium text-sm leading-snug group-data-[disabled=true]/field:opacity-50\",\n    ],\n  }),\n  Description: cva({\n    base: [\n      \"font-normal text-muted-foreground text-sm leading-normal group-has-orientation-horizontal/field:text-balance\",\n      \"nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5\",\n      \"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4\",\n    ],\n  }),\n  Separator: cva({\n    base: [\n      \"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2\",\n    ],\n  }),\n  Error: cva({\n    base: [\"font-normal text-destructive text-sm\"],\n  }),\n};\n",
      "path": "src/registry/ui/field/styles.ts",
      "type": "registry:ui"
    }
  ],
  "name": "field",
  "registryDependencies": [
    "@kanpeki/label",
    "@kanpeki/separator"
  ],
  "type": "registry:ui"
}