{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "Attachment",
  "dependencies": [
    "@base-ui/react",
    "cn",
    "rescript-base-ui"
  ],
  "registryDependencies": [
    "@rescript-shadcn/Button"
  ],
  "files": [
    {
      "path": "registry/base/ui/Attachment.res",
      "content": "@@jsxConfig({version: 4, mode: \"automatic\", module_: \"BaseUi.BaseUiJsxDOM\"})\n\n@module(\"cn\")\nexternal cn: (string, option<string>) => string = \"cn\"\n\nmodule State = {\n  @unboxed\n  type t =\n    | @as(\"idle\") Idle\n    | @as(\"uploading\") Uploading\n    | @as(\"processing\") Processing\n    | @as(\"error\") Error\n    | @as(\"done\") Done\n}\n\nmodule Size = {\n  @unboxed\n  type t =\n    | @as(\"default\") Default\n    | @as(\"sm\") Sm\n    | @as(\"xs\") Xs\n}\n\nmodule Orientation = {\n  @unboxed\n  type t =\n    | @as(\"horizontal\") Horizontal\n    | @as(\"vertical\") Vertical\n}\n\nmodule MediaVariant = {\n  @unboxed\n  type t =\n    | @as(\"icon\") Icon\n    | @as(\"image\") Image\n}\n\nlet sizeClass = (~size: Size.t) =>\n  switch size {\n  | Default => \"gap-2 has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2 text-sm\"\n  | Sm => \"gap-2.5 has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5 text-xs\"\n  | Xs => \"gap-1.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs rounded-lg\"\n  }\n\nlet orientationClass = (~orientation: Orientation.t) =>\n  switch orientation {\n  | Horizontal => \"min-w-40 items-center\"\n  | Vertical => \"w-24 has-data-[slot=attachment-content]:w-30 flex-col\"\n  }\n\ntype props = {\n  ...BaseUi.Types.BaseDomWithoutOrientationProps.t,\n  ...BaseUi.Types.ExtraDomProps.t,\n  children?: React.element,\n  state?: State.t,\n  size?: Size.t,\n  orientation?: Orientation.t,\n}\n\nlet toBaseUiProps: props => BaseUi.Types.DomProps.t = %raw(`({state, size, orientation, ...props}) => props`)\n\n@react.componentWithProps(props)\nlet make = (props: props) => {\n  let state = props.state->Option.getOr(State.Done)\n  let size = props.size->Option.getOr(Size.Default)\n  let orientation = props.orientation->Option.getOr(Orientation.Horizontal)\n  <div\n    {...props->toBaseUiProps}\n    dataSlot={props.dataSlot->Option.getOr(\"attachment\")}\n    dataState={props.dataState->Option.getOr((state :> string))}\n    dataSize={props.dataSize->Option.getOr((size :> string))}\n    dataOrientation={props.dataOrientation->Option.getOr((orientation :> string))}\n    className={cn(\n      `rounded-xl w-fit focus-within:ring-1 focus-within:ring-ring/50 group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed ${sizeClass(\n          ~size,\n        )} ${orientationClass(~orientation)}`,\n      props.className,\n    )}\n  />\n}\n\nmodule Media = {\n  let variantClass = (~variant: MediaVariant.t) =>\n    switch variant {\n    | Icon => \"\"\n    | Image => \"opacity-60 group-data-[state=idle]/attachment:opacity-100 group-data-[state=done]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover\"\n    }\n\n  type props = {\n    ...BaseUi.Types.DomProps.t,\n    variant?: MediaVariant.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(MediaVariant.Icon)\n    <div\n      {...props->toBaseUiProps}\n      dataSlot={props.dataSlot->Option.getOr(\"attachment-media\")}\n      dataVariant={props.dataVariant->Option.getOr((variant :> string))}\n      className={cn(\n        `bg-muted text-foreground w-10 rounded-lg group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md [&_svg:not([class*='size-'])]:size-4 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5 group-data-[orientation=vertical]/attachment:w-full group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none ${variantClass(\n            ~variant,\n          )}`,\n        props.className,\n      )}\n    />\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(\"attachment-content\")}\n      className={cn(\n        \"leading-tight group-data-[orientation=vertical]/attachment:px-1 max-w-full min-w-0 flex-1\",\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    <span\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"attachment-title\")}\n      className={cn(\n        \"font-medium block max-w-full min-w-0 truncate group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer\",\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    <span\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"attachment-description\")}\n      className={cn(\n        \"mt-0.5 text-xs block max-w-full min-w-0 truncate text-muted-foreground group-data-[state=error]/attachment:text-destructive/80\",\n        props.className,\n      )}\n    />\n}\n\nmodule Actions = {\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(\"attachment-actions\")}\n      className={cn(\n        \"group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 relative z-20 group-data-[orientation=vertical]/attachment:gap-1 flex shrink-0 items-center\",\n        props.className,\n      )}\n    />\n}\n\nmodule Action = {\n  @react.componentWithProps(Button.props)\n  let make = (props: Button.props) =>\n    <Button\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"attachment-action\")}\n      variant={props.variant->Option.getOr(Ghost)}\n      size={props.size->Option.getOr(IconXs)}\n      className={cn(\"\", props.className)}\n    />\n}\n\nmodule Trigger = {\n  type props = {\n    ...BaseUi.Types.BaseUIComponentWithoutTypeProps.t,\n    @as(\"type\") type_?: BaseUi.Types.ButtonType.t,\n  }\n  type state = {slot: string}\n  let toDomProps: props => BaseUi.Types.DomProps.t = %raw(`({className, render, type, ...props}) => props`)\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let type_ = switch props.render {\n    | Some(_) => props.type_\n    | None => Some(props.type_->Option.getOr(Button))\n    }\n    BaseUi.Render.use({\n      defaultTagName: \"button\",\n      props: BaseUi.Render.mergeProps(\n        {\n          type_: ?(type_->Option.map(value => (value :> string))),\n          className: cn(\n            \"absolute inset-0 z-10 outline-none absolute inset-0 z-10 outline-none\",\n            props.className,\n          ),\n        },\n        toDomProps(props),\n      ),\n      render: ?props.render,\n      state: {slot: \"attachment-trigger\"},\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(\"attachment-group\")}\n      className={cn(\n        \"gap-3 scroll-px-1 py-1 flex min-w-0 scroll-fade-x snap-x snap-mandatory scrollbar-none overflow-x-auto overscroll-x-contain *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start\",\n        props.className,\n      )}\n    />\n}\n",
      "type": "registry:file",
      "target": "@ui/Attachment.res"
    }
  ],
  "type": "registry:ui"
}