{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "lucide-provider",
  "title": "Lucide Provider",
  "description": "Pins lucide-react icons to nx-ui's line weight so they sit correctly beside @untitledui/icons; wrap your root layout once.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "files": [
    {
      "path": "components/ui/lucide-provider.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { LucideProvider as LucideProviderPrimitive } from \"lucide-react\"\n\n/**\n * LucideProvider — pins `lucide-react` icons to nx-ui's line weight so a\n * consumer app can mix them with `@untitledui/icons` without a visual seam.\n *\n * ## Why this exists\n *\n * nx-ui's own components import from `@untitledui/icons`, but consumer apps are\n * free to use `lucide-react` alongside them (see AGENTS.md, \"Icons — two sets,\n * one line weight\"). At the versions this was written against the two sets\n * already agree: all 1179 icons in `@untitledui/icons@0.0.22` render\n * `stroke-width=\"2\"` on a 24 viewBox with round caps and joins, and\n * `lucide-react@1.23.0`'s default is the same value.\n *\n * So this is a **pin, not a correction**. `lucide-react` is floated at\n * `^1.23.0`; a minor bump that moved the default weight would silently\n * desynchronise the two sets across every consumer. Wrapping the app once makes\n * the weight explicit, and `tests/icon-stroke-parity.test.ts` fails CI if either\n * package drifts off `NX_ICON_STROKE_WIDTH`.\n *\n * ## Why there is no CSS fallback\n *\n * A `.lucide` CSS rule would break per-call overrides: CSS always beats an SVG\n * presentation attribute, so `svg.lucide { stroke-width: 2 }` would clobber a\n * caller's `<Activity strokeWidth={3} />`. The only override-safe form matches\n * the untouched default only —\n * `@layer base { svg.lucide[stroke-width=\"<lucide's default>\"] { stroke-width: 2 } }`\n * — which at today's matching defaults is a literal no-op.\n *\n * **Trigger for revisiting:** add that rule if and only if the parity test fails\n * because lucide's default changed *and* the decision is to keep nx-ui at 2. In\n * that case put it in a new `styles/lucide-compat.css`, add a\n * `buildLucideCompatItem()` to `scripts/build-registry.ts` modelled on\n * `buildMapboxOverridesItem()`, wire it into `main()`'s `allItems`, and pull it\n * in from this file with an `import \"@/styles/lucide-compat.css\"` preceded by a\n * registry-dep marker comment naming `lucide-compat`, exactly as `map-view.tsx`\n * does. (Spelling that marker out literally here would make the registry\n * generator parse this prose as a real dependency — it scans for the marker to\n * end of line.)\n *\n * ## Usage\n *\n * Wrap the app once, inside your theme provider:\n *\n * ```tsx\n * // app/layout.tsx\n * <ThemeProvider>\n *   <LucideProvider>{children}</LucideProvider>\n * </ThemeProvider>\n * ```\n *\n * This is a client component, so a server root layout can render it directly —\n * the same pattern as `components/theme-provider.tsx`.\n *\n * Read the context back with lucide's own `useLucideContext()` — this file\n * wraps lucide's provider rather than replacing it, so the hook is imported\n * from `lucide-react` directly and is deliberately not re-exported here.\n */\n\n/**\n * nx-ui's base icon line weight.\n *\n * Measured, not assumed: all 1179 icons in `@untitledui/icons@0.0.22` render\n * `stroke-width=\"2\"` on a 24 viewBox, and `lucide-react`'s default is the same.\n * Small glyphs deliberately bump higher (2.25–3) via `stroke-[…]` utilities on\n * individual components — this is the base weight, not a ceiling.\n *\n * It lives in this file because this is the only place nx-ui has to *apply* it:\n * `@untitledui/icons` renders the weight itself and needs no configuration, so\n * an app using only that set never has to reference this constant (and should\n * not install this item, which depends on `lucide-react`, just to read it).\n */\nconst NX_ICON_STROKE_WIDTH = 2\n\n/**\n * Provides nx-ui's icon line weight to every `lucide-react` icon beneath it.\n *\n * Any icon may still override it per call — lucide computes\n * `strokeWidth ?? contextStrokeWidth`, so `<Activity strokeWidth={3} />` wins\n * over the provider. Tailwind `stroke-[…]` utilities also still win, because the\n * provider sets an SVG presentation attribute rather than a CSS declaration.\n *\n * Two props on the passed-through surface are traps in this codebase:\n *\n * - **Never set `absoluteStrokeWidth`.** lucide computes\n *   `strokeWidth * 24 / size`, dividing by the *numeric* `size` prop. nx-ui\n *   sizes icons with Tailwind `size-*` classes and never sets `size`, so it\n *   stays 24 while icons actually render at 16–28px — the scaling silently\n *   produces a wrong weight for every icon here.\n * - **Never put sizing or stroke utilities in `className`.** lucide merges the\n *   provider's class with each icon's own using a naive dedupe-and-join, not\n *   `tailwind-merge`, so `<LucideProvider className=\"size-6\">` yields\n *   `class=\"lucide size-6 lucide-activity size-4\"` — the classes accumulate and\n *   CSS source order, not specificity intent, decides the winner.\n */\nfunction LucideProvider({\n  strokeWidth = NX_ICON_STROKE_WIDTH,\n  ...props\n}: React.ComponentProps<typeof LucideProviderPrimitive>) {\n  return <LucideProviderPrimitive strokeWidth={strokeWidth} {...props} />\n}\n\nexport { LucideProvider, NX_ICON_STROKE_WIDTH }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}