@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,38 @@
1
+ import { type ReactNode } from 'react';
2
+ export type AppShellCrumb = {
3
+ label: ReactNode;
4
+ /** Renders a native anchor. Omit on the current, final step. */
5
+ href?: string;
6
+ };
7
+ export type AppShell01Props = {
8
+ /**
9
+ * The navigation rendered in the desktop rail and in the mobile sheet. Pass
10
+ * nodes rather than a route table: the block never imports a router.
11
+ */
12
+ navigation: ReactNode;
13
+ /** The accessible name for the navigation regions and the sheet trigger. */
14
+ navigationLabel: string;
15
+ /** The brand or product mark at the top of the rail and the sheet. */
16
+ brand?: ReactNode;
17
+ /** The trail shown in the top bar. */
18
+ breadcrumbs?: AppShellCrumb[];
19
+ /** Actions at the end of the top bar, e.g. an account menu. */
20
+ actions?: ReactNode;
21
+ /** A slot above the navigation, e.g. a workspace switcher. */
22
+ railHeader?: ReactNode;
23
+ /** A slot below the navigation, e.g. a user menu. */
24
+ railFooter?: ReactNode;
25
+ children: ReactNode;
26
+ };
27
+ /**
28
+ * An application shell.
29
+ *
30
+ * It owns the frame every application screen repeats: a fixed rail from the
31
+ * `lg` breakpoint up, a top bar with a breadcrumb trail and actions, and a
32
+ * left-anchored Dialog sheet that carries the same navigation on narrow
33
+ * screens. The navigation and the content are slots, so the app keeps its own
34
+ * links, router and data. The block fetches nothing and imports no router.
35
+ */
36
+ export declare function AppShell01({ navigation, navigationLabel, brand, breadcrumbs, actions, railHeader, railFooter, children, }: AppShell01Props): import("react").JSX.Element;
37
+ export default AppShell01;
38
+ //# sourceMappingURL=app-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../../src/blocks/app-shell-01/app-shell.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAc1D,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,SAAS,CAAA;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,UAAU,EAAE,SAAS,CAAA;IACrB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,CAAA;IACvB,sEAAsE;IACtE,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,sCAAsC;IACtC,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;IAC7B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,qDAAqD;IACrD,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,eAAe,EACf,KAAK,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,+BA4EjB;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Menu } from 'lucide-react';
4
+ import { Fragment, useState } from 'react';
5
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from '../../components/ui/breadcrumb';
6
+ import { Button } from '../../components/ui/button';
7
+ import { Dialog, DialogContent, DialogTitle } from '../../components/ui/dialog';
8
+ import { Separator } from '../../components/ui/separator';
9
+ /**
10
+ * An application shell.
11
+ *
12
+ * It owns the frame every application screen repeats: a fixed rail from the
13
+ * `lg` breakpoint up, a top bar with a breadcrumb trail and actions, and a
14
+ * left-anchored Dialog sheet that carries the same navigation on narrow
15
+ * screens. The navigation and the content are slots, so the app keeps its own
16
+ * links, router and data. The block fetches nothing and imports no router.
17
+ */
18
+ export function AppShell01({ navigation, navigationLabel, brand, breadcrumbs, actions, railHeader, railFooter, children, }) {
19
+ const [navOpen, setNavOpen] = useState(false);
20
+ return (_jsxs("div", { className: "bg-background text-foreground flex min-h-svh w-full", children: [_jsxs("aside", { className: "border-border hidden w-64 shrink-0 flex-col border-r lg:flex", children: [brand ? _jsx("div", { className: "flex h-14 items-center px-4", children: brand }) : null, _jsx(Separator, {}), railHeader ? _jsx("div", { className: "p-4", children: railHeader }) : null, _jsx("nav", { "aria-label": navigationLabel, className: "flex-1 overflow-y-auto p-4", children: navigation }), railFooter ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { className: "p-4", children: railFooter })] })) : null] }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsxs("header", { className: "border-border flex h-14 items-center gap-3 border-b px-4", children: [_jsxs(Dialog, { open: navOpen, onOpenChange: setNavOpen, children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "lg:hidden", "aria-label": navigationLabel, onClick: () => setNavOpen(true), children: _jsx(Menu, { className: "size-5" }) }), _jsxs(DialogContent, { side: "left", className: "w-72 gap-0 p-0", children: [_jsx(DialogTitle, { className: "sr-only", children: navigationLabel }), _jsxs("div", { className: "flex h-full flex-col p-4", children: [brand ? _jsx("div", { className: "mb-4", children: brand }) : null, railHeader ? _jsx("div", { className: "mb-4", children: railHeader }) : null, _jsx("nav", { "aria-label": navigationLabel, className: "flex-1 overflow-y-auto", children: navigation }), railFooter ? _jsx("div", { className: "mt-4", children: railFooter }) : null] })] })] }), breadcrumbs?.length ? (_jsx(Breadcrumb, { children: _jsx(BreadcrumbList, { children: breadcrumbs.map((crumb, index) => {
21
+ const last = index === breadcrumbs.length - 1;
22
+ return (
23
+ // Positional, for the same reason as the other blocks.
24
+ _jsxs(Fragment, { children: [index > 0 ? _jsx(BreadcrumbSeparator, {}) : null, _jsx(BreadcrumbItem, { children: last || !crumb.href ? (_jsx(BreadcrumbPage, { children: crumb.label })) : (_jsx(BreadcrumbLink, { href: crumb.href, children: crumb.label })) })] }, index));
25
+ }) }) })) : null, _jsx("div", { className: "ml-auto flex items-center gap-2", children: actions })] }), _jsx("main", { className: "flex-1 p-4 lg:p-6", children: children })] })] }));
26
+ }
27
+ export default AppShell01;
@@ -0,0 +1,3 @@
1
+ export { AppShell01, default } from './app-shell';
2
+ export type { AppShell01Props, AppShellCrumb } from './app-shell';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/app-shell-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1 @@
1
+ export { AppShell01, default } from './app-shell';
@@ -0,0 +1,52 @@
1
+ import type { FormEvent, ReactNode } from 'react';
2
+ export type AuthFormField = {
3
+ id: string;
4
+ label: string;
5
+ type?: 'text' | 'email' | 'password';
6
+ placeholder?: string;
7
+ autoComplete?: string;
8
+ value?: string;
9
+ defaultValue?: string;
10
+ onChange?: (value: string) => void;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ description?: string;
14
+ };
15
+ export type AuthFormRemember = {
16
+ id: string;
17
+ label: string;
18
+ checked?: boolean;
19
+ defaultChecked?: boolean;
20
+ onCheckedChange?: (checked: boolean) => void;
21
+ disabled?: boolean;
22
+ };
23
+ export type AuthForm01Props = {
24
+ title: string;
25
+ description?: string;
26
+ /** The credential fields, in order. */
27
+ fields: AuthFormField[];
28
+ /** An error message shown above the fields and marked on each control. */
29
+ error?: string;
30
+ /** A remember-me row under the fields. */
31
+ remember?: AuthFormRemember;
32
+ /** The submit button label. */
33
+ submitLabel: string;
34
+ /** The label shown while `pending` is true. Falls back to `submitLabel`. */
35
+ pendingLabel?: string;
36
+ /** Disables the submit control while a request is in flight. */
37
+ pending?: boolean;
38
+ onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
39
+ /** A row under the submit button, e.g. a link to another screen. */
40
+ footer?: ReactNode;
41
+ };
42
+ /**
43
+ * A sign-in card.
44
+ *
45
+ * The block renders the card, the labelled fields, the remember row and the
46
+ * submit control. It owns no credentials and no request: every field value and
47
+ * the submit handler come from the consumer, and the error line is a prop so
48
+ * the consumer's validation decides when it appears. Every string is a prop.
49
+ */
50
+ export declare function AuthForm01({ title, description, fields, error, remember, submitLabel, pendingLabel, pending, onSubmit, footer, }: AuthForm01Props): import("react").JSX.Element;
51
+ export default AuthForm01;
52
+ //# sourceMappingURL=auth-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-form.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/auth-form.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAqBjD,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAA;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IACtD,oEAAoE;IACpE,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,MAAM,EACN,KAAK,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,OAAe,EACf,QAAQ,EACR,MAAM,GACP,EAAE,eAAe,+BAmEjB;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CircleAlert } from 'lucide-react';
4
+ import { Alert, AlertDescription } from '../../components/ui/alert';
5
+ import { Button } from '../../components/ui/button';
6
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '../../components/ui/card';
7
+ import { Checkbox } from '../../components/ui/checkbox';
8
+ import { Field, FieldDescription, FieldGroup, FieldLabel, } from '../../components/ui/field';
9
+ import { Input } from '../../components/ui/input';
10
+ /**
11
+ * A sign-in card.
12
+ *
13
+ * The block renders the card, the labelled fields, the remember row and the
14
+ * submit control. It owns no credentials and no request: every field value and
15
+ * the submit handler come from the consumer, and the error line is a prop so
16
+ * the consumer's validation decides when it appears. Every string is a prop.
17
+ */
18
+ export function AuthForm01({ title, description, fields, error, remember, submitLabel, pendingLabel, pending = false, onSubmit, footer, }) {
19
+ return (_jsx("form", { onSubmit: onSubmit, className: "w-full", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: title }), description ? _jsx(CardDescription, { children: description }) : null] }), _jsxs(CardContent, { className: "flex flex-col gap-4", children: [error ? (_jsxs(Alert, { variant: "destructive", children: [_jsx(CircleAlert, {}), _jsx(AlertDescription, { children: error })] })) : null, _jsx(FieldGroup, { children: fields.map((field) => (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: field.id, children: field.label }), _jsx(Input, { id: field.id, type: field.type ?? 'text', placeholder: field.placeholder, autoComplete: field.autoComplete, value: field.value, defaultValue: field.defaultValue, onChange: field.onChange
20
+ ? (event) => field.onChange?.(event.target.value)
21
+ : undefined, required: field.required, disabled: field.disabled, "aria-invalid": error ? true : undefined }), field.description ? (_jsx(FieldDescription, { children: field.description })) : null] }, field.id))) }), remember ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: remember.id, checked: remember.checked, defaultChecked: remember.defaultChecked, onCheckedChange: remember.onCheckedChange, disabled: remember.disabled }), _jsx(FieldLabel, { htmlFor: remember.id, children: remember.label })] })) : null] }), _jsxs(CardFooter, { className: "flex-col gap-3", children: [_jsx(Button, { type: "submit", className: "w-full", disabled: pending, children: pending ? (pendingLabel ?? submitLabel) : submitLabel }), footer] })] }) }));
22
+ }
23
+ export default AuthForm01;
@@ -0,0 +1,3 @@
1
+ export { AuthForm01, default } from './auth-form';
2
+ export type { AuthForm01Props, AuthFormField, AuthFormRemember } from './auth-form';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1 @@
1
+ export { AuthForm01, default } from './auth-form';
@@ -0,0 +1,83 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type HeadingLevel } from '../../components/ui/section';
3
+ /**
4
+ * One closing action.
5
+ *
6
+ * The destination is required rather than optional, and that is the whole point
7
+ * of the type: `href` was already declared and never rendered, so the type said
8
+ * the control could navigate while the markup produced a `<button>` with no
9
+ * handler. An action with no handler navigates nothing, so there is no arm of
10
+ * this union that omits the destination and no optional one either. A caller
11
+ * whose control is not a link at all uses `Cta01`'s `actionSlot`.
12
+ */
13
+ export type Cta01Action = {
14
+ label: string;
15
+ /** Where the action goes. Rendered as a native anchor's `href`. */
16
+ href: string;
17
+ /**
18
+ * Opens the destination in a new browsing context, which defaults the link
19
+ * relationship to `noopener noreferrer`. Declared rather than inferred: Prism
20
+ * does not parse the destination, and a cross-origin URL is not by itself a
21
+ * reason to open a tab.
22
+ */
23
+ newTab?: boolean;
24
+ variant?: 'default' | 'secondary' | 'outline';
25
+ };
26
+ export type Cta01Props = {
27
+ title: string;
28
+ description?: string;
29
+ /**
30
+ * The one action this band carries. Omit it for a closing statement that asks
31
+ * for nothing, and use `actionSlot` for a control that is not a call to
32
+ * action.
33
+ */
34
+ action?: Cta01Action;
35
+ /**
36
+ * A slot for a control the block does not own, such as a client router's link
37
+ * or a menu. This is what a call to action with no destination becomes: a slot
38
+ * the consumer fills, rather than a control the block renders and cannot make
39
+ * work.
40
+ */
41
+ actionSlot?: ReactNode;
42
+ /**
43
+ * The second action, rendered beside the first at outline weight. It is a prop
44
+ * rather than a second `action` array because `action` is the one this Block
45
+ * styles as the closing ask and a second action in the same weight is two
46
+ * closing asks; a reader who has to choose between two equally-weighted
47
+ * buttons has been given a menu where a page wanted a decision.
48
+ *
49
+ * Three of the four NaniSoft sites render two actions in their closing band
50
+ * and all four do, and all four wrote the pair by hand, so each one re-decided
51
+ * the gap, the order and the weight between them.
52
+ */
53
+ secondaryAction?: Cta01Action;
54
+ /**
55
+ * The line under the actions: the footnote, the caveat, the sentence that
56
+ * qualifies the ask. Three of the four sites render one, and each wrote it by
57
+ * hand.
58
+ *
59
+ * A `ReactNode` rather than a string because the honest line is sometimes not
60
+ * one sentence: three of the four carry a link inside it, and a string prop
61
+ * would force a caller to compose a paragraph to say "this is in development,
62
+ * here is where to watch it".
63
+ */
64
+ note?: ReactNode;
65
+ /** Heading level for the headline. See `HeadingLevel`. */
66
+ headingLevel?: HeadingLevel;
67
+ };
68
+ /**
69
+ * A closing call to action on a filled primary surface.
70
+ *
71
+ * The copy and the action are props. It previously shipped the catalog's own
72
+ * pitch ("Start with one block, keep the tokens") and a hardcoded "Browse the
73
+ * catalog" button, both of which described the library rather than whatever
74
+ * product installed the block.
75
+ *
76
+ * The action renders a `CtaLink`, so it is a native anchor announced as a link
77
+ * rather than a button announced as a command, and its destination is a required
78
+ * prop. The only rendered change from the button this replaces is the element and
79
+ * the `href` it now carries.
80
+ */
81
+ export declare function Cta01({ title, description, action, actionSlot, secondaryAction, note, headingLevel, }: Cta01Props): import("react").JSX.Element;
82
+ export default Cta01;
83
+ //# sourceMappingURL=cta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cta.d.ts","sourceRoot":"","sources":["../../../src/blocks/cta-01/cta.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAExE;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAA;CAC9C,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,WAAW,CAAA;IAC7B;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,eAAe,EACf,IAAI,EACJ,YAAmB,GACpB,EAAE,UAAU,+BAyDZ;AAED,eAAe,KAAK,CAAA"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ArrowRight } from 'lucide-react';
3
+ import { CtaLink } from '../../components/ui/cta-link';
4
+ import { Section } from '../../components/ui/section';
5
+ /**
6
+ * A closing call to action on a filled primary surface.
7
+ *
8
+ * The copy and the action are props. It previously shipped the catalog's own
9
+ * pitch ("Start with one block, keep the tokens") and a hardcoded "Browse the
10
+ * catalog" button, both of which described the library rather than whatever
11
+ * product installed the block.
12
+ *
13
+ * The action renders a `CtaLink`, so it is a native anchor announced as a link
14
+ * rather than a button announced as a command, and its destination is a required
15
+ * prop. The only rendered change from the button this replaces is the element and
16
+ * the `href` it now carries.
17
+ */
18
+ export function Cta01({ title, description, action, actionSlot, secondaryAction, note, headingLevel = 'h2', }) {
19
+ /*
20
+ * The same mechanism `SectionHeading` uses for its own `as` prop, which this
21
+ * block cannot borrow: its copy sits on a filled `bg-primary` surface, where
22
+ * `SectionHeading`'s muted-surface description colour and `gap-4` would be
23
+ * wrong. So the tag is resolved here and the classes stay surface-specific
24
+ * rather than the heading level being the reason the markup stays hardcoded.
25
+ */
26
+ const Heading = headingLevel;
27
+ return (_jsx(Section, { className: "py-20", children: _jsxs("div", { className: "bg-primary text-primary-foreground relative overflow-hidden rounded-2xl px-8 py-16 text-center", children: [_jsx("div", { "aria-hidden": true, className: "from-primary-foreground/15 pointer-events-none absolute inset-0 bg-gradient-to-tr to-transparent" }), _jsxs("div", { className: "relative flex flex-col items-center gap-6", children: [_jsx(Heading, { className: "max-w-2xl text-3xl font-semibold tracking-tight text-balance sm:text-4xl", children: title }), description ? (_jsx("p", { className: "max-w-xl text-lg text-pretty opacity-90", children: description })) : null, action ? (_jsxs("div", { className: "flex flex-col items-center gap-3 sm:flex-row", children: [_jsxs(CtaLink, { size: "lg", variant: action.variant ?? 'secondary', href: action.href, newTab: action.newTab, className: "group", children: [action.label, _jsx(ArrowRight, { className: "motion-safe:transition-transform size-4 group-hover:translate-x-0.5" })] }), secondaryAction ? (_jsx(CtaLink, { size: "lg", variant: secondaryAction.variant ?? 'outline', href: secondaryAction.href, newTab: secondaryAction.newTab, children: secondaryAction.label })) : null] })) : actionSlot ? (actionSlot) : null, note ? (_jsx("p", { className: "max-w-2xl text-pretty text-sm opacity-80", children: note })) : null] })] }) }));
28
+ }
29
+ export default Cta01;
@@ -0,0 +1,3 @@
1
+ export { Cta01, default } from './cta';
2
+ export type { Cta01Action, Cta01Props } from './cta';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/cta-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACtC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA"}
@@ -0,0 +1 @@
1
+ export { Cta01, default } from './cta';
@@ -0,0 +1,102 @@
1
+ import { type ReactNode } from 'react';
2
+ /** One row of data. Identity comes from `getRowId`, not from the shape. */
3
+ export type DataTableRow = Record<string, unknown>;
4
+ export type DataTableColumn = {
5
+ /** Stable identifier, used for keys and the visibility menu. */
6
+ id: string;
7
+ /** The column heading. */
8
+ header: ReactNode;
9
+ /** Renders the cell for one row. */
10
+ cell: (row: DataTableRow) => ReactNode;
11
+ /** A plain-text name for the visibility menu. Falls back to `id`. */
12
+ label?: string;
13
+ /** Layout classes, for alignment or a fixed width. */
14
+ className?: string;
15
+ };
16
+ export type DataTableFilterOption = {
17
+ label: string;
18
+ value: string;
19
+ };
20
+ export type DataTableFilter = {
21
+ id: string;
22
+ label: string;
23
+ options: DataTableFilterOption[];
24
+ };
25
+ export type DataTableRowAction = {
26
+ label: string;
27
+ variant?: 'default' | 'destructive';
28
+ onSelect?: () => void;
29
+ };
30
+ /**
31
+ * Every string the block renders. Required because the block ships no copy of
32
+ * its own: a control hint, a selection summary and an empty-state line are the
33
+ * consumer's to write.
34
+ */
35
+ export type DataTable01Labels = {
36
+ /** Search field placeholder and accessible name. */
37
+ search: string;
38
+ /** The filters trigger. */
39
+ filters: string;
40
+ /** Clears every active filter. */
41
+ reset: string;
42
+ /** Headings for the column chooser. */
43
+ columns: string;
44
+ viewColumns: string;
45
+ selectAll: string;
46
+ selectRow: string;
47
+ rowActions: string;
48
+ previous: string;
49
+ next: string;
50
+ /** Accessible name for one page control. */
51
+ page: (page: number) => string;
52
+ /** The selection summary. */
53
+ selectedCount: (count: number) => string;
54
+ /** Shown in the body when `rows` is empty and `emptyMessage` is not set. */
55
+ empty: string;
56
+ };
57
+ export type DataTable01Props = {
58
+ title?: ReactNode;
59
+ description?: ReactNode;
60
+ columns: DataTableColumn[];
61
+ /** The rows for the current page. The block renders them; it never fetches. */
62
+ rows: DataTableRow[];
63
+ /** Returns a stable identity for a row. */
64
+ getRowId: (row: DataTableRow) => string;
65
+ /** Names the table for assistive technology when no heading does. */
66
+ caption?: ReactNode;
67
+ /** Adds the selection column and the selection summary. */
68
+ selectable?: boolean;
69
+ selectedIds?: string[];
70
+ defaultSelectedIds?: string[];
71
+ onSelectedIdsChange?: (ids: string[]) => void;
72
+ searchValue?: string;
73
+ onSearchChange?: (value: string) => void;
74
+ filters?: DataTableFilter[];
75
+ filterValues?: Record<string, string | undefined>;
76
+ onFilterChange?: (id: string, value: string | undefined) => void;
77
+ /** The current page, 1-based. */
78
+ page?: number;
79
+ defaultPage?: number;
80
+ /** How many pages exist. At least 1. */
81
+ pageCount: number;
82
+ onPageChange?: (page: number) => void;
83
+ /** The per-row action menu. Return an empty array to omit the menu. */
84
+ rowActions?: (row: DataTableRow) => DataTableRowAction[];
85
+ /** Controls rendered at the end of the toolbar, e.g. a create Button. */
86
+ toolbarActions?: ReactNode;
87
+ /** Replaces the fallback empty line. */
88
+ emptyMessage?: ReactNode;
89
+ labels: DataTable01Labels;
90
+ };
91
+ /**
92
+ * A table section with a toolbar, filters, row selection and pagination.
93
+ *
94
+ * The block renders exactly the rows it is given for the current page and
95
+ * reports every interaction through a callback. It performs no filtering,
96
+ * sorting or fetching of its own: the page, the search text, the filter values
97
+ * and the selection are the consumer's state, so a server-rendered page and a
98
+ * client data layer can each drive it. Every label is a prop.
99
+ */
100
+ export declare function DataTable01({ title, description, columns, rows, getRowId, caption, selectable, selectedIds, defaultSelectedIds, onSelectedIdsChange, searchValue, onSearchChange, filters, filterValues, onFilterChange, page: pageProp, defaultPage, pageCount, onPageChange, rowActions, toolbarActions, emptyMessage, labels, }: DataTable01Props): import("react").JSX.Element;
101
+ export default DataTable01;
102
+ //# sourceMappingURL=data-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../../src/blocks/data-table-01/data-table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ChevronDown, ListFilter, MoreHorizontal, Search } from 'lucide-react';
4
+ import { useState } from 'react';
5
+ import { Button } from '../../components/ui/button';
6
+ import { Checkbox } from '../../components/ui/checkbox';
7
+ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '../../components/ui/dropdown-menu';
8
+ import { Input } from '../../components/ui/input';
9
+ import { Pagination, PaginationContent, PaginationItem } from '../../components/ui/pagination';
10
+ import { Popover, PopoverContent, PopoverTrigger } from '../../components/ui/popover';
11
+ import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, } from '../../components/ui/table';
12
+ /** The page numbers to show, with `ellipsis` where a run is held back. */
13
+ function pageWindow(page, pageCount) {
14
+ if (pageCount <= 7) {
15
+ return Array.from({ length: pageCount }, (_, index) => index + 1);
16
+ }
17
+ const pages = [1];
18
+ const start = Math.max(2, page - 1);
19
+ const end = Math.min(pageCount - 1, page + 1);
20
+ if (start > 2)
21
+ pages.push('ellipsis');
22
+ for (let value = start; value <= end; value += 1)
23
+ pages.push(value);
24
+ if (end < pageCount - 1)
25
+ pages.push('ellipsis');
26
+ pages.push(pageCount);
27
+ return pages;
28
+ }
29
+ function RowMenu({ actions, label }) {
30
+ if (!actions.length)
31
+ return null;
32
+ return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { "aria-label": label, className: "size-8 p-0", children: _jsx(MoreHorizontal, { className: "size-4" }) }), _jsx(DropdownMenuContent, { align: "end", children: actions.map((action, index) => (
33
+ // Positional: an action label is display content and two may repeat.
34
+ _jsx(DropdownMenuItem, { variant: action.variant, onClick: action.onSelect, children: action.label }, index))) })] }));
35
+ }
36
+ /**
37
+ * A table section with a toolbar, filters, row selection and pagination.
38
+ *
39
+ * The block renders exactly the rows it is given for the current page and
40
+ * reports every interaction through a callback. It performs no filtering,
41
+ * sorting or fetching of its own: the page, the search text, the filter values
42
+ * and the selection are the consumer's state, so a server-rendered page and a
43
+ * client data layer can each drive it. Every label is a prop.
44
+ */
45
+ export function DataTable01({ title, description, columns, rows, getRowId, caption, selectable = false, selectedIds, defaultSelectedIds, onSelectedIdsChange, searchValue, onSearchChange, filters, filterValues, onFilterChange, page: pageProp, defaultPage = 1, pageCount, onPageChange, rowActions, toolbarActions, emptyMessage, labels, }) {
46
+ const [internalSelected, setInternalSelected] = useState(defaultSelectedIds ?? []);
47
+ const [internalPage, setInternalPage] = useState(defaultPage);
48
+ const [internalSearch, setInternalSearch] = useState('');
49
+ const [internalFilters, setInternalFilters] = useState({});
50
+ const [hiddenColumns, setHiddenColumns] = useState([]);
51
+ const selected = selectedIds ?? internalSelected;
52
+ const page = pageProp ?? internalPage;
53
+ const search = searchValue ?? internalSearch;
54
+ const activeFilters = filterValues ?? internalFilters;
55
+ const clampPage = (value) => Math.min(Math.max(1, value), Math.max(1, pageCount));
56
+ const currentPage = clampPage(page);
57
+ const visibleColumns = columns.filter((column) => !hiddenColumns.includes(column.id));
58
+ const hasRowActions = Boolean(rowActions);
59
+ const columnCount = (selectable ? 1 : 0) + visibleColumns.length + (hasRowActions ? 1 : 0);
60
+ const rowIds = rows.map(getRowId);
61
+ const allSelected = rowIds.length > 0 && rowIds.every((id) => selected.includes(id));
62
+ const someSelected = rowIds.some((id) => selected.includes(id));
63
+ function changeSelection(ids) {
64
+ if (selectedIds === undefined)
65
+ setInternalSelected(ids);
66
+ onSelectedIdsChange?.(ids);
67
+ }
68
+ function toggleAll(checked) {
69
+ if (checked) {
70
+ changeSelection([...new Set([...selected, ...rowIds])]);
71
+ }
72
+ else {
73
+ changeSelection(selected.filter((id) => !rowIds.includes(id)));
74
+ }
75
+ }
76
+ function toggleRow(id, checked) {
77
+ changeSelection(checked ? [...selected, id] : selected.filter((item) => item !== id));
78
+ }
79
+ function changeSearch(value) {
80
+ if (searchValue === undefined)
81
+ setInternalSearch(value);
82
+ onSearchChange?.(value);
83
+ }
84
+ function changeFilter(id, value) {
85
+ if (filterValues === undefined) {
86
+ setInternalFilters((previous) => ({ ...previous, [id]: value }));
87
+ }
88
+ onFilterChange?.(id, value);
89
+ }
90
+ function resetFilters() {
91
+ if (filterValues === undefined)
92
+ setInternalFilters({});
93
+ for (const filter of filters ?? [])
94
+ onFilterChange?.(filter.id, undefined);
95
+ }
96
+ function changePage(next) {
97
+ const clamped = clampPage(next);
98
+ if (pageProp === undefined)
99
+ setInternalPage(clamped);
100
+ onPageChange?.(clamped);
101
+ }
102
+ function toggleColumn(id, visible) {
103
+ setHiddenColumns((previous) => visible ? previous.filter((item) => item !== id) : [...previous, id]);
104
+ }
105
+ const activeFilterCount = Object.values(activeFilters).filter(Boolean).length;
106
+ return (_jsxs("div", { className: "flex flex-col gap-4", children: [title || description ? (_jsxs("div", { className: "flex flex-col gap-1", children: [title ? _jsx("h2", { className: "text-lg font-semibold tracking-tight", children: title }) : null, description ? (_jsx("p", { className: "text-muted-foreground text-sm", children: description })) : null] })) : null, _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2" }), _jsx(Input, { value: search, onChange: (event) => changeSearch(event.target.value), placeholder: labels.search, "aria-label": labels.search, className: "h-9 w-56 pl-8" })] }), filters?.length ? (_jsxs(Popover, { children: [_jsxs(PopoverTrigger, { children: [_jsx(ListFilter, { className: "size-4" }), labels.filters, activeFilterCount > 0 ? (_jsx("span", { className: "bg-primary text-primary-foreground rounded-full px-1.5 text-xs", children: activeFilterCount })) : null] }), _jsxs(PopoverContent, { align: "start", className: "flex w-64 flex-col gap-4", children: [filters.map((filter) => (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "text-sm font-medium", children: filter.label }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: filter.options.map((option) => {
107
+ const active = activeFilters[filter.id] === option.value;
108
+ return (_jsx(Button, { type: "button", size: "sm", variant: active ? 'default' : 'outline', onClick: () => changeFilter(filter.id, active ? undefined : option.value), children: option.label }, option.value));
109
+ }) })] }, filter.id))), _jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: activeFilterCount === 0, onClick: resetFilters, children: labels.reset })] })] })) : null] }), _jsxs("div", { className: "flex items-center gap-2", children: [toolbarActions, _jsxs(DropdownMenu, { children: [_jsxs(DropdownMenuTrigger, { children: [labels.viewColumns, _jsx(ChevronDown, { className: "size-4" })] }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuLabel, { children: labels.columns }), _jsx(DropdownMenuSeparator, {}), columns.map((column) => (_jsx(DropdownMenuCheckboxItem, { checked: !hiddenColumns.includes(column.id), closeOnClick: false, onCheckedChange: (checked) => toggleColumn(column.id, checked), children: column.label ?? column.id }, column.id)))] })] })] })] }), _jsx("div", { className: "border-border overflow-hidden rounded-xl border", children: _jsxs(Table, { children: [caption ? _jsx(TableCaption, { children: caption }) : null, _jsx(TableHeader, { children: _jsxs(TableRow, { children: [selectable ? (_jsx(TableHead, { className: "w-10", children: _jsx(Checkbox, { checked: allSelected, indeterminate: !allSelected && someSelected, onCheckedChange: toggleAll, "aria-label": labels.selectAll }) })) : null, visibleColumns.map((column) => (_jsx(TableHead, { className: column.className, children: column.header }, column.id))), hasRowActions ? (_jsx(TableHead, { className: "w-10", children: _jsx("span", { className: "sr-only", children: labels.rowActions }) })) : null] }) }), _jsx(TableBody, { children: rows.length ? (rows.map((row) => {
110
+ const id = getRowId(row);
111
+ const isSelected = selected.includes(id);
112
+ const actions = rowActions?.(row) ?? [];
113
+ return (_jsxs(TableRow, { "data-state": isSelected ? 'selected' : undefined, children: [selectable ? (_jsx(TableCell, { children: _jsx(Checkbox, { checked: isSelected, onCheckedChange: (checked) => toggleRow(id, checked), "aria-label": labels.selectRow }) })) : null, visibleColumns.map((column) => (_jsx(TableCell, { className: column.className, children: column.cell(row) }, column.id))), hasRowActions ? (_jsx(TableCell, { className: "text-right", children: _jsx(RowMenu, { actions: actions, label: labels.rowActions }) })) : null] }, id));
114
+ })) : (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: columnCount, className: "text-muted-foreground h-24 text-center", children: emptyMessage ?? labels.empty }) })) })] }) }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [selectable ? (_jsx("span", { className: "text-muted-foreground text-sm", children: labels.selectedCount(selected.length) })) : (_jsx("span", {})), _jsx(Pagination, { className: "mx-0 w-auto justify-end", children: _jsxs(PaginationContent, { children: [_jsx(PaginationItem, { children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: currentPage <= 1, "aria-label": labels.previous, onClick: () => changePage(currentPage - 1), children: labels.previous }) }), pageWindow(currentPage, Math.max(1, pageCount)).map((item, index) => item === 'ellipsis' ? (_jsx(PaginationItem, { children: _jsx("span", { "aria-hidden": "true", className: "text-muted-foreground px-2", children: "..." }) }, `ellipsis-${index}`)) : (_jsx(PaginationItem, { children: _jsx(Button, { type: "button", variant: item === currentPage ? 'outline' : 'ghost', size: "icon", "aria-label": labels.page(item), "aria-current": item === currentPage ? 'page' : undefined, onClick: () => changePage(item), children: item }) }, item))), _jsx(PaginationItem, { children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: currentPage >= Math.max(1, pageCount), "aria-label": labels.next, onClick: () => changePage(currentPage + 1), children: labels.next }) })] }) })] })] }));
115
+ }
116
+ export default DataTable01;
@@ -0,0 +1,3 @@
1
+ export { DataTable01, default } from './data-table';
2
+ export type { DataTable01Props, DataTable01Labels, DataTableColumn, DataTableFilter, DataTableFilterOption, DataTableRow, DataTableRowAction, } from './data-table';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/data-table-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACnD,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,GACnB,MAAM,cAAc,CAAA"}
@@ -0,0 +1 @@
1
+ export { DataTable01, default } from './data-table';