{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "separator",
  "type": "registry:ui",
  "title": "Separator",
  "description": "Static Separator and Divider primitive with semantic or decorative modes, horizontal and vertical orientation, token-backed tone, thickness, spacing, and asChild composition.",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://components.dethink.co.uk/r/dethink-base.json"
  ],
  "files": [
    {
      "path": "packages/components/src/components/separator/separator.tsx",
      "type": "registry:file",
      "target": "~/components/dethink/components/separator/separator.tsx",
      "content": "import {\n  Children,\n  cloneElement,\n  createElement,\n  forwardRef,\n  isValidElement,\n  version as reactVersion,\n  type ForwardedRef,\n  type HTMLAttributes,\n  type ReactElement,\n  type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type SeparatorElement = \"hr\" | \"div\" | \"span\";\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\nexport type SeparatorThickness = \"1\" | \"2\";\nexport type SeparatorTone = \"default\" | \"muted\" | \"strong\";\nexport type SeparatorSpacing = \"none\" | \"1\" | \"2\" | \"3\" | \"4\" | \"6\" | \"8\";\n\ntype SeparatorValueAttributes = {\n  \"aria-valuemax\"?: never;\n  \"aria-valuemin\"?: never;\n  \"aria-valuenow\"?: never;\n  \"aria-valuetext\"?: never;\n};\n\ntype SeparatorBaseProps = SeparatorValueAttributes & {\n  as?: SeparatorElement;\n  asChild?: boolean;\n  decorative?: boolean;\n  orientation?: SeparatorOrientation;\n  spacing?: SeparatorSpacing;\n  thickness?: SeparatorThickness;\n  tone?: SeparatorTone;\n};\n\ntype SeparatorReservedAttribute =\n  | \"aria-hidden\"\n  | \"aria-orientation\"\n  | \"aria-valuemax\"\n  | \"aria-valuemin\"\n  | \"aria-valuenow\"\n  | \"aria-valuetext\"\n  | \"role\"\n  | \"tabIndex\";\n\ntype SeparatorNativeAttributes = Omit<\n  HTMLAttributes<HTMLElement>,\n  SeparatorReservedAttribute | \"children\"\n>;\n\ntype NativeSeparatorProps = SeparatorNativeAttributes &\n  SeparatorBaseProps & {\n    asChild?: false;\n    children?: never;\n  };\n\ntype ChildSeparatorProps = SeparatorNativeAttributes &\n  SeparatorBaseProps & {\n    asChild: true;\n    children: ReactElement<SeparatorSlotProps>;\n  };\n\nexport type SeparatorProps = NativeSeparatorProps | ChildSeparatorProps;\nexport type DividerProps = SeparatorProps;\n\ntype SeparatorSlotProps = Record<string, unknown> & {\n  children?: never;\n  className?: string;\n  ref?: Ref<HTMLElement>;\n};\n\ntype SeparatorElementWithRef = ReactElement<SeparatorSlotProps> & {\n  ref?: Ref<HTMLElement>;\n};\n\ntype EventHandler = (...args: unknown[]) => void;\n\nconst separatorBaseClasses = \"block shrink-0 border-0 bg-border\";\n\nconst separatorOrientationClasses: Record<SeparatorOrientation, string> = {\n  horizontal: \"w-full\",\n  vertical: \"h-full min-h-4 self-stretch\",\n};\n\nconst separatorThicknessClasses: Record<\n  SeparatorOrientation,\n  Record<SeparatorThickness, string>\n> = {\n  horizontal: {\n    1: \"h-px\",\n    2: \"h-0.5\",\n  },\n  vertical: {\n    1: \"w-px\",\n    2: \"w-0.5\",\n  },\n};\n\nconst separatorToneClasses: Record<SeparatorTone, string> = {\n  default: \"bg-border\",\n  muted: \"bg-muted-foreground/25\",\n  strong: \"bg-foreground/40\",\n};\n\nconst separatorSpacingClasses: Record<\n  SeparatorOrientation,\n  Record<SeparatorSpacing, string | undefined>\n> = {\n  horizontal: {\n    none: undefined,\n    1: \"my-[var(--dt-space-1)]\",\n    2: \"my-[var(--dt-space-2)]\",\n    3: \"my-[var(--dt-space-3)]\",\n    4: \"my-[var(--dt-space-4)]\",\n    6: \"my-[var(--dt-space-6)]\",\n    8: \"my-[var(--dt-space-8)]\",\n  },\n  vertical: {\n    none: undefined,\n    1: \"mx-[var(--dt-space-1)]\",\n    2: \"mx-[var(--dt-space-2)]\",\n    3: \"mx-[var(--dt-space-3)]\",\n    4: \"mx-[var(--dt-space-4)]\",\n    6: \"mx-[var(--dt-space-6)]\",\n    8: \"mx-[var(--dt-space-8)]\",\n  },\n};\n\nconst strippedSeparatorReservedAttributes: Record<\n  SeparatorReservedAttribute,\n  undefined\n> = {\n  \"aria-hidden\": undefined,\n  \"aria-orientation\": undefined,\n  \"aria-valuemax\": undefined,\n  \"aria-valuemin\": undefined,\n  \"aria-valuenow\": undefined,\n  \"aria-valuetext\": undefined,\n  role: undefined,\n  tabIndex: undefined,\n};\n\nexport function separatorClassNames({\n  className,\n  orientation = \"horizontal\",\n  spacing = \"none\",\n  thickness = \"1\",\n  tone = \"default\",\n}: Pick<\n  SeparatorProps,\n  \"className\" | \"orientation\" | \"spacing\" | \"thickness\" | \"tone\"\n> = {}) {\n  return cn(\n    separatorBaseClasses,\n    separatorOrientationClasses[orientation],\n    separatorThicknessClasses[orientation][thickness],\n    separatorToneClasses[tone],\n    separatorSpacingClasses[orientation][spacing],\n    className,\n  );\n}\n\nfunction setRef<T>(ref: Ref<T> | undefined, node: T | null) {\n  if (typeof ref === \"function\") {\n    ref(node);\n    return;\n  }\n\n  if (ref) {\n    ref.current = node;\n  }\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      setRef(ref, node);\n    }\n  };\n}\n\nfunction getChildRef(child: ReactElement<SeparatorSlotProps>) {\n  if (\"ref\" in child.props) {\n    return child.props.ref;\n  }\n\n  return reactVersion.startsWith(\"18.\")\n    ? (child as SeparatorElementWithRef).ref\n    : undefined;\n}\n\nfunction isEventHandler(key: string, value: unknown): value is EventHandler {\n  return /^on[A-Z]/.test(key) && typeof value === \"function\";\n}\n\nfunction isDefaultPreventedEvent(\n  event: unknown,\n): event is { defaultPrevented: boolean } {\n  return (\n    typeof event === \"object\" &&\n    event !== null &&\n    \"defaultPrevented\" in event &&\n    event.defaultPrevented === true\n  );\n}\n\nfunction composeEventHandlers(\n  componentHandler: EventHandler,\n  childHandler: EventHandler,\n): EventHandler {\n  return (...args) => {\n    componentHandler(...args);\n\n    if (!isDefaultPreventedEvent(args[0])) {\n      childHandler(...args);\n    }\n  };\n}\n\nfunction composeSlotProps(\n  componentProps: Record<string, unknown>,\n  childProps: SeparatorSlotProps,\n) {\n  const composedProps: SeparatorSlotProps = {\n    ...componentProps,\n    ...childProps,\n  };\n\n  for (const [key, componentValue] of Object.entries(componentProps)) {\n    const childValue = childProps[key];\n\n    if (\n      isEventHandler(key, componentValue) &&\n      isEventHandler(key, childValue)\n    ) {\n      composedProps[key] = composeEventHandlers(componentValue, childValue);\n    }\n  }\n\n  return composedProps;\n}\n\nfunction stripSeparatorReservedAttributes<T extends object>(\n  props: T,\n): Omit<T, SeparatorReservedAttribute> {\n  const {\n    \"aria-hidden\": _ariaHidden,\n    \"aria-orientation\": _ariaOrientation,\n    \"aria-valuemax\": _ariaValueMax,\n    \"aria-valuemin\": _ariaValueMin,\n    \"aria-valuenow\": _ariaValueNow,\n    \"aria-valuetext\": _ariaValueText,\n    role: _role,\n    tabIndex: _tabIndex,\n    ...safeProps\n  } = props as Record<string, unknown>;\n\n  return safeProps as Omit<T, SeparatorReservedAttribute>;\n}\n\nfunction getSeparatorDataAttributes({\n  as,\n  asChild,\n  decorative,\n  orientation,\n  spacing,\n  thickness,\n  tone,\n}: Pick<\n  SeparatorProps,\n  | \"as\"\n  | \"asChild\"\n  | \"decorative\"\n  | \"orientation\"\n  | \"spacing\"\n  | \"thickness\"\n  | \"tone\"\n>) {\n  return {\n    \"data-slot\": \"separator\",\n    \"data-as-child\": asChild ? \"true\" : undefined,\n    \"data-element\": asChild ? undefined : as,\n    \"data-orientation\": orientation,\n    \"data-decorative\": decorative ? \"true\" : \"false\",\n    \"data-thickness\": thickness,\n    \"data-tone\": tone,\n    \"data-spacing\": spacing,\n  };\n}\n\nfunction getSeparatorAccessibilityAttributes({\n  as,\n  asChild,\n  decorative,\n  orientation,\n}: Pick<SeparatorProps, \"as\" | \"asChild\" | \"decorative\" | \"orientation\">) {\n  if (decorative) {\n    return {\n      \"aria-hidden\": true,\n      \"aria-orientation\": undefined,\n      role: undefined,\n    };\n  }\n\n  return {\n    \"aria-hidden\": undefined,\n    \"aria-orientation\": orientation,\n    role: asChild || as !== \"hr\" ? \"separator\" : undefined,\n  };\n}\n\nexport const Separator = forwardRef<HTMLElement, SeparatorProps>(\n  (\n    {\n      as = \"hr\",\n      asChild = false,\n      children,\n      className,\n      decorative = false,\n      orientation = \"horizontal\",\n      spacing = \"none\",\n      thickness = \"1\",\n      tone = \"default\",\n      ...props\n    },\n    ref,\n  ) => {\n    const safeProps = stripSeparatorReservedAttributes(props);\n    const classes = separatorClassNames({\n      className,\n      orientation,\n      spacing,\n      thickness,\n      tone,\n    });\n    const dataAttributes = getSeparatorDataAttributes({\n      as,\n      asChild,\n      decorative,\n      orientation,\n      spacing,\n      thickness,\n      tone,\n    });\n    const accessibilityAttributes = getSeparatorAccessibilityAttributes({\n      as,\n      asChild,\n      decorative,\n      orientation,\n    });\n\n    if (asChild) {\n      const child = Children.only(children);\n\n      if (!isValidElement<SeparatorSlotProps>(child)) {\n        throw new Error(\n          \"Separator with asChild expects a single React element child.\",\n        );\n      }\n\n      const childRef = getChildRef(child);\n      const safeChildProps = stripSeparatorReservedAttributes(child.props);\n      const composedProps = composeSlotProps(safeProps, safeChildProps);\n\n      return cloneElement(child, {\n        ...composedProps,\n        ...strippedSeparatorReservedAttributes,\n        ...dataAttributes,\n        ...accessibilityAttributes,\n        ref: composeRefs(ref as Ref<HTMLElement>, childRef),\n        className: cn(classes, child.props.className),\n      });\n    }\n\n    return createElement(as, {\n      ...safeProps,\n      ...dataAttributes,\n      ...accessibilityAttributes,\n      ref: ref as ForwardedRef<HTMLElement>,\n      className: classes,\n    });\n  },\n);\n\nSeparator.displayName = \"Separator\";\n\nexport const Divider = forwardRef<HTMLElement, DividerProps>((props, ref) => (\n  <Separator ref={ref} {...props} />\n));\n\nDivider.displayName = \"Divider\";\n"
    },
    {
      "path": "packages/components/src/components/separator/index.ts",
      "type": "registry:file",
      "target": "~/components/dethink/components/separator/index.ts",
      "content": "export {\n  Divider,\n  Separator,\n  separatorClassNames,\n  type DividerProps,\n  type SeparatorElement,\n  type SeparatorOrientation,\n  type SeparatorProps,\n  type SeparatorSpacing,\n  type SeparatorThickness,\n  type SeparatorTone,\n} from \"./separator\";\n"
    },
    {
      "path": "packages/components/src/utils/cn.ts",
      "type": "registry:file",
      "target": "~/components/dethink/utils/cn.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
    }
  ]
}
