@nanisoft/prism-ui 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/THIRD-PARTY-NOTICES.md +48 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/blocks/app-shell-01/app-shell.d.ts +38 -0
  6. package/dist/blocks/app-shell-01/app-shell.d.ts.map +1 -0
  7. package/dist/blocks/app-shell-01/app-shell.js +27 -0
  8. package/dist/blocks/app-shell-01/index.d.ts +3 -0
  9. package/dist/blocks/app-shell-01/index.d.ts.map +1 -0
  10. package/dist/blocks/app-shell-01/index.js +1 -0
  11. package/dist/blocks/auth-form-01/auth-form.d.ts +52 -0
  12. package/dist/blocks/auth-form-01/auth-form.d.ts.map +1 -0
  13. package/dist/blocks/auth-form-01/auth-form.js +23 -0
  14. package/dist/blocks/auth-form-01/index.d.ts +3 -0
  15. package/dist/blocks/auth-form-01/index.d.ts.map +1 -0
  16. package/dist/blocks/auth-form-01/index.js +1 -0
  17. package/dist/blocks/cta-01/cta.d.ts +83 -0
  18. package/dist/blocks/cta-01/cta.d.ts.map +1 -0
  19. package/dist/blocks/cta-01/cta.js +29 -0
  20. package/dist/blocks/cta-01/index.d.ts +3 -0
  21. package/dist/blocks/cta-01/index.d.ts.map +1 -0
  22. package/dist/blocks/cta-01/index.js +1 -0
  23. package/dist/blocks/data-table-01/data-table.d.ts +102 -0
  24. package/dist/blocks/data-table-01/data-table.d.ts.map +1 -0
  25. package/dist/blocks/data-table-01/data-table.js +116 -0
  26. package/dist/blocks/data-table-01/index.d.ts +3 -0
  27. package/dist/blocks/data-table-01/index.d.ts.map +1 -0
  28. package/dist/blocks/data-table-01/index.js +1 -0
  29. package/dist/blocks/feature-grid-01/feature-grid.d.ts +78 -0
  30. package/dist/blocks/feature-grid-01/feature-grid.d.ts.map +1 -0
  31. package/dist/blocks/feature-grid-01/feature-grid.js +24 -0
  32. package/dist/blocks/feature-grid-01/index.d.ts +3 -0
  33. package/dist/blocks/feature-grid-01/index.d.ts.map +1 -0
  34. package/dist/blocks/feature-grid-01/index.js +1 -0
  35. package/dist/blocks/hero-01/hero.d.ts +59 -0
  36. package/dist/blocks/hero-01/hero.d.ts.map +1 -0
  37. package/dist/blocks/hero-01/hero.js +24 -0
  38. package/dist/blocks/hero-01/index.d.ts +2 -0
  39. package/dist/blocks/hero-01/index.d.ts.map +1 -0
  40. package/dist/blocks/hero-01/index.js +1 -0
  41. package/dist/blocks/index.d.ts +28 -0
  42. package/dist/blocks/index.d.ts.map +1 -0
  43. package/dist/blocks/index.js +26 -0
  44. package/dist/blocks/instrument-panel-01/index.d.ts +3 -0
  45. package/dist/blocks/instrument-panel-01/index.d.ts.map +1 -0
  46. package/dist/blocks/instrument-panel-01/index.js +1 -0
  47. package/dist/blocks/instrument-panel-01/instrument-panel.d.ts +114 -0
  48. package/dist/blocks/instrument-panel-01/instrument-panel.d.ts.map +1 -0
  49. package/dist/blocks/instrument-panel-01/instrument-panel.js +64 -0
  50. package/dist/blocks/logo-strip-01/index.d.ts +3 -0
  51. package/dist/blocks/logo-strip-01/index.d.ts.map +1 -0
  52. package/dist/blocks/logo-strip-01/index.js +1 -0
  53. package/dist/blocks/logo-strip-01/logo-strip.d.ts +84 -0
  54. package/dist/blocks/logo-strip-01/logo-strip.d.ts.map +1 -0
  55. package/dist/blocks/logo-strip-01/logo-strip.js +40 -0
  56. package/dist/blocks/note-grid-01/index.d.ts +3 -0
  57. package/dist/blocks/note-grid-01/index.d.ts.map +1 -0
  58. package/dist/blocks/note-grid-01/index.js +1 -0
  59. package/dist/blocks/note-grid-01/note-grid.d.ts +79 -0
  60. package/dist/blocks/note-grid-01/note-grid.d.ts.map +1 -0
  61. package/dist/blocks/note-grid-01/note-grid.js +37 -0
  62. package/dist/blocks/page-header-01/index.d.ts +3 -0
  63. package/dist/blocks/page-header-01/index.d.ts.map +1 -0
  64. package/dist/blocks/page-header-01/index.js +1 -0
  65. package/dist/blocks/page-header-01/page-header.d.ts +48 -0
  66. package/dist/blocks/page-header-01/page-header.d.ts.map +1 -0
  67. package/dist/blocks/page-header-01/page-header.js +27 -0
  68. package/dist/blocks/pricing-01/index.d.ts +2 -0
  69. package/dist/blocks/pricing-01/index.d.ts.map +1 -0
  70. package/dist/blocks/pricing-01/index.js +1 -0
  71. package/dist/blocks/pricing-01/pricing.d.ts +35 -0
  72. package/dist/blocks/pricing-01/pricing.d.ts.map +1 -0
  73. package/dist/blocks/pricing-01/pricing.js +20 -0
  74. package/dist/blocks/process-rail-01/index.d.ts +3 -0
  75. package/dist/blocks/process-rail-01/index.d.ts.map +1 -0
  76. package/dist/blocks/process-rail-01/index.js +1 -0
  77. package/dist/blocks/process-rail-01/process-rail.d.ts +99 -0
  78. package/dist/blocks/process-rail-01/process-rail.d.ts.map +1 -0
  79. package/dist/blocks/process-rail-01/process-rail.js +58 -0
  80. package/dist/blocks/product-grid-01/index.d.ts +3 -0
  81. package/dist/blocks/product-grid-01/index.d.ts.map +1 -0
  82. package/dist/blocks/product-grid-01/index.js +1 -0
  83. package/dist/blocks/product-grid-01/product-grid.d.ts +114 -0
  84. package/dist/blocks/product-grid-01/product-grid.d.ts.map +1 -0
  85. package/dist/blocks/product-grid-01/product-grid.js +51 -0
  86. package/dist/blocks/settings-panel-01/index.d.ts +3 -0
  87. package/dist/blocks/settings-panel-01/index.d.ts.map +1 -0
  88. package/dist/blocks/settings-panel-01/index.js +1 -0
  89. package/dist/blocks/settings-panel-01/settings-panel.d.ts +71 -0
  90. package/dist/blocks/settings-panel-01/settings-panel.d.ts.map +1 -0
  91. package/dist/blocks/settings-panel-01/settings-panel.js +38 -0
  92. package/dist/blocks/site-footer/index.d.ts +3 -0
  93. package/dist/blocks/site-footer/index.d.ts.map +1 -0
  94. package/dist/blocks/site-footer/index.js +1 -0
  95. package/dist/blocks/site-footer/site-footer.d.ts +135 -0
  96. package/dist/blocks/site-footer/site-footer.d.ts.map +1 -0
  97. package/dist/blocks/site-footer/site-footer.js +41 -0
  98. package/dist/blocks/site-header/index.d.ts +3 -0
  99. package/dist/blocks/site-header/index.d.ts.map +1 -0
  100. package/dist/blocks/site-header/index.js +1 -0
  101. package/dist/blocks/site-header/site-header.d.ts +142 -0
  102. package/dist/blocks/site-header/site-header.d.ts.map +1 -0
  103. package/dist/blocks/site-header/site-header.js +46 -0
  104. package/dist/blocks/stack-grid-01/index.d.ts +3 -0
  105. package/dist/blocks/stack-grid-01/index.d.ts.map +1 -0
  106. package/dist/blocks/stack-grid-01/index.js +1 -0
  107. package/dist/blocks/stack-grid-01/stack-grid.d.ts +118 -0
  108. package/dist/blocks/stack-grid-01/stack-grid.d.ts.map +1 -0
  109. package/dist/blocks/stack-grid-01/stack-grid.js +49 -0
  110. package/dist/blocks/stats-01/index.d.ts +2 -0
  111. package/dist/blocks/stats-01/index.d.ts.map +1 -0
  112. package/dist/blocks/stats-01/index.js +1 -0
  113. package/dist/blocks/stats-01/stats.d.ts +28 -0
  114. package/dist/blocks/stats-01/stats.d.ts.map +1 -0
  115. package/dist/blocks/stats-01/stats.js +27 -0
  116. package/dist/blocks/status-ledger-01/index.d.ts +3 -0
  117. package/dist/blocks/status-ledger-01/index.d.ts.map +1 -0
  118. package/dist/blocks/status-ledger-01/index.js +1 -0
  119. package/dist/blocks/status-ledger-01/status-ledger.d.ts +131 -0
  120. package/dist/blocks/status-ledger-01/status-ledger.d.ts.map +1 -0
  121. package/dist/blocks/status-ledger-01/status-ledger.js +80 -0
  122. package/dist/catalog.d.ts +28 -0
  123. package/dist/catalog.d.ts.map +1 -0
  124. package/dist/catalog.js +672 -0
  125. package/dist/components/index.d.ts +64 -0
  126. package/dist/components/index.d.ts.map +1 -0
  127. package/dist/components/index.js +43 -0
  128. package/dist/components/ui/accordion.d.ts +65 -0
  129. package/dist/components/ui/accordion.d.ts.map +1 -0
  130. package/dist/components/ui/accordion.js +30 -0
  131. package/dist/components/ui/alert.d.ts +19 -0
  132. package/dist/components/ui/alert.d.ts.map +1 -0
  133. package/dist/components/ui/alert.js +31 -0
  134. package/dist/components/ui/avatar.d.ts +47 -0
  135. package/dist/components/ui/avatar.d.ts.map +1 -0
  136. package/dist/components/ui/avatar.js +30 -0
  137. package/dist/components/ui/badge.d.ts +14 -0
  138. package/dist/components/ui/badge.d.ts.map +1 -0
  139. package/dist/components/ui/badge.js +26 -0
  140. package/dist/components/ui/breadcrumb.d.ts +35 -0
  141. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  142. package/dist/components/ui/breadcrumb.js +48 -0
  143. package/dist/components/ui/button.d.ts +16 -0
  144. package/dist/components/ui/button.d.ts.map +1 -0
  145. package/dist/components/ui/button.js +63 -0
  146. package/dist/components/ui/card.d.ts +41 -0
  147. package/dist/components/ui/card.d.ts.map +1 -0
  148. package/dist/components/ui/card.js +53 -0
  149. package/dist/components/ui/checkbox.d.ts +43 -0
  150. package/dist/components/ui/checkbox.d.ts.map +1 -0
  151. package/dist/components/ui/checkbox.js +18 -0
  152. package/dist/components/ui/cta-link.d.ts +45 -0
  153. package/dist/components/ui/cta-link.d.ts.map +1 -0
  154. package/dist/components/ui/cta-link.js +81 -0
  155. package/dist/components/ui/diagram.d.ts +154 -0
  156. package/dist/components/ui/diagram.d.ts.map +1 -0
  157. package/dist/components/ui/diagram.js +150 -0
  158. package/dist/components/ui/dialog.d.ts +81 -0
  159. package/dist/components/ui/dialog.d.ts.map +1 -0
  160. package/dist/components/ui/dialog.js +60 -0
  161. package/dist/components/ui/dropdown-menu.d.ts +189 -0
  162. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  163. package/dist/components/ui/dropdown-menu.js +67 -0
  164. package/dist/components/ui/fact-list.d.ts +90 -0
  165. package/dist/components/ui/fact-list.d.ts.map +1 -0
  166. package/dist/components/ui/fact-list.js +38 -0
  167. package/dist/components/ui/field.d.ts +36 -0
  168. package/dist/components/ui/field.d.ts.map +1 -0
  169. package/dist/components/ui/field.js +46 -0
  170. package/dist/components/ui/input.d.ts +12 -0
  171. package/dist/components/ui/input.d.ts.map +1 -0
  172. package/dist/components/ui/input.js +14 -0
  173. package/dist/components/ui/kbd.d.ts +10 -0
  174. package/dist/components/ui/kbd.d.ts.map +1 -0
  175. package/dist/components/ui/kbd.js +12 -0
  176. package/dist/components/ui/pagination.d.ts +40 -0
  177. package/dist/components/ui/pagination.d.ts.map +1 -0
  178. package/dist/components/ui/pagination.js +49 -0
  179. package/dist/components/ui/popover.d.ts +56 -0
  180. package/dist/components/ui/popover.d.ts.map +1 -0
  181. package/dist/components/ui/popover.js +25 -0
  182. package/dist/components/ui/product-mark.d.ts +115 -0
  183. package/dist/components/ui/product-mark.d.ts.map +1 -0
  184. package/dist/components/ui/product-mark.js +82 -0
  185. package/dist/components/ui/product-switcher.d.ts +108 -0
  186. package/dist/components/ui/product-switcher.d.ts.map +1 -0
  187. package/dist/components/ui/product-switcher.js +47 -0
  188. package/dist/components/ui/progress.d.ts +38 -0
  189. package/dist/components/ui/progress.d.ts.map +1 -0
  190. package/dist/components/ui/progress.js +17 -0
  191. package/dist/components/ui/prose.d.ts +88 -0
  192. package/dist/components/ui/prose.d.ts.map +1 -0
  193. package/dist/components/ui/prose.js +53 -0
  194. package/dist/components/ui/radio-group.d.ts +66 -0
  195. package/dist/components/ui/radio-group.d.ts.map +1 -0
  196. package/dist/components/ui/radio-group.js +30 -0
  197. package/dist/components/ui/section.d.ts +60 -0
  198. package/dist/components/ui/section.d.ts.map +1 -0
  199. package/dist/components/ui/section.js +21 -0
  200. package/dist/components/ui/select.d.ts +124 -0
  201. package/dist/components/ui/select.d.ts.map +1 -0
  202. package/dist/components/ui/select.js +47 -0
  203. package/dist/components/ui/separator.d.ts +16 -0
  204. package/dist/components/ui/separator.d.ts.map +1 -0
  205. package/dist/components/ui/separator.js +15 -0
  206. package/dist/components/ui/skeleton.d.ts +12 -0
  207. package/dist/components/ui/skeleton.d.ts.map +1 -0
  208. package/dist/components/ui/skeleton.js +14 -0
  209. package/dist/components/ui/slider.d.ts +43 -0
  210. package/dist/components/ui/slider.d.ts.map +1 -0
  211. package/dist/components/ui/slider.js +23 -0
  212. package/dist/components/ui/switch.d.ts +42 -0
  213. package/dist/components/ui/switch.d.ts.map +1 -0
  214. package/dist/components/ui/switch.js +16 -0
  215. package/dist/components/ui/table.d.ts +27 -0
  216. package/dist/components/ui/table.d.ts.map +1 -0
  217. package/dist/components/ui/table.js +43 -0
  218. package/dist/components/ui/tabs.d.ts +66 -0
  219. package/dist/components/ui/tabs.d.ts.map +1 -0
  220. package/dist/components/ui/tabs.js +29 -0
  221. package/dist/components/ui/textarea.d.ts +11 -0
  222. package/dist/components/ui/textarea.d.ts.map +1 -0
  223. package/dist/components/ui/textarea.js +13 -0
  224. package/dist/components/ui/tooltip.d.ts +63 -0
  225. package/dist/components/ui/tooltip.d.ts.map +1 -0
  226. package/dist/components/ui/tooltip.js +25 -0
  227. package/dist/components/ui/typography.d.ts +32 -0
  228. package/dist/components/ui/typography.d.ts.map +1 -0
  229. package/dist/components/ui/typography.js +51 -0
  230. package/dist/index.d.ts +79 -0
  231. package/dist/index.d.ts.map +1 -0
  232. package/dist/index.js +68 -0
  233. package/dist/lib/utils.d.ts +3 -0
  234. package/dist/lib/utils.d.ts.map +1 -0
  235. package/dist/lib/utils.js +5 -0
  236. package/dist/pages/auth-page/index.d.ts +36 -0
  237. package/dist/pages/auth-page/index.d.ts.map +1 -0
  238. package/dist/pages/auth-page/index.js +23 -0
  239. package/dist/pages/blog-post-page/index.d.ts +174 -0
  240. package/dist/pages/blog-post-page/index.d.ts.map +1 -0
  241. package/dist/pages/blog-post-page/index.js +49 -0
  242. package/dist/pages/dashboard-page/index.d.ts +36 -0
  243. package/dist/pages/dashboard-page/index.d.ts.map +1 -0
  244. package/dist/pages/dashboard-page/index.js +24 -0
  245. package/dist/pages/index.d.ts +21 -0
  246. package/dist/pages/index.d.ts.map +1 -0
  247. package/dist/pages/index.js +14 -0
  248. package/dist/pages/marketing-page/index.d.ts +43 -0
  249. package/dist/pages/marketing-page/index.d.ts.map +1 -0
  250. package/dist/pages/marketing-page/index.js +25 -0
  251. package/dist/pages/not-found-page/index.d.ts +112 -0
  252. package/dist/pages/not-found-page/index.d.ts.map +1 -0
  253. package/dist/pages/not-found-page/index.js +46 -0
  254. package/dist/pages/settings-page/index.d.ts +47 -0
  255. package/dist/pages/settings-page/index.d.ts.map +1 -0
  256. package/dist/pages/settings-page/index.js +24 -0
  257. package/dist/provider/index.d.ts +12 -0
  258. package/dist/provider/index.d.ts.map +1 -0
  259. package/dist/provider/index.js +9 -0
  260. package/dist/provider/provider.d.ts +42 -0
  261. package/dist/provider/provider.d.ts.map +1 -0
  262. package/dist/provider/provider.js +178 -0
  263. package/dist/provider/theme-script.d.ts +55 -0
  264. package/dist/provider/theme-script.d.ts.map +1 -0
  265. package/dist/provider/theme-script.js +79 -0
  266. package/dist/styles.css +2894 -0
  267. package/dist/theming/index.d.ts +173 -0
  268. package/dist/theming/index.d.ts.map +1 -0
  269. package/dist/theming/index.js +186 -0
  270. package/package.json +89 -18
  271. package/components.json +0 -21
  272. package/public/r/badge.json +0 -26
  273. package/public/r/button.json +0 -26
  274. package/public/r/card.json +0 -25
  275. package/public/r/cta-01.json +0 -44
  276. package/public/r/feature-grid-01.json +0 -44
  277. package/public/r/hero-01.json +0 -44
  278. package/public/r/pricing-01.json +0 -46
  279. package/public/r/registry.json +0 -294
  280. package/public/r/section.json +0 -25
  281. package/public/r/stats-01.json +0 -44
  282. package/registry.json +0 -294
  283. package/src/components/ds/blocks/cta-01/block.json +0 -8
  284. package/src/components/ds/blocks/cta-01/cta.tsx +0 -62
  285. package/src/components/ds/blocks/cta-01/index.tsx +0 -1
  286. package/src/components/ds/blocks/feature-grid-01/block.json +0 -8
  287. package/src/components/ds/blocks/feature-grid-01/feature-grid.tsx +0 -69
  288. package/src/components/ds/blocks/feature-grid-01/index.tsx +0 -1
  289. package/src/components/ds/blocks/hero-01/block.json +0 -8
  290. package/src/components/ds/blocks/hero-01/hero.tsx +0 -85
  291. package/src/components/ds/blocks/hero-01/index.tsx +0 -1
  292. package/src/components/ds/blocks/pricing-01/block.json +0 -8
  293. package/src/components/ds/blocks/pricing-01/index.tsx +0 -1
  294. package/src/components/ds/blocks/pricing-01/pricing.tsx +0 -122
  295. package/src/components/ds/blocks/section.meta.json +0 -6
  296. package/src/components/ds/blocks/section.tsx +0 -86
  297. package/src/components/ds/blocks/stats-01/block.json +0 -8
  298. package/src/components/ds/blocks/stats-01/index.tsx +0 -1
  299. package/src/components/ds/blocks/stats-01/stats.tsx +0 -92
  300. package/src/components/ui/badge.tsx +0 -37
  301. package/src/components/ui/button.tsx +0 -77
  302. package/src/components/ui/card.tsx +0 -65
  303. package/src/lib/utils.ts +0 -6
@@ -0,0 +1,173 @@
1
+ /**
2
+ * The Prism theming vocabulary: pack and mode are two independent axes.
3
+ *
4
+ * `data-pack` selects the palette and `.dark` selects the mode; neither implies
5
+ * the other (ticket 07). `default` is the selectable neutral pack id, and its
6
+ * markup is the absence of the attribute. Everything here is pure and
7
+ * isomorphic so a Server Component can render the declarative form without a
8
+ * client runtime. There is no theme factory and no override object: the pack
9
+ * and mode are the whole API.
10
+ */
11
+ export declare const PACKS: readonly ["default", "blush", "mint", "lavender", "sky", "peach"];
12
+ export type PackId = (typeof PACKS)[number];
13
+ export declare const MODES: readonly ["light", "dark"];
14
+ export type Mode = (typeof MODES)[number];
15
+ export declare const PACK_ATTRIBUTE = "data-pack";
16
+ export declare const DEFAULT_STORAGE_KEY = "prism-theme";
17
+ /**
18
+ * The root attribute that records where the active pack and mode came from.
19
+ *
20
+ * This is a contract, not markup. The boot script is its only writer, and the
21
+ * provider never touches it, because two writers would make the recorded origin
22
+ * a race rather than a record. The value is always one of `THEME_ORIGINS` and is
23
+ * written on every path the script reaches, including a stored value that could
24
+ * not be parsed: an absent attribute cannot be told from an unread one, and a
25
+ * theme that fell through to the default is exactly the case a reader needs to
26
+ * see named.
27
+ *
28
+ * It is not `data-theme`, which `MIGRATION.md` retires. It carries the
29
+ * provenance of a resolution, never a pack.
30
+ */
31
+ export declare const THEME_ORIGIN_ATTRIBUTE = "data-theme-origin";
32
+ /**
33
+ * The closed set the boot script may write to `THEME_ORIGIN_ATTRIBUTE`.
34
+ *
35
+ * - `stored` a valid `{ pack, mode }` pair was in the key this line writes.
36
+ * - `legacy` the key was empty and a key this line no longer writes held a
37
+ * recoverable mode, so that decision was taken and carried over.
38
+ * - `unparsed` the key held a value that is not a pair. The theme fell
39
+ * through whole, and the value was left in place, because it is
40
+ * the only record that this reader ever chose anything.
41
+ * - `document` the key was empty and the root element's own attributes
42
+ * supplied the theme.
43
+ * - `default` neither did, so the consumer's own defaults apply.
44
+ *
45
+ * `legacy` and `unparsed` are why the set is five and not three: a
46
+ * three-value set records that the theme came from somewhere but cannot
47
+ * distinguish "never chose" from "chose, and the value no longer parses", which
48
+ * is the one distinction a storage migration has to be retired against.
49
+ */
50
+ export declare const THEME_ORIGINS: readonly ["stored", "legacy", "document", "default", "unparsed"];
51
+ export type ThemeOrigin = (typeof THEME_ORIGINS)[number];
52
+ /**
53
+ * Keys earlier lines of this package wrote and this line does not.
54
+ *
55
+ * `prism-theme-mode` was the shared chrome key: the mode setter wrote it, and
56
+ * only the mode setter, as a bare `'light'` or `'dark'` string, because the pack
57
+ * was fixed per site and the mode was the one choice that travelled across
58
+ * sites. The value is not a `{ pack, mode }` pair and can never collide with one
59
+ * this line writes, so reading it costs nothing and recovers a real decision.
60
+ *
61
+ * The list is the migration's own expiry. Every key in it is a clause the boot
62
+ * script carries and prices, and the migration is retired by deleting the last
63
+ * entry: the clause's live population is then empty, the gate reports it, and
64
+ * the byte ceiling's generation allowance falls to zero with it. Nothing here
65
+ * is bounded by a date or a version number.
66
+ */
67
+ export declare const LEGACY_MODE_STORAGE_KEYS: readonly ["prism-theme-mode"];
68
+ /**
69
+ * Reads a persisted `{ pack, mode }` object.
70
+ *
71
+ * Returns `null` for anything that is not a valid pair, so a corrupt or
72
+ * superseded stored value falls back to the defaults rather than to a pack that
73
+ * does not exist. Parsing is deliberately strict: the store is owned by
74
+ * `PrismProvider`, which always writes this exact shape.
75
+ */
76
+ export declare function parseStoredTheme(raw: string | null): {
77
+ pack: PackId;
78
+ mode: Mode;
79
+ } | null;
80
+ /**
81
+ * What `resolveTheme` was given, and nothing else.
82
+ *
83
+ * The three readers are all the same question asked of different state: what
84
+ * does this reader believe, what has the server rendered, and what is the
85
+ * consumer's own default. `stored` and `legacy` are raw strings exactly as the
86
+ * store holds them, so a corrupt value is visible to the rule rather than
87
+ * normalised away by a caller.
88
+ */
89
+ export type ThemeResolutionInput = {
90
+ /** Raw contents of the key this line writes, or `null` when it is absent. */
91
+ stored: string | null;
92
+ /** Raw contents of one key this line no longer writes, or `null`. */
93
+ legacy: string | null;
94
+ /** `data-pack` on the root element as rendered, valid or not. */
95
+ documentPack: string | null;
96
+ /** Whether the root element carries `.dark` as rendered. */
97
+ documentDark: boolean;
98
+ defaultPack: PackId;
99
+ defaultMode: Mode;
100
+ };
101
+ export type ThemeResolution = {
102
+ pack: PackId;
103
+ mode: Mode;
104
+ /** Which source named the pair, for `THEME_ORIGIN_ATTRIBUTE`. */
105
+ origin: ThemeOrigin;
106
+ };
107
+ /**
108
+ * The one resolution rule. `PrismProvider` calls it, and the boot script
109
+ * implements it as a string, and the equivalence gate runs both over one table
110
+ * because the string cannot import it.
111
+ *
112
+ * A serialised function is not a way to share it. The build minifies, a renamed
113
+ * identifier inside the script's own `try` would throw there and the catch
114
+ * would fail open, leaving a silent no-op on every page; so the honest shape is
115
+ * one implementation plus a gate that can fail, not two copies that look
116
+ * aligned.
117
+ *
118
+ * The order, and why each step is where it is:
119
+ *
120
+ * 1. A valid pair in the key this line writes wins outright. A decision
121
+ * recorded as a pair is a decision, and it is the only source that names
122
+ * both axes at once.
123
+ * 2. A value that is present but is not a pair falls through WHOLE. It is not
124
+ * repaired field by field, because a half-applied pair is a theme neither
125
+ * the reader nor the server chose, and because repairing it would make the
126
+ * two readers disagree about what "a valid mode" means. The value is also
127
+ * not cleared: it is the only record that this reader ever chose, and the
128
+ * origin is `unparsed` so a reader can see that it is there and unusable.
129
+ * 3. Only an absent key reaches the keys this line no longer writes. A present
130
+ * but unusable value is a record of an intent and outranks an older one.
131
+ * 4. The root element's own attributes, which is what a server rendered and
132
+ * what must survive hydration rather than flash to the default.
133
+ * 5. The consumer's defaults, which is the site's decision, not the reader's.
134
+ *
135
+ * Every step names its own source, so the pack and the mode always come from
136
+ * the same one. That is the whole-vs-half property, and it is structural rather
137
+ * than a check.
138
+ */
139
+ export declare function resolveTheme({ stored, legacy, documentPack, documentDark, defaultPack, defaultMode, }: ThemeResolutionInput): ThemeResolution;
140
+ /**
141
+ * The first key in `LEGACY_MODE_STORAGE_KEYS` that holds a recoverable mode.
142
+ *
143
+ * Returned with the key that held it, because the recovery has to retire that
144
+ * key and no other. Order is the list's order, and the list is short enough
145
+ * that the loop is not worth a comment about its cost.
146
+ */
147
+ export declare function readLegacyMode(read: (key: string) => string | null): {
148
+ key: string;
149
+ mode: Mode;
150
+ } | null;
151
+ /**
152
+ * Turns a pack and a mode into the markup attributes that express them.
153
+ *
154
+ * Returns attributes, never CSS values: a Server Component spreads the result
155
+ * onto `<html>` and gets the declarative form with no client runtime. `default`
156
+ * is expressed by omitting `data-pack`; light is expressed by omitting `dark`.
157
+ *
158
+ * `mode` is optional because a server cannot know the reader's mode, and a
159
+ * required one is that impossibility written into the type: the only way to ask
160
+ * for a boundary with no mode class of its own would be to pass `'light'` as a
161
+ * guess, and the guess is wrong for half of them. Omitting it is the honest
162
+ * spelling of "wear the mode of the element carrying `.dark`", which is what the
163
+ * token build's descendant selector implements. `pack` stays required, because an
164
+ * element carrying neither axis is not a theme boundary.
165
+ */
166
+ export declare function themeAttributes({ pack, mode, }: {
167
+ pack: PackId;
168
+ mode?: Mode;
169
+ }): {
170
+ 'data-pack'?: string;
171
+ className?: string;
172
+ };
173
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theming/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,KAAK,mEAAoE,CAAA;AACtF,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3C,eAAO,MAAM,KAAK,4BAA6B,CAAA;AAC/C,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzC,eAAO,MAAM,cAAc,cAAc,CAAA;AACzC,eAAO,MAAM,mBAAmB,gBAAgB,CAAA;AAEhD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAA;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa,kEAAmE,CAAA;AAC7F,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB,+BAAgC,CAAA;AAUrE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAgBxF;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,iEAAiE;IACjE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,IAAI,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,iEAAiE;IACjE,MAAM,EAAE,WAAW,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,EAAE,oBAAoB,GAAG,eAAe,CAoBxC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GACnC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAMpC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAK/C"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * The Prism theming vocabulary: pack and mode are two independent axes.
3
+ *
4
+ * `data-pack` selects the palette and `.dark` selects the mode; neither implies
5
+ * the other (ticket 07). `default` is the selectable neutral pack id, and its
6
+ * markup is the absence of the attribute. Everything here is pure and
7
+ * isomorphic so a Server Component can render the declarative form without a
8
+ * client runtime. There is no theme factory and no override object: the pack
9
+ * and mode are the whole API.
10
+ */
11
+ export const PACKS = ['default', 'blush', 'mint', 'lavender', 'sky', 'peach'];
12
+ export const MODES = ['light', 'dark'];
13
+ export const PACK_ATTRIBUTE = 'data-pack';
14
+ export const DEFAULT_STORAGE_KEY = 'prism-theme';
15
+ /**
16
+ * The root attribute that records where the active pack and mode came from.
17
+ *
18
+ * This is a contract, not markup. The boot script is its only writer, and the
19
+ * provider never touches it, because two writers would make the recorded origin
20
+ * a race rather than a record. The value is always one of `THEME_ORIGINS` and is
21
+ * written on every path the script reaches, including a stored value that could
22
+ * not be parsed: an absent attribute cannot be told from an unread one, and a
23
+ * theme that fell through to the default is exactly the case a reader needs to
24
+ * see named.
25
+ *
26
+ * It is not `data-theme`, which `MIGRATION.md` retires. It carries the
27
+ * provenance of a resolution, never a pack.
28
+ */
29
+ export const THEME_ORIGIN_ATTRIBUTE = 'data-theme-origin';
30
+ /**
31
+ * The closed set the boot script may write to `THEME_ORIGIN_ATTRIBUTE`.
32
+ *
33
+ * - `stored` a valid `{ pack, mode }` pair was in the key this line writes.
34
+ * - `legacy` the key was empty and a key this line no longer writes held a
35
+ * recoverable mode, so that decision was taken and carried over.
36
+ * - `unparsed` the key held a value that is not a pair. The theme fell
37
+ * through whole, and the value was left in place, because it is
38
+ * the only record that this reader ever chose anything.
39
+ * - `document` the key was empty and the root element's own attributes
40
+ * supplied the theme.
41
+ * - `default` neither did, so the consumer's own defaults apply.
42
+ *
43
+ * `legacy` and `unparsed` are why the set is five and not three: a
44
+ * three-value set records that the theme came from somewhere but cannot
45
+ * distinguish "never chose" from "chose, and the value no longer parses", which
46
+ * is the one distinction a storage migration has to be retired against.
47
+ */
48
+ export const THEME_ORIGINS = ['stored', 'legacy', 'document', 'default', 'unparsed'];
49
+ /**
50
+ * Keys earlier lines of this package wrote and this line does not.
51
+ *
52
+ * `prism-theme-mode` was the shared chrome key: the mode setter wrote it, and
53
+ * only the mode setter, as a bare `'light'` or `'dark'` string, because the pack
54
+ * was fixed per site and the mode was the one choice that travelled across
55
+ * sites. The value is not a `{ pack, mode }` pair and can never collide with one
56
+ * this line writes, so reading it costs nothing and recovers a real decision.
57
+ *
58
+ * The list is the migration's own expiry. Every key in it is a clause the boot
59
+ * script carries and prices, and the migration is retired by deleting the last
60
+ * entry: the clause's live population is then empty, the gate reports it, and
61
+ * the byte ceiling's generation allowance falls to zero with it. Nothing here
62
+ * is bounded by a date or a version number.
63
+ */
64
+ export const LEGACY_MODE_STORAGE_KEYS = ['prism-theme-mode'];
65
+ function isPack(value) {
66
+ return typeof value === 'string' && PACKS.includes(value);
67
+ }
68
+ function isMode(value) {
69
+ return typeof value === 'string' && MODES.includes(value);
70
+ }
71
+ /**
72
+ * Reads a persisted `{ pack, mode }` object.
73
+ *
74
+ * Returns `null` for anything that is not a valid pair, so a corrupt or
75
+ * superseded stored value falls back to the defaults rather than to a pack that
76
+ * does not exist. Parsing is deliberately strict: the store is owned by
77
+ * `PrismProvider`, which always writes this exact shape.
78
+ */
79
+ export function parseStoredTheme(raw) {
80
+ if (!raw)
81
+ return null;
82
+ let parsed;
83
+ try {
84
+ parsed = JSON.parse(raw);
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ if (typeof parsed !== 'object' || parsed === null)
90
+ return null;
91
+ const { pack, mode } = parsed;
92
+ if (!isPack(pack) || !isMode(mode))
93
+ return null;
94
+ return { pack, mode };
95
+ }
96
+ /**
97
+ * The one resolution rule. `PrismProvider` calls it, and the boot script
98
+ * implements it as a string, and the equivalence gate runs both over one table
99
+ * because the string cannot import it.
100
+ *
101
+ * A serialised function is not a way to share it. The build minifies, a renamed
102
+ * identifier inside the script's own `try` would throw there and the catch
103
+ * would fail open, leaving a silent no-op on every page; so the honest shape is
104
+ * one implementation plus a gate that can fail, not two copies that look
105
+ * aligned.
106
+ *
107
+ * The order, and why each step is where it is:
108
+ *
109
+ * 1. A valid pair in the key this line writes wins outright. A decision
110
+ * recorded as a pair is a decision, and it is the only source that names
111
+ * both axes at once.
112
+ * 2. A value that is present but is not a pair falls through WHOLE. It is not
113
+ * repaired field by field, because a half-applied pair is a theme neither
114
+ * the reader nor the server chose, and because repairing it would make the
115
+ * two readers disagree about what "a valid mode" means. The value is also
116
+ * not cleared: it is the only record that this reader ever chose, and the
117
+ * origin is `unparsed` so a reader can see that it is there and unusable.
118
+ * 3. Only an absent key reaches the keys this line no longer writes. A present
119
+ * but unusable value is a record of an intent and outranks an older one.
120
+ * 4. The root element's own attributes, which is what a server rendered and
121
+ * what must survive hydration rather than flash to the default.
122
+ * 5. The consumer's defaults, which is the site's decision, not the reader's.
123
+ *
124
+ * Every step names its own source, so the pack and the mode always come from
125
+ * the same one. That is the whole-vs-half property, and it is structural rather
126
+ * than a check.
127
+ */
128
+ export function resolveTheme({ stored, legacy, documentPack, documentDark, defaultPack, defaultMode, }) {
129
+ const pair = parseStoredTheme(stored);
130
+ if (pair)
131
+ return { pack: pair.pack, mode: pair.mode, origin: 'stored' };
132
+ const renderedPack = isPack(documentPack) ? documentPack : null;
133
+ const renderedMode = documentDark ? 'dark' : null;
134
+ const fromDocument = () => ({
135
+ pack: renderedPack ?? defaultPack,
136
+ mode: renderedMode ?? defaultMode,
137
+ origin: 'document',
138
+ });
139
+ // A value the store holds with content, and `parseStoredTheme` did not accept.
140
+ const held = stored !== null && stored !== '';
141
+ if (held)
142
+ return { ...fromDocument(), origin: 'unparsed' };
143
+ if (isMode(legacy))
144
+ return { pack: defaultPack, mode: legacy, origin: 'legacy' };
145
+ if (renderedPack !== null || renderedMode !== null)
146
+ return fromDocument();
147
+ return { pack: defaultPack, mode: defaultMode, origin: 'default' };
148
+ }
149
+ /**
150
+ * The first key in `LEGACY_MODE_STORAGE_KEYS` that holds a recoverable mode.
151
+ *
152
+ * Returned with the key that held it, because the recovery has to retire that
153
+ * key and no other. Order is the list's order, and the list is short enough
154
+ * that the loop is not worth a comment about its cost.
155
+ */
156
+ export function readLegacyMode(read) {
157
+ for (const key of LEGACY_MODE_STORAGE_KEYS) {
158
+ const value = read(key);
159
+ if (isMode(value))
160
+ return { key, mode: value };
161
+ }
162
+ return null;
163
+ }
164
+ /**
165
+ * Turns a pack and a mode into the markup attributes that express them.
166
+ *
167
+ * Returns attributes, never CSS values: a Server Component spreads the result
168
+ * onto `<html>` and gets the declarative form with no client runtime. `default`
169
+ * is expressed by omitting `data-pack`; light is expressed by omitting `dark`.
170
+ *
171
+ * `mode` is optional because a server cannot know the reader's mode, and a
172
+ * required one is that impossibility written into the type: the only way to ask
173
+ * for a boundary with no mode class of its own would be to pass `'light'` as a
174
+ * guess, and the guess is wrong for half of them. Omitting it is the honest
175
+ * spelling of "wear the mode of the element carrying `.dark`", which is what the
176
+ * token build's descendant selector implements. `pack` stays required, because an
177
+ * element carrying neither axis is not a theme boundary.
178
+ */
179
+ export function themeAttributes({ pack, mode, }) {
180
+ const attributes = {};
181
+ if (pack !== 'default')
182
+ attributes[PACK_ATTRIBUTE] = pack;
183
+ if (mode === 'dark')
184
+ attributes.className = 'dark';
185
+ return attributes;
186
+ }
package/package.json CHANGED
@@ -1,48 +1,119 @@
1
1
  {
2
2
  "name": "@nanisoft/prism-ui",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
- "description": "Component + block source of truth, published as a shadcn registry.",
5
+ "description": "Prism's React component, block and page library.",
6
6
  "license": "MIT",
7
7
  "author": "NaniSoft",
8
8
  "homepage": "https://prism.nanisoft.com",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/NaniSoft/prism.git",
11
+ "url": "git+https://github.com/NaniSoft/prism.git",
12
12
  "directory": "packages/ui"
13
13
  },
14
+ "sideEffects": [
15
+ "**/*.css"
16
+ ],
17
+ "types": "./dist/index.d.ts",
14
18
  "exports": {
15
- "./components/*": "./src/components/*.tsx",
16
- "./registry.json": "./registry.json",
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./provider": {
24
+ "types": "./dist/provider/index.d.ts",
25
+ "default": "./dist/provider/index.js"
26
+ },
27
+ "./components": {
28
+ "types": "./dist/components/index.d.ts",
29
+ "default": "./dist/components/index.js"
30
+ },
31
+ "./components/*": {
32
+ "types": "./dist/components/ui/*.d.ts",
33
+ "default": "./dist/components/ui/*.js"
34
+ },
35
+ "./blocks": {
36
+ "types": "./dist/blocks/index.d.ts",
37
+ "default": "./dist/blocks/index.js"
38
+ },
39
+ "./blocks/*": {
40
+ "types": "./dist/blocks/*/index.d.ts",
41
+ "default": "./dist/blocks/*/index.js"
42
+ },
43
+ "./pages": {
44
+ "types": "./dist/pages/index.d.ts",
45
+ "default": "./dist/pages/index.js"
46
+ },
47
+ "./pages/*": {
48
+ "types": "./dist/pages/*/index.d.ts",
49
+ "default": "./dist/pages/*/index.js"
50
+ },
51
+ "./theming": {
52
+ "types": "./dist/theming/index.d.ts",
53
+ "default": "./dist/theming/index.js"
54
+ },
55
+ "./catalog": {
56
+ "types": "./dist/catalog.d.ts",
57
+ "default": "./dist/catalog.js"
58
+ },
59
+ "./styles.css": "./dist/styles.css",
17
60
  "./package.json": "./package.json"
18
61
  },
19
62
  "files": [
20
- "src",
21
- "registry.json",
22
- "public/r",
23
- "components.json"
63
+ "dist",
64
+ "THIRD-PARTY-NOTICES.md"
24
65
  ],
66
+ "engines": {
67
+ "node": ">=22.14.0"
68
+ },
25
69
  "publishConfig": {
26
70
  "access": "public"
27
71
  },
28
- "scripts": {
29
- "sync": "node scripts/sync-registry.mjs",
30
- "validate": "node scripts/validate-registry.mjs",
31
- "build": "pnpm sync && pnpm validate && shadcn build",
32
- "typecheck": "tsc --noEmit"
33
- },
34
72
  "dependencies": {
35
73
  "@base-ui/react": "^1.0.0",
36
74
  "class-variance-authority": "^0.7.1",
37
75
  "clsx": "^2.1.1",
38
76
  "lucide-react": "^0.545.0",
39
- "tailwind-merge": "^3.3.1"
77
+ "tailwind-merge": "^3.3.1",
78
+ "@nanisoft/prism-tokens": "0.6.0"
40
79
  },
41
80
  "devDependencies": {
81
+ "@tailwindcss/postcss": "^4.3.3",
82
+ "@testing-library/dom": "^10.4.1",
83
+ "@testing-library/jest-dom": "^6.9.1",
84
+ "@testing-library/react": "^16.3.0",
85
+ "@testing-library/user-event": "^14.6.1",
42
86
  "@types/node": "^22.0.0",
43
87
  "@types/react": "^19.2.0",
44
88
  "@types/react-dom": "^19.2.0",
89
+ "axe-core": "^4.13.0",
90
+ "esbuild": "^0.28.0",
91
+ "jsdom": "^26.1.0",
92
+ "postcss": "^8.5.28",
93
+ "react": "^19.2.0",
94
+ "react-dom": "^19.2.0",
45
95
  "shadcn": "^3.6.0",
46
- "typescript": "^5.7.0"
96
+ "tailwindcss": "^4.3.3",
97
+ "typescript": "^5.7.0",
98
+ "vitest": "^3.2.4"
99
+ },
100
+ "scripts": {
101
+ "sync": "node scripts/sync-registry.mjs",
102
+ "validate": "node scripts/validate-registry.mjs",
103
+ "build": "node scripts/build.mjs && pnpm sync && pnpm validate && node scripts/check-catalogue.mjs && shadcn build && node scripts/check-surface.mjs && node scripts/check-focus-indicators.mjs && node scripts/check-item-docs.mjs && node scripts/check-block-copy.mjs && node scripts/check-item-category.mjs && node scripts/check-block-imports.mjs",
104
+ "check": "node scripts/validate-registry.mjs && node scripts/check-catalogue.mjs && node scripts/check-surface.mjs && node scripts/check-focus-indicators.mjs && node scripts/check-pack-boundary.mjs && node scripts/check-vector-ink.mjs && node scripts/check-client-budget.mjs && node scripts/check-theme-resolution.mjs && node scripts/check-boot-budget.mjs && node scripts/check-item-docs.mjs && node scripts/check-block-copy.mjs && node scripts/check-item-category.mjs && node scripts/check-block-imports.mjs",
105
+ "check:vector-ink": "node scripts/check-vector-ink.mjs",
106
+ "check:client-budget": "node scripts/check-client-budget.mjs",
107
+ "check:pack-boundary": "node scripts/check-pack-boundary.mjs",
108
+ "check:theme-resolution": "node scripts/check-theme-resolution.mjs",
109
+ "check:boot-budget": "node scripts/check-boot-budget.mjs",
110
+ "check:catalogue": "node scripts/check-catalogue.mjs",
111
+ "check:focus-indicators": "node scripts/check-focus-indicators.mjs",
112
+ "check:item-docs": "node scripts/check-item-docs.mjs",
113
+ "check:block-copy": "node scripts/check-block-copy.mjs",
114
+ "check:item-category": "node scripts/check-item-category.mjs",
115
+ "check:block-imports": "node scripts/check-block-imports.mjs",
116
+ "test": "vitest run",
117
+ "typecheck": "tsc --noEmit"
47
118
  }
48
- }
119
+ }
package/components.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "base-nova",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "src/app/globals.css",
9
- "baseColor": "neutral",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "iconLibrary": "lucide",
14
- "aliases": {
15
- "components": "@/components",
16
- "utils": "@/lib/utils",
17
- "ui": "@/components/ui",
18
- "lib": "@/lib",
19
- "hooks": "@/hooks"
20
- }
21
- }
@@ -1,26 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
- "name": "badge",
4
- "title": "Badge",
5
- "description": "Shared badge primitive. Installed automatically as a dependency of any block that uses it.",
6
- "dependencies": [
7
- "class-variance-authority",
8
- "clsx",
9
- "tailwind-merge"
10
- ],
11
- "files": [
12
- {
13
- "path": "src/components/ui/badge.tsx",
14
- "content": "import { cva, type VariantProps } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst badgeVariants = cva(\n 'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-md border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-colors',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground border-transparent',\n secondary: 'bg-secondary text-secondary-foreground border-transparent',\n destructive: 'bg-destructive text-destructive-foreground border-transparent',\n success: 'bg-success text-success-foreground border-transparent',\n warning: 'bg-warning text-warning-foreground border-transparent',\n outline: 'text-foreground border-border',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n)\n\nfunction Badge({\n className,\n variant,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof badgeVariants>) {\n return (\n <span\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n",
15
- "type": "registry:component",
16
- "target": "components/ui/badge.tsx"
17
- },
18
- {
19
- "path": "src/lib/utils.ts",
20
- "content": "import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
21
- "type": "registry:lib",
22
- "target": "lib/utils.ts"
23
- }
24
- ],
25
- "type": "registry:component"
26
- }
@@ -1,26 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
- "name": "button",
4
- "title": "Button",
5
- "description": "Shared button primitive. Installed automatically as a dependency of any block that uses it.",
6
- "dependencies": [
7
- "class-variance-authority",
8
- "clsx",
9
- "tailwind-merge"
10
- ],
11
- "files": [
12
- {
13
- "path": "src/components/ui/button.tsx",
14
- "content": "import { cva, type VariantProps } from 'class-variance-authority'\nimport type { ComponentProps } from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst buttonVariants = cva(\n // The focus ring is `ring-ring` at full strength, not shadcn's stock\n // `focus-visible:ring-ring/50`. The token build pins `--ring` to a step that\n // clears 3:1 against the surface, and half alpha throws that away: 50% of this\n // ring composites to between 1.14:1 and 2.74:1 against every surface in all\n // six themes and clears 3:1 in none of them, which fails WCAG 1.4.11 on the one\n // indicator a keyboard user has. The stock value is kept here deliberately as a\n // deviation from upstream: a consumer's button must not fail the threshold the\n // ring exists to meet.\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium outline-none transition-[color,box-shadow,background-color] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring focus-visible:ring-[3px] aria-invalid:ring-destructive/20 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90',\n outline:\n 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n // `primary` is a surface token, not a text token: in the pastel themes it\n // compiles to a light tint (e.g. #ec88a0) that fails 4.5:1 on the page\n // background. Link text uses the foreground and keeps the underline as its\n // affordance, so emphasis comes from weight rather than a failing colour.\n link: 'text-foreground underline-offset-4 hover:underline',\n },\n // Touch targets are enlarged by input method, not by viewport. The\n // metrics below are the designed desktop sizes and stay untouched for\n // mouse and trackpad; only a coarse pointer — finger or stylus — gets\n // the 44px iOS/Android HIG target. `pointer-coarse:` compiles to\n // `@media (pointer: coarse)` inside `@layer utilities`, which lands\n // after the base utility in the cascade, so it wins without needing\n // `!important` or a specificity fight.\n //\n // `min-w-11` is what makes the second axis safe: an icon-only `default`\n // is `size-4` plus `px-3` = 40px wide and an icon-only `sm` is `size-4`\n // plus `px-2.5` = 36px, so growing the height alone would still leave\n // both under 44px across. The coarse padding step on `default` lifts the\n // common cases clear of the floor outright, and `min-w-11` backstops\n // whatever content a consumer passes.\n size: {\n default:\n 'h-9 px-4 py-2 has-[>svg]:px-3 pointer-coarse:h-11 pointer-coarse:min-w-11 pointer-coarse:px-5 pointer-coarse:has-[>svg]:px-4',\n sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 pointer-coarse:h-11 pointer-coarse:min-w-11',\n lg: 'h-10 rounded-md px-6 has-[>svg]:px-4 pointer-coarse:h-11',\n icon: 'size-9 pointer-coarse:size-11',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nfunction Button({\n className,\n variant,\n size,\n ...props\n}: ComponentProps<'button'> & VariantProps<typeof buttonVariants>) {\n return (\n <button\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n",
15
- "type": "registry:component",
16
- "target": "components/ui/button.tsx"
17
- },
18
- {
19
- "path": "src/lib/utils.ts",
20
- "content": "import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
21
- "type": "registry:lib",
22
- "target": "lib/utils.ts"
23
- }
24
- ],
25
- "type": "registry:component"
26
- }
@@ -1,25 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
- "name": "card",
4
- "title": "Card",
5
- "description": "Shared card primitive. Installed automatically as a dependency of any block that uses it.",
6
- "dependencies": [
7
- "clsx",
8
- "tailwind-merge"
9
- ],
10
- "files": [
11
- {
12
- "path": "src/components/ui/card.tsx",
13
- "content": "import type { ComponentProps } from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Card({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n 'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n '@container/card-header grid auto-rows-min items-start gap-1.5 px-6',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('font-semibold leading-none', className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('px-6', className)} {...props} />\n}\n\nfunction CardFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn('flex items-center px-6', className)}\n {...props}\n />\n )\n}\n\nexport { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter }\n",
14
- "type": "registry:component",
15
- "target": "components/ui/card.tsx"
16
- },
17
- {
18
- "path": "src/lib/utils.ts",
19
- "content": "import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
20
- "type": "registry:lib",
21
- "target": "lib/utils.ts"
22
- }
23
- ],
24
- "type": "registry:component"
25
- }