{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "Field",
  "dependencies": [
    "cn",
    "rescript-base-ui"
  ],
  "registryDependencies": [
    "@rescript-shadcn/Label",
    "@rescript-shadcn/Separator"
  ],
  "files": [
    {
      "path": "registry/base/ui/Field.res",
      "content": "@@jsxConfig({version: 4, mode: \"automatic\", module_: \"BaseUi.BaseUiJsxDOM\"})\n\n@@directive(\"'use client'\")\n\n@module(\"cn\")\nexternal cn: (string, option<string>) => string = \"cn\"\n\nmodule Orientation = {\n  @unboxed\n  type t =\n    | @as(\"horizontal\") Horizontal\n    | @as(\"vertical\") Vertical\n    | @as(\"responsive\") Responsive\n}\n\nmodule Variant = {\n  @unboxed\n  type t =\n    | @as(\"legend\") Legend\n    | @as(\"label\") Label\n}\n\nlet fieldOrientationClass = (~orientation: Orientation.t) =>\n  switch orientation {\n  | Horizontal => \" flex-row items-center *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\"\n  | Responsive => \" flex-col *:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:*:data-[slot=field-label]:flex-auto @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  | Vertical => \" flex-col *:w-full [&>.sr-only]:w-auto\"\n  }\n\nlet fieldVariants = (~orientation=Orientation.Vertical) => {\n  let base = \"data-[invalid=true]:text-destructive gap-2 group/field flex w-full\"\n  `${base} ${fieldOrientationClass(~orientation)}`\n}\n\nmodule Set = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <fieldset\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-set\")}\n      className={cn(\n        \"gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col\",\n        props.className,\n      )}\n    />\n}\n\nmodule Legend = {\n  type props = {\n    ...BaseUi.Types.DomProps.t,\n    variant?: Variant.t,\n  }\n\n  let toBaseUiProps: props => BaseUi.Types.DomProps.t = %raw(`({variant, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let variant = props.variant->Option.getOr(Variant.Legend)\n    <legend\n      {...props->toBaseUiProps}\n      dataSlot={props.dataSlot->Option.getOr(\"field-legend\")}\n      dataVariant={props.dataVariant->Option.getOr((variant :> string))}\n      className={cn(\n        \"mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base\",\n        props.className,\n      )}\n    />\n  }\n}\n\nmodule Group = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <div\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-group\")}\n      className={cn(\n        \"gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col\",\n        props.className,\n      )}\n    />\n}\n\ntype props = {\n  ...BaseUi.Types.BaseDomWithoutOrientationProps.t,\n  ...BaseUi.Types.ExtraDomProps.t,\n  children?: React.element,\n  orientation?: Orientation.t,\n}\n\nlet toBaseUiProps: props => BaseUi.Types.DomProps.t = %raw(`({orientation, ...props}) => props`)\n\n@react.componentWithProps(props)\nlet make = (props: props) => {\n  let role = props.role->Option.getOr(\"group\")\n  let orientation = props.orientation->Option.getOr(Orientation.Vertical)\n  <div\n    {...props->toBaseUiProps}\n    role\n    dataSlot={props.dataSlot->Option.getOr(\"field\")}\n    dataOrientation={props.dataOrientation->Option.getOr((orientation :> string))}\n    className={cn(fieldVariants(~orientation), props.className)}\n  />\n}\n\nmodule Content = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <div\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-content\")}\n      className={cn(\n        \"gap-0.5 group/field-content flex flex-1 flex-col leading-snug\",\n        props.className,\n      )}\n    />\n}\n\nmodule Label = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <Label\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-label\")}\n      className={cn(\n        \"has-data-checked:bg-primary/5 has-data-checked:border-primary/30 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10 gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 *:data-[slot=field]:p-2.5 group/field-label peer/field-label flex w-fit has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col\",\n        props.className,\n      )}\n    />\n}\n\nmodule Title = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <div\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-label\")}\n      className={cn(\n        \"gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50 flex w-fit items-center\",\n        props.className,\n      )}\n    />\n}\n\nmodule Description = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <p\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-description\")}\n      className={cn(\n        \"text-muted-foreground text-left text-sm [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-data-horizontal/field:text-balance last:mt-0 nth-last-2:-mt-1 [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4\",\n        props.className,\n      )}\n    />\n}\n\nmodule Separator = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) => {\n    let children = props.children\n    let hasContent = children->Option.isSome\n    <div\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"field-separator\")}\n      dataContent={hasContent}\n      className={cn(\n        \"-my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2 relative\",\n        props.className,\n      )}\n    >\n      <Separator className=\"absolute inset-0 top-1/2\" />\n      {switch children {\n      | Some(value) =>\n        <span\n          className=\"text-muted-foreground px-2 bg-background relative mx-auto block w-fit\"\n          dataSlot=\"field-separator-content\"\n        >\n          {value}\n        </span>\n      | None => React.null\n      }}\n    </div>\n  }\n}\n\nmodule Error = {\n  type t = {\n    message: string,\n  }\n  type props = {\n    ...BaseUi.Types.DomProps.t,\n    errors?: array<t>,\n  }\n\n  let toBaseUiProps: props => BaseUi.Types.DomProps.t = %raw(`({errors, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let role = props.role->Option.getOr(\"alert\")\n    let children = props.children\n    let errors = props.errors\n    let content = React.useMemo(() => {\n      children->Option.getOr(\n        switch errors {\n        | None | Some([]) => React.null\n        | Some(errors) =>\n          let uniqueErrors =\n            Map.fromArray(errors->Array.map(error => (error.message, error)))\n            ->Map.values\n            ->Iterator.toArray\n          switch uniqueErrors {\n          | [{message}] => message->React.string\n          | errors =>\n            <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n              {errors\n              ->Array.mapWithIndex(({message}, index) =>\n                <li key={index->Int.toString}> {message->React.string} </li>\n              )\n              ->React.array}\n            </ul>\n          }\n        },\n      )\n    }, (children, errors))\n    <div\n      {...props->toBaseUiProps}\n      role\n      dataSlot={props.dataSlot->Option.getOr(\"field-error\")}\n      className={cn(\"text-destructive text-sm font-normal\", props.className)}\n    >\n      {content}\n    </div>\n  }\n}\n",
      "type": "registry:file",
      "target": "@ui/Field.res"
    }
  ],
  "type": "registry:ui"
}