{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "if-function",
  "title": "if() Conditional Value",
  "description": "Ridiculously typed editor for the CSS if() conditional value function. Validates the wrapper, splits branches, checks each condition kind (media/supports/style/else), and enforces else-last. Ships a popover branch-builder UI with a live preview.",
  "dependencies": [],
  "registryDependencies": [
    "ridiculous-type-kit",
    "button",
    "popover",
    "input"
  ],
  "files": [
    {
      "path": "src/components/ui/if-function/index.ts",
      "content": "export type {\n  AddBranchButtonProps,\n  BranchRowProps,\n  ConditionKindSelectProps,\n  IfFunctionPanelProps,\n  IfFunctionProps,\n  IfPreviewProps,\n} from \"./if-function\"\nexport {\n  AddBranchButton,\n  BranchRow,\n  ConditionKindSelect,\n  IfFunction,\n  IfFunctionPanel,\n  IfPreview,\n} from \"./if-function\"\nexport {\n  branchCount,\n  branchToCss,\n  defaultBranch,\n  formatIf,\n  parseIf,\n} from \"./if-function.helpers\"\nexport type {\n  BranchCountOf,\n  BranchesOf,\n  ConditionKind,\n  ConditionKindsOf,\n  ConditionString,\n  IfBranch,\n  IfFunctionLiteral,\n  IfFunctionState,\n  IfFunctionString,\n  SplitBySemicolon,\n} from \"./if-function.types\"\nexport { cssIf } from \"./if-function.types\"\n",
      "type": "registry:ui",
      "target": "components/ui/if-function/index.ts"
    },
    {
      "path": "src/components/ui/if-function/if-function.tsx",
      "content": "\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ui/popover\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  branchCount,\n  defaultBranch,\n  formatIf,\n  parseIf,\n} from \"./if-function.helpers\"\nimport type {\n  ConditionKind,\n  IfBranch,\n  IfFunctionString,\n} from \"./if-function.types\"\n\n// ---------------------------------------------------------------------------\n// Shared constants\n// ---------------------------------------------------------------------------\n\nconst ALL_KINDS: readonly ConditionKind[] = [\n  \"media\",\n  \"supports\",\n  \"style\",\n  \"else\",\n]\n\nconst CONDITION_PLACEHOLDER: Record<ConditionKind, string> = {\n  media: \"width >= 600px\",\n  supports: \"display: grid\",\n  style: \"--x: 1\",\n  else: \"\",\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface IfFunctionPanelProps {\n  value: IfFunctionString | (string & {})\n  onChange: (value: IfFunctionString) => void\n  className?: string\n  \"aria-label\"?: string\n}\n\nexport type IfFunctionProps = IfFunctionPanelProps\n\n// ---------------------------------------------------------------------------\n// IfFunction — popover-wrapped\n// ---------------------------------------------------------------------------\n\nexport function IfFunction(props: IfFunctionProps) {\n  const {\n    value,\n    className,\n    \"aria-label\": ariaLabel = \"Edit a CSS if() conditional value\",\n  } = props\n  const count = branchCount(String(value))\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          className={cn(\"h-9 gap-2 px-3 font-mono\", className)}\n          aria-label={ariaLabel}\n        >\n          <span className=\"text-[10px] text-muted-foreground uppercase\">\n            if\n          </span>\n          <span className=\"text-[10px] text-muted-foreground\">\n            {count} {count === 1 ? \"branch\" : \"branches\"}\n          </span>\n          <span className=\"max-w-[200px] truncate text-xs\">{value}</span>\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-auto p-0\" align=\"start\">\n        <IfFunctionPanel {...props} />\n      </PopoverContent>\n    </Popover>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// IfFunctionPanel — inline\n// ---------------------------------------------------------------------------\n\nexport function IfFunctionPanel({\n  value,\n  onChange,\n  className,\n  \"aria-label\": ariaLabel = \"CSS if() conditional value editor\",\n}: IfFunctionPanelProps) {\n  const [branches, setBranches] = useState<IfBranch[]>(\n    () => parseIf(String(value)) ?? [],\n  )\n  const lastEmittedRef = useRef<string | null>(null)\n\n  // Resync from external value (skip our own emits).\n  useEffect(() => {\n    if (value === lastEmittedRef.current) return\n    const parsed = parseIf(String(value))\n    if (parsed !== null) setBranches(parsed)\n  }, [value])\n\n  const commit = (next: IfBranch[]) => {\n    setBranches(next)\n    const str = formatIf(next)\n    lastEmittedRef.current = str\n    onChange(str as IfFunctionString)\n  }\n\n  const lastIndex = branches.length - 1\n\n  const updateAt = (index: number, branch: IfBranch) => {\n    commit(branches.map((it, i) => (i === index ? branch : it)))\n  }\n  const removeAt = (index: number) => {\n    commit(branches.filter((_, i) => i !== index))\n  }\n  const add = () => {\n    // `else` is only legal as the FINAL branch, so insert a new media branch\n    // *before* a trailing else (keeping else last); otherwise append. Appending\n    // after an else would emit a value parseIf rejects → silent data loss on\n    // remount.\n    const insertAt =\n      branches.length > 0 && branches[branches.length - 1].kind === \"else\"\n        ? branches.length - 1\n        : branches.length\n    const next = [...branches]\n    next.splice(insertAt, 0, defaultBranch(\"media\"))\n    commit(next)\n  }\n\n  return (\n    <fieldset\n      className={cn(\n        \"m-0 w-[560px] space-y-3 border-0 bg-background p-3\",\n        className,\n      )}\n      aria-label={ariaLabel}\n    >\n      <div className=\"space-y-2\">\n        {branches.map((branch, i) => (\n          <BranchRow\n            // biome-ignore lint/suspicious/noArrayIndexKey: rows are positional and reorderable only by add/remove\n            key={`branch-${i}`}\n            index={i}\n            branch={branch}\n            // `else` is only offered on the final row.\n            allowElse={i === lastIndex}\n            onChange={(next) => updateAt(i, next)}\n            onRemove={() => removeAt(i)}\n          />\n        ))}\n      </div>\n      <AddBranchButton onAdd={add} />\n      <LiveString value={formatIf(branches)} />\n      <IfPreview value={formatIf(branches)} />\n    </fieldset>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// BranchRow (public)\n// ---------------------------------------------------------------------------\n\nexport interface BranchRowProps {\n  branch: IfBranch\n  onChange: (branch: IfBranch) => void\n  onRemove: () => void\n  /** Whether the `else` kind is selectable (final row only). */\n  allowElse?: boolean\n  /** Positional index — used only for stable control labels. */\n  index?: number\n  className?: string\n}\n\nexport function BranchRow({\n  branch,\n  onChange,\n  onRemove,\n  allowElse = false,\n  index,\n  className,\n}: BranchRowProps) {\n  const n = index === undefined ? \"\" : ` ${index + 1}`\n  const isElse = branch.kind === \"else\"\n\n  const setKind = (kind: ConditionKind) => {\n    // Switching to/from else clears/keeps the condition appropriately.\n    onChange({\n      ...branch,\n      kind,\n      condition: kind === \"else\" ? \"\" : branch.condition,\n    })\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex flex-wrap items-center gap-1.5 rounded-md border p-1.5\",\n        className,\n      )}\n    >\n      <ConditionKindSelect\n        label={`condition-kind${n}`}\n        value={branch.kind}\n        allowElse={allowElse || isElse}\n        onChange={setKind}\n      />\n      {isElse ? (\n        <span className=\"px-1 font-mono text-muted-foreground text-xs\">\n          (always)\n        </span>\n      ) : (\n        <Input\n          aria-label={`condition${n}`}\n          value={branch.condition}\n          spellCheck={false}\n          autoComplete=\"off\"\n          placeholder={CONDITION_PLACEHOLDER[branch.kind]}\n          onChange={(e) => onChange({ ...branch, condition: e.target.value })}\n          className=\"h-8 w-[180px] font-mono text-xs\"\n        />\n      )}\n      <span className=\"font-mono text-muted-foreground text-xs\">:</span>\n      <Input\n        aria-label={`value${n}`}\n        value={branch.value}\n        spellCheck={false}\n        autoComplete=\"off\"\n        placeholder=\"value\"\n        onChange={(e) => onChange({ ...branch, value: e.target.value })}\n        className=\"h-8 w-[120px] font-mono text-xs\"\n      />\n      <button\n        type=\"button\"\n        onClick={onRemove}\n        aria-label={`Remove branch${n}`}\n        className=\"ml-auto rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive\"\n      >\n        <span aria-hidden=\"true\">×</span>\n      </button>\n    </div>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// ConditionKindSelect (public) — a labelled native select\n// ---------------------------------------------------------------------------\n\nexport interface ConditionKindSelectProps {\n  label: string\n  value: ConditionKind\n  onChange: (value: ConditionKind) => void\n  /** Whether to offer the `else` option (final row only). */\n  allowElse?: boolean\n  className?: string\n}\n\nexport function ConditionKindSelect({\n  label,\n  value,\n  onChange,\n  allowElse = false,\n  className,\n}: ConditionKindSelectProps) {\n  const options = ALL_KINDS.filter((k) => k !== \"else\" || allowElse)\n  return (\n    <select\n      aria-label={label}\n      value={value}\n      onChange={(e) => onChange(e.target.value as ConditionKind)}\n      className={cn(\n        \"h-8 rounded-md border border-input bg-background px-1 font-mono text-xs\",\n        className,\n      )}\n    >\n      {options.map((k) => (\n        <option key={k} value={k}>\n          {k}\n        </option>\n      ))}\n    </select>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// AddBranchButton (public)\n// ---------------------------------------------------------------------------\n\nexport interface AddBranchButtonProps {\n  onAdd: () => void\n  className?: string\n}\n\nexport function AddBranchButton({ onAdd, className }: AddBranchButtonProps) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onAdd}\n      aria-label=\"Add a branch\"\n      className={cn(\n        \"h-9 w-full rounded-md border border-dashed bg-background px-2 font-mono text-muted-foreground text-xs hover:text-foreground\",\n        className,\n      )}\n    >\n      + add branch\n    </button>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// LiveString (internal)\n// ---------------------------------------------------------------------------\n\nfunction LiveString({ value }: { value: string }) {\n  return (\n    <code className=\"block overflow-x-auto rounded bg-muted/50 px-2 py-1.5 font-mono text-foreground text-xs\">\n      {value}\n    </code>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// IfPreview (public) — applies the if() string to a sample element's color\n// ---------------------------------------------------------------------------\n\nexport interface IfPreviewProps {\n  value: string\n  className?: string\n}\n\nexport function IfPreview({ value, className }: IfPreviewProps) {\n  return (\n    <div className={cn(\"space-y-2 rounded-lg border p-3\", className)}>\n      <div className=\"flex items-center justify-between\">\n        <div className=\"text-muted-foreground text-xs\">preview</div>\n        <span className=\"font-mono text-[10px] text-amber-500\">\n          cutting-edge browser support\n        </span>\n      </div>\n      <div className=\"flex h-16 items-center justify-center overflow-hidden rounded-md bg-[radial-gradient(circle_at_30%_40%,#1e293b,#0f172a)] px-4\">\n        {/* `if()` resolves in supporting browsers; elsewhere the declaration\n            is ignored and the fallback color shows. No injection surface —\n            the value is set via the style object, not innerHTML. */}\n        <span\n          data-preview-target\n          className=\"font-mono font-semibold text-lg text-muted-foreground\"\n          style={{ color: value }}\n        >\n          if() value\n        </span>\n      </div>\n      <p className=\"text-[10px] text-muted-foreground/70 leading-relaxed\">\n        The CSS <code className=\"font-mono\">if()</code> function shipped in\n        2025; support is still rolling out. Non-supporting browsers ignore the\n        declaration and fall back.\n      </p>\n    </div>\n  )\n}\n",
      "type": "registry:ui",
      "target": "components/ui/if-function/if-function.tsx"
    },
    {
      "path": "src/components/ui/if-function/if-function.types.ts",
      "content": "// =====================================================================\n// if-function.types.ts\n//\n// The \"ridiculous\" tier for the CSS `if()` conditional value function\n// (shipped 2025). Grammar:\n//\n//   if( <branch> [ ; <branch> ]* )\n//   <branch>    = <condition> : <value>\n//   <condition> = media(<media-query>) | supports(<supports-condition>)\n//               | style(<style-query>) | else     // else: LAST branch only\n//\n// `IfFunctionLiteral<S>` resolves to `S` when:\n//   1. `S` is an `if( … )` wrapper (name === \"if\", via the kit's ParseFunction),\n//   2. the body splits on TOP-LEVEL semicolons into >= 1 branch,\n//   3. each branch splits on its FIRST TOP-LEVEL colon into condition/value,\n//   4. the condition is media()/supports()/style() (body non-empty + parens\n//      balanced — LENIENT, per roadmap §7) OR the literal `else` (last only),\n//   5. the value is non-empty.\n// Otherwise → never.\n//\n// The kit ships no semicolon splitter, so SplitBySemicolon is implemented\n// locally by mirroring the kit's paren-aware char-walk (the kit is NOT\n// modified). Same for the first-colon splitter and the balance checker.\n//\n//   \"if(media(width >= 800px): red; else: blue)\"  → the literal\n//   \"if(style(--x: 1): 2px)\"                       → the literal\n//   \"if(else: a; media(x): b)\"                     → never (else not last)\n//   \"if(media(x) red)\"                             → never (no colon)\n//   \"if(foo(x): 1)\"                                → never (unknown kind)\n//\n// See `2026-05-29-if-function-design.md` §3 + §7 for the validated-vs-deferred\n// boundary.\n// =====================================================================\n\nimport type { And, ParseFunction, Trim } from \"@/lib/ridiculous-type-kit\"\n\n// =====================================================================\n// 1. LOCAL PAREN-AWARE SPLITTERS (kit mirror — kit has no `;` splitter)\n// =====================================================================\n\ntype Push<Acc extends string[], Cur extends string> = [...Acc, Cur]\n\n// Walk char-by-char tracking ()/[] depth; split on `;` only at depth 0.\ntype SplitSemiTopLevel<\n  S extends string,\n  Depth extends unknown[] = [],\n  Cur extends string = \"\",\n  Acc extends string[] = [],\n> = S extends `${infer C}${infer Rest}`\n  ? C extends \"(\" | \"[\"\n    ? SplitSemiTopLevel<Rest, [...Depth, unknown], `${Cur}${C}`, Acc>\n    : C extends \")\" | \"]\"\n      ? SplitSemiTopLevel<\n          Rest,\n          Depth extends [unknown, ...infer D] ? D : [],\n          `${Cur}${C}`,\n          Acc\n        >\n      : C extends \";\"\n        ? Depth[\"length\"] extends 0\n          ? SplitSemiTopLevel<Rest, Depth, \"\", Push<Acc, Cur>>\n          : SplitSemiTopLevel<Rest, Depth, `${Cur}${C}`, Acc>\n        : SplitSemiTopLevel<Rest, Depth, `${Cur}${C}`, Acc>\n  : Push<Acc, Cur>\n\n// Trim each part; DROP empty parts (so a trailing `;` is tolerated).\ntype TrimDropEmpty<T extends string[]> = T extends [\n  infer H extends string,\n  ...infer R extends string[],\n]\n  ? Trim<H> extends \"\"\n    ? TrimDropEmpty<R>\n    : [Trim<H>, ...TrimDropEmpty<R>]\n  : []\n\n/** Split an `if()` body on TOP-LEVEL semicolons into trimmed branches. */\nexport type SplitBySemicolon<S extends string> = TrimDropEmpty<\n  SplitSemiTopLevel<S>\n>\n\n// Split on the FIRST `:` at depth 0 → [before, after], else never. A colon\n// inside `style(--x: 1)` (depth 1) or a value's `url(a:b)` is NOT the split.\ntype SplitFirstColon<\n  S extends string,\n  Depth extends unknown[] = [],\n  Cur extends string = \"\",\n> = S extends `${infer C}${infer Rest}`\n  ? C extends \"(\" | \"[\"\n    ? SplitFirstColon<Rest, [...Depth, unknown], `${Cur}${C}`>\n    : C extends \")\" | \"]\"\n      ? SplitFirstColon<\n          Rest,\n          Depth extends [unknown, ...infer D] ? D : [],\n          `${Cur}${C}`\n        >\n      : C extends \":\"\n        ? Depth[\"length\"] extends 0\n          ? [Cur, Rest]\n          : SplitFirstColon<Rest, Depth, `${Cur}${C}`>\n        : SplitFirstColon<Rest, Depth, `${Cur}${C}`>\n  : never // no top-level colon\n\n// =====================================================================\n// 2. BALANCE CHECK (parens balance + never go negative)\n// =====================================================================\n\ntype IsBalancedAcc<\n  S extends string,\n  Depth extends unknown[] = [],\n> = S extends `${infer C}${infer Rest}`\n  ? C extends \"(\" | \"[\"\n    ? IsBalancedAcc<Rest, [...Depth, unknown]>\n    : C extends \")\" | \"]\"\n      ? Depth extends [unknown, ...infer D]\n        ? IsBalancedAcc<Rest, D>\n        : false // closed with nothing open → negative\n      : IsBalancedAcc<Rest, Depth>\n  : Depth[\"length\"] extends 0\n    ? true\n    : false // unclosed at end\n\n/** True iff every `(`/`[` is matched and depth never goes negative. */\nexport type IsBalanced<S extends string> = IsBalancedAcc<S>\n\n// =====================================================================\n// 3. CONDITION VALIDATION (lenient bodies — roadmap §7)\n// =====================================================================\n\n// A media()/supports()/style() condition whose body is non-empty + balanced.\ntype IsConditionKind<S extends string> =\n  Trim<S> extends `media(${infer B})`\n    ? NonEmptyBalanced<B>\n    : Trim<S> extends `supports(${infer B})`\n      ? NonEmptyBalanced<B>\n      : Trim<S> extends `style(${infer B})`\n        ? NonEmptyBalanced<B>\n        : false\n\ntype NonEmptyBalanced<B extends string> =\n  Trim<B> extends \"\" ? false : IsBalanced<B>\n\n// =====================================================================\n// 4. BRANCH + WRAPPER VALIDATION\n// =====================================================================\n\n// One branch: split on the first top-level colon, validate condition + value.\n// `else` is accepted only when `IsLast` is true.\ntype IsBranch<S extends string, IsLast extends boolean> =\n  SplitFirstColon<Trim<S>> extends [\n    infer Cond extends string,\n    infer Val extends string,\n  ]\n    ? And<\n        Trim<Cond> extends \"else\" ? IsLast : IsConditionKind<Cond>,\n        Trim<Val> extends \"\" ? false : true\n      >\n    : false // no colon\n\n// Fold the branch list; only the final element may be `else`.\ntype ValidateBranches<Branches extends string[]> = Branches extends [\n  infer Only extends string,\n]\n  ? IsBranch<Only, true>\n  : Branches extends [infer Head extends string, ...infer Rest extends string[]]\n    ? IsBranch<Head, false> extends true\n      ? ValidateBranches<Rest>\n      : false\n    : false // empty list\n\n/**\n * Strict `if()` validator. Resolves to `S` for a valid CSS `if()` value,\n * `never` otherwise. Condition bodies are validated leniently (non-empty +\n * balanced parens); their internal grammar is deferred to the runtime parser\n * (design §7).\n *\n * @example\n * type A = IfFunctionLiteral<\"if(media(width >= 800px): red; else: blue)\"> // literal\n * type B = IfFunctionLiteral<\"if(else: a; media(x): b)\">                   // never\n * type C = IfFunctionLiteral<\"if(style(--x: 1): 2px)\">                     // literal\n */\nexport type IfFunctionLiteral<S extends string> =\n  ParseFunction<Trim<S>> extends { name: \"if\"; args: infer Body extends string }\n    ? SplitBySemicolon<Body> extends infer Branches extends string[]\n      ? Branches extends []\n        ? never\n        : ValidateBranches<Branches> extends true\n          ? S\n          : never\n      : never\n    : never\n\n/**\n * Call-site validator helper. Mirrors `color()` / `easing()` / `cssCalc()`.\n * An invalid `if()` becomes a type error at the argument.\n */\nexport const cssIf = <S extends string>(value: S & IfFunctionLiteral<S>): S =>\n  value\n\n// =====================================================================\n// 5. SUGGESTION STRINGS — IntelliSense + onChange return types\n//\n// Permissive (the strict tier is the real gate), like transition-editor's\n// TransitionString. `if()` has a single output shape — no mode prop narrows\n// the output, so there is no StringMap (design A6).\n// =====================================================================\n\n/** A condition kind discriminant. */\nexport type ConditionKind = \"media\" | \"supports\" | \"style\" | \"else\"\n\n/** Suggestion union for a single condition. */\nexport type ConditionString =\n  | `media(${string})`\n  | `supports(${string})`\n  | `style(${string})`\n  | \"else\"\n\n/** Suggestion union — \"this is an if() string\". */\nexport type IfFunctionString = `if(${string})` | (string & {})\n\n// =====================================================================\n// 6. UTILITY TYPES — operate on if() literals at the type level\n// =====================================================================\n\n/**\n * The raw per-branch strings of an `if()` body (`[]` if not an if()).\n *\n * @example\n * type T = BranchesOf<\"if(media(x): a; else: b)\"> // [\"media(x): a\", \"else: b\"]\n */\nexport type BranchesOf<S extends string> =\n  ParseFunction<Trim<S>> extends { name: \"if\"; args: infer Body extends string }\n    ? SplitBySemicolon<Body>\n    : []\n\n/**\n * The number of branches.\n *\n * @example\n * type C = BranchCountOf<\"if(media(x): a; else: b)\"> // 2\n */\nexport type BranchCountOf<S extends string> = BranchesOf<S>[\"length\"]\n\n// The condition kind of one branch string (defaults to \"else\" wording for the\n// bare `else`; \"media\"/\"supports\"/\"style\" by prefix). Used by ConditionKindsOf.\ntype KindOfBranch<S extends string> =\n  SplitFirstColon<Trim<S>> extends [infer Cond extends string, string]\n    ? Trim<Cond> extends `media(${string}`\n      ? \"media\"\n      : Trim<Cond> extends `supports(${string}`\n        ? \"supports\"\n        : Trim<Cond> extends `style(${string}`\n          ? \"style\"\n          : Trim<Cond> extends \"else\"\n            ? \"else\"\n            : never\n    : never\n\ntype MapKinds<Branches extends string[]> = Branches extends [\n  infer H extends string,\n  ...infer R extends string[],\n]\n  ? [KindOfBranch<H>, ...MapKinds<R>]\n  : []\n\n/**\n * The condition kind of each branch.\n *\n * @example\n * type T = ConditionKindsOf<\"if(media(x): a; else: b)\"> // [\"media\", \"else\"]\n */\nexport type ConditionKindsOf<S extends string> = MapKinds<BranchesOf<S>>\n\n// =====================================================================\n// 7. INTERNAL STATE — the per-branch record + the editor state object\n//    (exported for advanced use: custom serialization, programmatic build).\n//    Values are kept as strings (they carry CSS tokens), mirroring how the\n//    literal preserves the raw text.\n// =====================================================================\n\n/**\n * One `if()` branch. All kinds share this flat shape; `else` leaves\n * `condition` empty (design A11). `kind` is the literal-union discriminant.\n */\nexport interface IfBranch {\n  /** The condition kind. */\n  kind: ConditionKind\n  /** The condition body (inside the kind's parens). Empty for `else`. */\n  condition: string\n  /** The branch value (right of the colon). */\n  value: string\n}\n\n/**\n * The editor's internal state — a branch list. An object wrapper (not a bare\n * array) for forward-compat; the discriminant lives per-branch on `kind`.\n */\nexport interface IfFunctionState {\n  branches: IfBranch[]\n}\n",
      "type": "registry:ui",
      "target": "components/ui/if-function/if-function.types.ts"
    },
    {
      "path": "src/components/ui/if-function/if-function.helpers.ts",
      "content": "// =====================================================================\n// if-function.helpers.ts\n//\n// Pure runtime parse / format for the CSS `if()` conditional value function.\n// This is the SUPERSET of the strict type tier: it validates the wrapper, the\n// top-level `;` branch split, the first top-level `:` per branch, the condition\n// kind, paren balance, and value presence — but keeps condition bodies + values\n// verbatim (it does NOT parse the media/supports/style grammar, per design §7).\n// It is the single source of truth the UI drives off.\n//\n//   if( <branch> [ ; <branch> ]* )\n//   <branch>    = <condition> : <value>\n//   <condition> = media(...) | supports(...) | style(...) | else (last only)\n// =====================================================================\n\nimport type { ConditionKind, IfBranch } from \"./if-function.types\"\n\n// ---------------------------------------------------------------------------\n// Top-level splitter (paren-aware, runtime mirror of the kit combinator)\n// ---------------------------------------------------------------------------\n\n/** Split `src` on `sep` only at bracket depth 0. */\nfunction splitTopLevel(src: string, sep: string): string[] {\n  const out: string[] = []\n  let depth = 0\n  let cur = \"\"\n  for (const ch of src) {\n    if (ch === \"(\" || ch === \"[\") depth++\n    else if (ch === \")\" || ch === \"]\") depth--\n    if (ch === sep && depth === 0) {\n      out.push(cur)\n      cur = \"\"\n    } else {\n      cur += ch\n    }\n  }\n  out.push(cur)\n  return out\n}\n\n/** Index of the first `:` at bracket depth 0, or -1. */\nfunction firstTopLevelColon(src: string): number {\n  let depth = 0\n  for (let i = 0; i < src.length; i++) {\n    const ch = src[i]\n    if (ch === \"(\" || ch === \"[\") depth++\n    else if (ch === \")\" || ch === \"]\") depth--\n    else if (ch === \":\" && depth === 0) return i\n  }\n  return -1\n}\n\n/** True iff every `(`/`[` is matched and depth never goes negative. */\nfunction isBalanced(src: string): boolean {\n  let depth = 0\n  for (const ch of src) {\n    if (ch === \"(\" || ch === \"[\") depth++\n    else if (ch === \")\" || ch === \"]\") {\n      depth--\n      if (depth < 0) return false\n    }\n  }\n  return depth === 0\n}\n\n// ---------------------------------------------------------------------------\n// Condition classification\n// ---------------------------------------------------------------------------\n\ninterface ParsedCondition {\n  kind: ConditionKind\n  condition: string\n}\n\nconst KIND_RE = /^(media|supports|style)\\(([\\s\\S]*)\\)$/\n\n/**\n * Classify a condition string into a kind + inner body. `else` → empty body.\n * Returns null on an unknown kind or an unbalanced / empty-body kind call.\n */\nfunction parseCondition(raw: string): ParsedCondition | null {\n  const cond = raw.trim()\n  if (cond === \"else\") return { kind: \"else\", condition: \"\" }\n  const m = cond.match(KIND_RE)\n  if (m === null) return null\n  const kind = m[1] as ConditionKind\n  const body = m[2]\n  if (body.trim() === \"\" || !isBalanced(body)) return null\n  return { kind, condition: body.trim() }\n}\n\n// ---------------------------------------------------------------------------\n// parseIf — string → branches | null\n// ---------------------------------------------------------------------------\n\nconst IF_WRAPPER_RE = /^if\\(([\\s\\S]*)\\)$/\n\n/**\n * Parse a CSS `if()` value into typed branches, or `null` on any error:\n * bad wrapper, no branches, a branch without a top-level colon, an empty value,\n * an unknown condition kind, an unbalanced condition body, or `else` not last.\n * A trailing `;` (and interior empty branches) are tolerated (dropped).\n */\nexport function parseIf(src: string): IfBranch[] | null {\n  const trimmed = src.trim()\n  const wrap = trimmed.match(IF_WRAPPER_RE)\n  if (wrap === null || !isBalanced(trimmed)) return null\n  const body = wrap[1]\n\n  const branchStrings = splitTopLevel(body, \";\")\n    .map((s) => s.trim())\n    .filter((s) => s.length > 0)\n  if (branchStrings.length === 0) return null\n\n  const branches: IfBranch[] = []\n  for (let i = 0; i < branchStrings.length; i++) {\n    const branchStr = branchStrings[i]\n    const colon = firstTopLevelColon(branchStr)\n    if (colon === -1) return null\n    const condRaw = branchStr.slice(0, colon)\n    const value = branchStr.slice(colon + 1).trim()\n    if (value === \"\") return null\n    const parsed = parseCondition(condRaw)\n    if (parsed === null) return null\n    // else only allowed as the final branch\n    if (parsed.kind === \"else\" && i !== branchStrings.length - 1) return null\n    branches.push({ kind: parsed.kind, condition: parsed.condition, value })\n  }\n  return branches\n}\n\n// ---------------------------------------------------------------------------\n// branchToCss / format — canonical serialization\n// ---------------------------------------------------------------------------\n\n/** Serialize one branch: `else: value` or `kind(condition): value`. */\nexport function branchToCss(branch: IfBranch): string {\n  if (branch.kind === \"else\") return `else: ${branch.value}`\n  return `${branch.kind}(${branch.condition}): ${branch.value}`\n}\n\n/** Canonical re-serialization of a branch list → `if( b1; b2; … )`. */\nexport function formatIf(branches: IfBranch[]): string {\n  return `if(${branches.map(branchToCss).join(\"; \")})`\n}\n\n// ---------------------------------------------------------------------------\n// defaults — seed a fresh branch\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CONDITION: Record<ConditionKind, string> = {\n  media: \"width >= 600px\",\n  supports: \"display: grid\",\n  style: \"--x: 1\",\n  else: \"\",\n}\n\n/** A sensible default branch for a kind (defaults to a media branch). */\nexport function defaultBranch(kind: ConditionKind = \"media\"): IfBranch {\n  return { kind, condition: DEFAULT_CONDITION[kind], value: \"red\" }\n}\n\n// ---------------------------------------------------------------------------\n// branchCount — runtime mirror of BranchCountOf (invalid → 0)\n// ---------------------------------------------------------------------------\n\n/** The number of branches in a value, or 0 if it does not parse. */\nexport function branchCount(src: string): number {\n  const branches = parseIf(src)\n  return branches === null ? 0 : branches.length\n}\n",
      "type": "registry:ui",
      "target": "components/ui/if-function/if-function.helpers.ts"
    }
  ],
  "type": "registry:ui"
}