{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"separator","type":"registry:ui","title":"Separator","description":"A thin line between groups – across or upright between tools, an optional word in its middle like \\\"or\\\" or \\\"Earlier\\\", decorative or a real separator for screen readers","dependencies":[],"files":[{"path":"registry/separator/separator.tsx","type":"registry:ui","content":"\"use client\";\n\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\n/*\n * Separator – a single self-contained file.\n * A 1px line between groups: across a card or a list, or upright between tools in a bar. It can carry a short\n * label in its middle – \"or\" between two ways in, \"Earlier\" above older rows.\n * The styles are injected below, so no extra files are needed.\n */\n\nexport type SeparatorProps = Omit<ComponentPropsWithRef<\"div\">, \"children\"> & {\n  /** horizontal: a line across, as wide as its container · vertical: an upright line, 18px high in a row */\n  orientation?: \"horizontal\" | \"vertical\";\n  /**\n   * true (the default): only a visual line, hidden from screen readers · false: a real separator (role=\"separator\")\n   * that splits content into sections screen readers announce\n   */\n  decorative?: boolean;\n  /** A short word in the middle of a horizontal line – \"or\", \"Earlier\", \"Today\" */\n  label?: ReactNode;\n};\n\nexport function Separator({ orientation = \"horizontal\", decorative = true, label, className, ...rest }: SeparatorProps) {\n  const vertical = orientation === \"vertical\";\n  const hasLabel = !vertical && label != null && label !== false && label !== \"\";\n  // A labelled separator names itself after its label, when the label is text\n  const name = hasLabel && (typeof label === \"string\" || typeof label === \"number\") ? String(label) : undefined;\n  const a11y = decorative\n    ? // A decorative line with a label: the label stays readable as plain text, only the lines are hidden\n      hasLabel\n      ? {}\n      : { role: \"none\" as const }\n    : {\n        role: \"separator\" as const,\n        \"aria-orientation\": vertical ? (\"vertical\" as const) : undefined,\n        \"aria-label\": name,\n      };\n\n  return (\n    <>\n      {/* React 19 hoists this into <head> once, no matter how many separators render */}\n      <style href=\"ui-separator\" precedence=\"default\">\n        {css}\n      </style>\n      <div\n        className={[\"ui-sep\", className].filter(Boolean).join(\" \")}\n        data-orientation={vertical ? \"vertical\" : \"horizontal\"}\n        data-label={hasLabel ? \"\" : undefined}\n        {...a11y}\n        {...rest}\n      >\n        {hasLabel && (\n          <>\n            <span className=\"ui-sep__line\" aria-hidden=\"true\" />\n            <span className=\"ui-sep__label\">{label}</span>\n            <span className=\"ui-sep__line\" aria-hidden=\"true\" />\n          </>\n        )}\n      </div>\n    </>\n  );\n}\n\n/* ---------- Styles ---------- */\n\nconst css = /* css */ `\n/* Colors as variables – override them on .ui-sep (see Theming in the docs) */\n.ui-sep {\n  --ui-sep-line: var(--aui-border, #ececec);\n  --ui-sep-text: var(--aui-muted, #8f8f8f);\n  --ui-sep-weight: 1px;\n  flex: none;\n  box-sizing: border-box;\n}\n\n/* A line across: a border, so it stays one crisp device pixel on any screen */\n.ui-sep[data-orientation=\"horizontal\"]:not([data-label]) {\n  width: 100%;\n  height: 0;\n  border-top: var(--ui-sep-weight) solid var(--ui-sep-line);\n}\n\n/* Upright between tools: 18px high, centred in its row – set height to change it */\n.ui-sep[data-orientation=\"vertical\"] {\n  display: inline-block;\n  align-self: center;\n  width: 0;\n  vertical-align: middle;\n  height: 18px;\n  border-inline-start: var(--ui-sep-weight) solid var(--ui-sep-line);\n}\n\n/* With a label: line · word · line, the word in the middle */\n.ui-sep[data-label] {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  width: 100%;\n  min-width: 0;\n  font-family: var(--aui-font, \"Inter\", \"InterVariable\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif);\n  font-size: 12.5px;\n  line-height: 18px;\n  color: var(--ui-sep-text);\n  -webkit-font-smoothing: antialiased;\n}\n.ui-sep__line {\n  flex: 1 1 0;\n  min-width: 12px;\n  height: 0;\n  border-top: var(--ui-sep-weight) solid var(--ui-sep-line);\n}\n/* A long label wraps inside the middle rather than pushing the lines out */\n.ui-sep__label {\n  flex: 0 1 auto;\n  min-width: 0;\n  max-width: 80%;\n  text-align: center;\n  overflow-wrap: anywhere;\n}\n\n/* Windows high contrast: the line keeps a system color */\n@media (forced-colors: active) {\n  .ui-sep { --ui-sep-line: CanvasText; }\n}\n\n/* Dark mode: follows a .dark class or data-theme=\"dark\" on any ancestor, e.g. <html> */\n:where(.dark, [data-theme=\"dark\"]) .ui-sep {\n  --ui-sep-line: var(--aui-border, #2a2a2e);\n  --ui-sep-text: var(--aui-muted, #8b8b92);\n}\n`;\n"}]}