cortena-ui 1.3.0 → 1.4.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 (280) hide show
  1. package/README.md +74 -3
  2. package/dist/a2ui/catalogue-doc.d.ts +44 -0
  3. package/dist/a2ui/catalogue-doc.js +169 -0
  4. package/dist/a2ui/catalogue-doc.js.map +1 -0
  5. package/dist/a2ui/catalogue.d.ts +44 -0
  6. package/dist/a2ui/catalogue.js +942 -0
  7. package/dist/a2ui/catalogue.js.map +1 -0
  8. package/dist/a2ui/index.d.ts +7 -0
  9. package/dist/a2ui/message.d.ts +232 -0
  10. package/dist/a2ui/message.js +365 -0
  11. package/dist/a2ui/message.js.map +1 -0
  12. package/dist/a2ui/renderer.d.ts +46 -0
  13. package/dist/a2ui/renderer.js +252 -0
  14. package/dist/a2ui/renderer.js.map +1 -0
  15. package/dist/a2ui/views.d.ts +80 -0
  16. package/dist/a2ui/views.js +596 -0
  17. package/dist/a2ui/views.js.map +1 -0
  18. package/dist/a2ui.d.ts +8 -0
  19. package/dist/a2ui.js +7 -0
  20. package/dist/chart.d.ts +9 -0
  21. package/dist/chart.js +9 -0
  22. package/dist/components/accordion.d.ts +22 -0
  23. package/dist/components/accordion.js +63 -0
  24. package/dist/components/accordion.js.map +1 -0
  25. package/dist/components/alert.d.ts +15 -0
  26. package/dist/components/alert.js +64 -0
  27. package/dist/components/alert.js.map +1 -0
  28. package/dist/components/avatar.d.ts +18 -0
  29. package/dist/components/avatar.js +40 -0
  30. package/dist/components/avatar.js.map +1 -0
  31. package/dist/components/badge.d.ts +12 -0
  32. package/dist/components/badge.js +47 -0
  33. package/dist/components/badge.js.map +1 -0
  34. package/dist/components/breadcrumb.d.ts +71 -0
  35. package/dist/components/breadcrumb.js +123 -0
  36. package/dist/components/breadcrumb.js.map +1 -0
  37. package/dist/components/button-link.d.ts +28 -0
  38. package/dist/components/button-link.js +24 -0
  39. package/dist/components/button-link.js.map +1 -0
  40. package/dist/components/button.d.ts +24 -0
  41. package/dist/components/button.js +65 -0
  42. package/dist/components/button.js.map +1 -0
  43. package/dist/components/calendar.d.ts +28 -0
  44. package/dist/components/calendar.js +123 -0
  45. package/dist/components/calendar.js.map +1 -0
  46. package/dist/components/card.d.ts +32 -0
  47. package/dist/components/card.js +57 -0
  48. package/dist/components/card.js.map +1 -0
  49. package/dist/components/chart/chart.d.ts +71 -0
  50. package/dist/components/chart/chart.js +167 -0
  51. package/dist/components/chart/chart.js.map +1 -0
  52. package/dist/components/chart/container.d.ts +88 -0
  53. package/dist/components/chart/container.js +189 -0
  54. package/dist/components/chart/container.js.map +1 -0
  55. package/dist/components/chart/data.js +128 -0
  56. package/dist/components/chart/data.js.map +1 -0
  57. package/dist/components/chart/index.d.ts +9 -0
  58. package/dist/components/chart/index.js +10 -0
  59. package/dist/components/chart/nivo-charts.js +225 -0
  60. package/dist/components/chart/nivo-charts.js.map +1 -0
  61. package/dist/components/chart/nivo-lazy.js +50 -0
  62. package/dist/components/chart/nivo-lazy.js.map +1 -0
  63. package/dist/components/chart/nivo-theme.d.ts +156 -0
  64. package/dist/components/chart/nivo-theme.js +161 -0
  65. package/dist/components/chart/nivo-theme.js.map +1 -0
  66. package/dist/components/chart/recharts-charts.js +276 -0
  67. package/dist/components/chart/recharts-charts.js.map +1 -0
  68. package/dist/components/chart/recharts-lazy.js +58 -0
  69. package/dist/components/chart/recharts-lazy.js.map +1 -0
  70. package/dist/components/chart/recharts-parts.d.ts +10 -0
  71. package/dist/components/chart/recharts-parts.js +25 -0
  72. package/dist/components/chart/recharts-parts.js.map +1 -0
  73. package/dist/components/chart/tokens.d.ts +62 -0
  74. package/dist/components/chart/tokens.js +192 -0
  75. package/dist/components/chart/tokens.js.map +1 -0
  76. package/dist/components/chart/types.d.ts +114 -0
  77. package/dist/components/chart/types.js +27 -0
  78. package/dist/components/chart/types.js.map +1 -0
  79. package/dist/components/checkbox.d.ts +20 -0
  80. package/dist/components/checkbox.js +24 -0
  81. package/dist/components/checkbox.js.map +1 -0
  82. package/dist/components/chip.d.ts +17 -0
  83. package/dist/components/chip.js +47 -0
  84. package/dist/components/chip.js.map +1 -0
  85. package/dist/components/combobox.d.ts +76 -0
  86. package/dist/components/combobox.js +201 -0
  87. package/dist/components/combobox.js.map +1 -0
  88. package/dist/components/command.d.ts +50 -0
  89. package/dist/components/command.js +117 -0
  90. package/dist/components/command.js.map +1 -0
  91. package/dist/components/data-table/data-table.d.ts +65 -0
  92. package/dist/components/data-table/data-table.js +588 -0
  93. package/dist/components/data-table/data-table.js.map +1 -0
  94. package/dist/components/data-table/export.d.ts +23 -0
  95. package/dist/components/data-table/export.js +95 -0
  96. package/dist/components/data-table/export.js.map +1 -0
  97. package/dist/components/data-table/features.d.ts +66 -0
  98. package/dist/components/data-table/features.js +103 -0
  99. package/dist/components/data-table/features.js.map +1 -0
  100. package/dist/components/data-table/index.d.ts +8 -0
  101. package/dist/components/data-table/parts.d.ts +79 -0
  102. package/dist/components/data-table/parts.js +400 -0
  103. package/dist/components/data-table/parts.js.map +1 -0
  104. package/dist/components/data-table/system-columns.js +84 -0
  105. package/dist/components/data-table/system-columns.js.map +1 -0
  106. package/dist/components/data-table/types.d.ts +172 -0
  107. package/dist/components/data-table/use-data-table.d.ts +19 -0
  108. package/dist/components/data-table/use-data-table.js +171 -0
  109. package/dist/components/data-table/use-data-table.js.map +1 -0
  110. package/dist/components/data-table/use-server-source.js +200 -0
  111. package/dist/components/data-table/use-server-source.js.map +1 -0
  112. package/dist/components/date-field.d.ts +54 -0
  113. package/dist/components/date-field.js +235 -0
  114. package/dist/components/date-field.js.map +1 -0
  115. package/dist/components/date-picker.d.ts +42 -0
  116. package/dist/components/date-picker.js +125 -0
  117. package/dist/components/date-picker.js.map +1 -0
  118. package/dist/components/dialog.d.ts +36 -0
  119. package/dist/components/dialog.js +97 -0
  120. package/dist/components/dialog.js.map +1 -0
  121. package/dist/components/dropdown-menu.d.ts +54 -0
  122. package/dist/components/dropdown-menu.js +191 -0
  123. package/dist/components/dropdown-menu.js.map +1 -0
  124. package/dist/components/dropzone.d.ts +48 -0
  125. package/dist/components/dropzone.js +185 -0
  126. package/dist/components/dropzone.js.map +1 -0
  127. package/dist/components/empty-state.d.ts +22 -0
  128. package/dist/components/empty-state.js +46 -0
  129. package/dist/components/empty-state.js.map +1 -0
  130. package/dist/components/error-banner.d.ts +17 -0
  131. package/dist/components/error-banner.js +52 -0
  132. package/dist/components/error-banner.js.map +1 -0
  133. package/dist/components/field.d.ts +64 -0
  134. package/dist/components/field.js +133 -0
  135. package/dist/components/field.js.map +1 -0
  136. package/dist/components/form.d.ts +37 -0
  137. package/dist/components/form.js +103 -0
  138. package/dist/components/form.js.map +1 -0
  139. package/dist/components/input.d.ts +17 -0
  140. package/dist/components/input.js +26 -0
  141. package/dist/components/input.js.map +1 -0
  142. package/dist/components/kbd.d.ts +11 -0
  143. package/dist/components/kbd.js +20 -0
  144. package/dist/components/kbd.js.map +1 -0
  145. package/dist/components/label.d.ts +14 -0
  146. package/dist/components/label.js +28 -0
  147. package/dist/components/label.js.map +1 -0
  148. package/dist/components/loading-skeleton.d.ts +22 -0
  149. package/dist/components/loading-skeleton.js +123 -0
  150. package/dist/components/loading-skeleton.js.map +1 -0
  151. package/dist/components/markdown.d.ts +44 -0
  152. package/dist/components/markdown.js +231 -0
  153. package/dist/components/markdown.js.map +1 -0
  154. package/dist/components/page-header.d.ts +26 -0
  155. package/dist/components/page-header.js +53 -0
  156. package/dist/components/page-header.js.map +1 -0
  157. package/dist/components/popover.d.ts +29 -0
  158. package/dist/components/popover.js +74 -0
  159. package/dist/components/popover.js.map +1 -0
  160. package/dist/components/progress.d.ts +22 -0
  161. package/dist/components/progress.js +49 -0
  162. package/dist/components/progress.js.map +1 -0
  163. package/dist/components/radio-group.d.ts +20 -0
  164. package/dist/components/radio-group.js +29 -0
  165. package/dist/components/radio-group.js.map +1 -0
  166. package/dist/components/scroll-area.d.ts +25 -0
  167. package/dist/components/scroll-area.js +39 -0
  168. package/dist/components/scroll-area.js.map +1 -0
  169. package/dist/components/section-card.d.ts +29 -0
  170. package/dist/components/section-card.js +55 -0
  171. package/dist/components/section-card.js.map +1 -0
  172. package/dist/components/segmented.d.ts +27 -0
  173. package/dist/components/segmented.js +32 -0
  174. package/dist/components/segmented.js.map +1 -0
  175. package/dist/components/select.d.ts +62 -0
  176. package/dist/components/select.js +97 -0
  177. package/dist/components/select.js.map +1 -0
  178. package/dist/components/separator.d.ts +19 -0
  179. package/dist/components/separator.js +23 -0
  180. package/dist/components/separator.js.map +1 -0
  181. package/dist/components/sheet.d.ts +35 -0
  182. package/dist/components/sheet.js +131 -0
  183. package/dist/components/sheet.js.map +1 -0
  184. package/dist/components/skeleton.d.ts +12 -0
  185. package/dist/components/skeleton.js +22 -0
  186. package/dist/components/skeleton.js.map +1 -0
  187. package/dist/components/sortable-list.d.ts +67 -0
  188. package/dist/components/sortable-list.js +206 -0
  189. package/dist/components/sortable-list.js.map +1 -0
  190. package/dist/components/spinner.d.ts +29 -0
  191. package/dist/components/spinner.js +34 -0
  192. package/dist/components/spinner.js.map +1 -0
  193. package/dist/components/status-dot.d.ts +26 -0
  194. package/dist/components/status-dot.js +47 -0
  195. package/dist/components/status-dot.js.map +1 -0
  196. package/dist/components/switch.d.ts +21 -0
  197. package/dist/components/switch.js +21 -0
  198. package/dist/components/switch.js.map +1 -0
  199. package/dist/components/tabs.d.ts +24 -0
  200. package/dist/components/tabs.js +60 -0
  201. package/dist/components/tabs.js.map +1 -0
  202. package/dist/components/textarea.d.ts +19 -0
  203. package/dist/components/textarea.js +47 -0
  204. package/dist/components/textarea.js.map +1 -0
  205. package/dist/components/toast.d.ts +47 -0
  206. package/dist/components/toast.js +106 -0
  207. package/dist/components/toast.js.map +1 -0
  208. package/dist/components/toolbar.d.ts +19 -0
  209. package/dist/components/toolbar.js +45 -0
  210. package/dist/components/toolbar.js.map +1 -0
  211. package/dist/components/tooltip.d.ts +28 -0
  212. package/dist/components/tooltip.js +59 -0
  213. package/dist/components/tooltip.js.map +1 -0
  214. package/dist/core.d.ts +44 -0
  215. package/dist/core.js +44 -0
  216. package/dist/data-table.d.ts +9 -0
  217. package/dist/data-table.js +7 -0
  218. package/dist/form.d.ts +7 -0
  219. package/dist/form.js +7 -0
  220. package/dist/hooks/use-cortena-theme.d.ts +98 -0
  221. package/dist/hooks/use-cortena-theme.js +145 -0
  222. package/dist/hooks/use-cortena-theme.js.map +1 -0
  223. package/dist/index.d.ts +75 -2678
  224. package/dist/index.js +66 -8598
  225. package/dist/lib/cn.d.ts +10 -0
  226. package/dist/lib/cn.js +15 -0
  227. package/dist/lib/cn.js.map +1 -0
  228. package/dist/lib/render.d.ts +23 -0
  229. package/dist/lib/render.js +20 -0
  230. package/dist/lib/render.js.map +1 -0
  231. package/dist/lib/shakeable.js +39 -0
  232. package/dist/lib/shakeable.js.map +1 -0
  233. package/dist/markdown.d.ts +3 -0
  234. package/dist/markdown.js +3 -0
  235. package/dist/sortable-list.d.ts +3 -0
  236. package/dist/sortable-list.js +3 -0
  237. package/package.json +37 -14
  238. package/src/a2ui/catalogue.ts +140 -103
  239. package/src/a2ui/views.tsx +5 -2
  240. package/src/components/alert.tsx +1 -1
  241. package/src/components/badge.tsx +1 -1
  242. package/src/components/button.tsx +1 -1
  243. package/src/components/chart/chart.tsx +72 -25
  244. package/src/components/chart/container.tsx +24 -39
  245. package/src/components/chart/index.tsx +4 -2
  246. package/src/components/chart/nivo-charts.tsx +41 -13
  247. package/src/components/chart/nivo-lazy.tsx +52 -0
  248. package/src/components/chart/recharts-charts.tsx +98 -3
  249. package/src/components/chart/recharts-lazy.tsx +72 -0
  250. package/src/components/chart/recharts-parts.tsx +34 -0
  251. package/src/components/chart/tokens.ts +1 -1
  252. package/src/components/chart/types.ts +14 -0
  253. package/src/components/chip.tsx +1 -1
  254. package/src/components/combobox.tsx +2 -2
  255. package/src/components/data-table/export.ts +18 -2
  256. package/src/components/data-table/features.ts +77 -45
  257. package/src/components/data-table/parts.tsx +15 -0
  258. package/src/components/data-table/use-data-table.ts +7 -2
  259. package/src/components/data-table/use-server-source.ts +17 -4
  260. package/src/components/date-field.tsx +1 -1
  261. package/src/components/error-banner.tsx +1 -1
  262. package/src/components/field.tsx +2 -2
  263. package/src/components/form.tsx +2 -2
  264. package/src/components/input.tsx +1 -1
  265. package/src/components/label.tsx +1 -1
  266. package/src/components/markdown.tsx +5 -4
  267. package/src/components/sheet.tsx +2 -2
  268. package/src/components/sortable-list.tsx +2 -2
  269. package/src/components/textarea.tsx +1 -1
  270. package/src/components/toast.tsx +1 -1
  271. package/src/entries/a2ui.ts +11 -0
  272. package/src/entries/chart.ts +10 -0
  273. package/src/entries/core.ts +91 -0
  274. package/src/entries/data-table.ts +9 -0
  275. package/src/entries/form.ts +24 -0
  276. package/src/entries/markdown.ts +9 -0
  277. package/src/entries/sortable-list.ts +13 -0
  278. package/src/index.ts +32 -98
  279. package/src/lib/shakeable.ts +33 -0
  280. package/dist/index.js.map +0 -1
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { ClassValue } from "clsx";
3
+ //#region src/lib/cn.d.ts
4
+ /**
5
+ * Merge class names the shadcn way: clsx for conditionals, tailwind-merge so a
6
+ * consumer's `className` wins over a component's default for the same utility.
7
+ */
8
+ export declare function cn(...inputs: ClassValue[]): string;
9
+ //#endregion
10
+ //# sourceMappingURL=cn.d.ts.map
package/dist/lib/cn.js ADDED
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { clsx } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+ //#region src/lib/cn.ts
5
+ /**
6
+ * Merge class names the shadcn way: clsx for conditionals, tailwind-merge so a
7
+ * consumer's `className` wins over a component's default for the same utility.
8
+ */
9
+ function cn(...inputs) {
10
+ return twMerge(clsx(inputs));
11
+ }
12
+ //#endregion
13
+ export { cn };
14
+
15
+ //# sourceMappingURL=cn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.js","names":[],"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names the shadcn way: clsx for conditionals, tailwind-merge so a\n * consumer's `className` wins over a component's default for the same utility.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,GAAG,GAAG,QAA8B;CAClD,OAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ //#region src/lib/render.d.ts
4
+ /**
5
+ * The `render` prop for the components that are plain markup rather than Base
6
+ * UI primitives (Card, SectionCard, ButtonLink, BreadcrumbLink).
7
+ *
8
+ * Base UI parts take their own `render` and need nothing from here. The rest
9
+ * are a `<div>` or an `<a>` this package writes itself, and a consumer
10
+ * sometimes needs a different element under the same styling: a Card that is
11
+ * the page's `<aside>` landmark, or a link that is the router's `<Link>`.
12
+ * Passing an element rather than a component keeps the call site readable and
13
+ * lets the caller set props on it (`render={<Link to="/x" />}`).
14
+ *
15
+ * `props` wins over the passed element's own props, so the `className` and
16
+ * handlers a component computed are not silently dropped, while the element's
17
+ * own props (`href`, `to`, `aria-labelledby`) come through untouched. What a
18
+ * component lets a *caller* override is decided by the order it builds `props`
19
+ * in, not here. Children are `children`, falling back to the element's.
20
+ */
21
+ export type RenderProp = React.ReactElement<Record<string, unknown>>;
22
+ //#endregion
23
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/lib/render.tsx
4
+ function renderWith(render, props, children, Fallback) {
5
+ if (!render) return /* @__PURE__ */ jsx(Fallback, {
6
+ ...props,
7
+ children
8
+ });
9
+ const Element = render.type;
10
+ const given = render.props;
11
+ return /* @__PURE__ */ jsx(Element, {
12
+ ...render.props,
13
+ ...props,
14
+ children: children ?? given.children
15
+ });
16
+ }
17
+ //#endregion
18
+ export { renderWith };
19
+
20
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","names":["Element"],"sources":["../../src/lib/render.tsx"],"sourcesContent":["import type * as React from \"react\";\n\n/**\n * The `render` prop for the components that are plain markup rather than Base\n * UI primitives (Card, SectionCard, ButtonLink, BreadcrumbLink).\n *\n * Base UI parts take their own `render` and need nothing from here. The rest\n * are a `<div>` or an `<a>` this package writes itself, and a consumer\n * sometimes needs a different element under the same styling: a Card that is\n * the page's `<aside>` landmark, or a link that is the router's `<Link>`.\n * Passing an element rather than a component keeps the call site readable and\n * lets the caller set props on it (`render={<Link to=\"/x\" />}`).\n *\n * `props` wins over the passed element's own props, so the `className` and\n * handlers a component computed are not silently dropped, while the element's\n * own props (`href`, `to`, `aria-labelledby`) come through untouched. What a\n * component lets a *caller* override is decided by the order it builds `props`\n * in, not here. Children are `children`, falling back to the element's.\n */\nexport type RenderProp = React.ReactElement<Record<string, unknown>>;\n\nexport function renderWith(\n render: RenderProp | undefined,\n props: Record<string, unknown>,\n children: React.ReactNode,\n Fallback: React.ElementType,\n): React.ReactElement {\n if (!render) {\n const Element = Fallback;\n return <Element {...props}>{children}</Element>;\n }\n const Element = render.type as React.ElementType;\n const given = render.props as { children?: React.ReactNode };\n return (\n <Element {...(render.props as Record<string, unknown>)} {...props}>\n {children ?? given.children}\n </Element>\n );\n}\n"],"mappings":";;;AAqBA,SAAgB,WACd,QACA,OACA,UACA,UACoB;CACpB,IAAI,CAAC,QAEH,OAAO,oBAACA,UAAD;EAAS,GAAI;EAAQ;CAAkB,CAAA;CAEhD,MAAM,UAAU,OAAO;CACvB,MAAM,QAAQ,OAAO;CACrB,OACE,oBAAC,SAAD;EAAS,GAAK,OAAO;EAAmC,GAAI;EACzD,UAAA,YAAY,MAAM;CACZ,CAAA;AAEb"}
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ //#region src/lib/shakeable.ts
3
+ /**
4
+ * Evaluates `build` immediately and returns its value.
5
+ *
6
+ * A pass-through with exactly one job: to let a consumer's bundler delete what
7
+ * it wraps.
8
+ *
9
+ * The package is one ESM module tree with no side effects, so a bundler is free
10
+ * to drop anything an app does not reach. It can only do that for statements it
11
+ * can prove are safe to skip, and a top-level call it cannot see inside —
12
+ * `tableFeatures({ … })`, a `z.enum(...).describe(...)` chain, `Object.freeze`
13
+ * over a spread — is never provably safe. The statement is kept, and with it
14
+ * every module it can reach. That is how `import { Button } from "cortena-ui"`
15
+ * came to pull recharts, nivo, exceljs, dnd-kit, react-markdown, cmdk and
16
+ * react-day-picker into an app that renders one button: 2,479 kB of it.
17
+ *
18
+ * Wrapped in a thunk the same work is no longer a top-level expression, and the
19
+ * `@__PURE__` annotation each call site carries tells the bundler the call may
20
+ * be dropped when its result is unused. Runtime behaviour is unchanged — the
21
+ * thunk runs on the line it is written — so nothing is deferred, lazy or
22
+ * asynchronous. Only the bundler sees a difference.
23
+ *
24
+ * Use it for a module-scope constant built by a call. Prefer a bare
25
+ * `/* @__PURE__ *\/` annotation where the call's arguments are literals
26
+ * (`cva(...)`, `cn(...)`, `React.createContext(...)`); the thunk is for the
27
+ * cases where the arguments themselves contain calls, because a bundler
28
+ * evaluates arguments even when the call around them is annotated pure.
29
+ *
30
+ * `test/bundle-probe.test.mjs` measures a real consumer bundle, which is what
31
+ * stops any of this being quietly undone.
32
+ */
33
+ function shakeable(build) {
34
+ return build();
35
+ }
36
+ //#endregion
37
+ export { shakeable };
38
+
39
+ //# sourceMappingURL=shakeable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shakeable.js","names":[],"sources":["../../src/lib/shakeable.ts"],"sourcesContent":["/**\n * Evaluates `build` immediately and returns its value.\n *\n * A pass-through with exactly one job: to let a consumer's bundler delete what\n * it wraps.\n *\n * The package is one ESM module tree with no side effects, so a bundler is free\n * to drop anything an app does not reach. It can only do that for statements it\n * can prove are safe to skip, and a top-level call it cannot see inside —\n * `tableFeatures({ … })`, a `z.enum(...).describe(...)` chain, `Object.freeze`\n * over a spread — is never provably safe. The statement is kept, and with it\n * every module it can reach. That is how `import { Button } from \"cortena-ui\"`\n * came to pull recharts, nivo, exceljs, dnd-kit, react-markdown, cmdk and\n * react-day-picker into an app that renders one button: 2,479 kB of it.\n *\n * Wrapped in a thunk the same work is no longer a top-level expression, and the\n * `@__PURE__` annotation each call site carries tells the bundler the call may\n * be dropped when its result is unused. Runtime behaviour is unchanged — the\n * thunk runs on the line it is written — so nothing is deferred, lazy or\n * asynchronous. Only the bundler sees a difference.\n *\n * Use it for a module-scope constant built by a call. Prefer a bare\n * `/* @__PURE__ *\\/` annotation where the call's arguments are literals\n * (`cva(...)`, `cn(...)`, `React.createContext(...)`); the thunk is for the\n * cases where the arguments themselves contain calls, because a bundler\n * evaluates arguments even when the call around them is annotated pure.\n *\n * `test/bundle-probe.test.mjs` measures a real consumer bundle, which is what\n * stops any of this being quietly undone.\n */\nexport function shakeable<T>(build: () => T): T {\n return build();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,UAAa,OAAmB;CAC9C,OAAO,MAAM;AACf"}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import { CodeRendererProps, Markdown, MarkdownComponents as Components, MarkdownProps, markdownSanitizeSchema } from "./components/markdown.js";
3
+ export { type CodeRendererProps, Markdown, type Components as MarkdownComponents, type MarkdownProps, markdownSanitizeSchema };
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import { Markdown, markdownSanitizeSchema } from "./components/markdown.js";
3
+ export { Markdown, markdownSanitizeSchema };
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import { SortableHandle, SortableHandleProps, SortableList, SortableListProps, SortableRenderState, SortableReorderDetails, arrayMove } from "./components/sortable-list.js";
3
+ export { SortableHandle, type SortableHandleProps, SortableList, type SortableListProps, type SortableRenderState, type SortableReorderDetails, arrayMove };
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import { SortableHandle, SortableList, arrayMove } from "./components/sortable-list.js";
3
+ export { SortableHandle, SortableList, arrayMove };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortena-ui",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Cortena UI — the shared React component library for cortenaweb and every Cortena extension. shadcn over Base UI, styled entirely from cortena-design tokens.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "type": "module",
12
12
  "sideEffects": [
13
- "*.css"
13
+ "**/*.css"
14
14
  ],
15
15
  "engines": {
16
16
  "node": ">=22"
@@ -25,6 +25,34 @@
25
25
  "types": "./dist/index.d.ts",
26
26
  "default": "./dist/index.js"
27
27
  },
28
+ "./core": {
29
+ "types": "./dist/core.d.ts",
30
+ "default": "./dist/core.js"
31
+ },
32
+ "./form": {
33
+ "types": "./dist/form.d.ts",
34
+ "default": "./dist/form.js"
35
+ },
36
+ "./data-table": {
37
+ "types": "./dist/data-table.d.ts",
38
+ "default": "./dist/data-table.js"
39
+ },
40
+ "./chart": {
41
+ "types": "./dist/chart.d.ts",
42
+ "default": "./dist/chart.js"
43
+ },
44
+ "./markdown": {
45
+ "types": "./dist/markdown.d.ts",
46
+ "default": "./dist/markdown.js"
47
+ },
48
+ "./a2ui": {
49
+ "types": "./dist/a2ui.d.ts",
50
+ "default": "./dist/a2ui.js"
51
+ },
52
+ "./sortable-list": {
53
+ "types": "./dist/sortable-list.d.ts",
54
+ "default": "./dist/sortable-list.js"
55
+ },
28
56
  "./styles.css": "./src/styles/index.css",
29
57
  "./package.json": "./package.json"
30
58
  },
@@ -32,18 +60,20 @@
32
60
  "build": "tsdown",
33
61
  "check": "tsc --noEmit",
34
62
  "lint:design": "node ../../lint/cli.mjs --exempt chart-import src",
35
- "test": "vitest run",
63
+ "test": "vitest run && vitest run --config vitest.bundle.config.ts",
36
64
  "guide": "vite --config guide/vite.config.ts",
37
65
  "guide:build": "vite build --config guide/vite.config.ts",
38
66
  "a2ui:catalogue": "node scripts/a2ui-catalogue.mjs",
39
- "prepack": "pnpm build"
67
+ "prepack": "pnpm build",
68
+ "test:bundle": "vitest run --config vitest.bundle.config.ts",
69
+ "bundle:probe": "node scripts/bundle-probe.mjs"
40
70
  },
41
71
  "peerDependencies": {
72
+ "@tanstack/react-query": "^5.0.0",
42
73
  "cortena-design": ">=3.2.0",
43
74
  "react": "^19.0.0",
44
75
  "react-dom": "^19.0.0",
45
- "zod": "^3.25.0 || ^4.0.0",
46
- "@tanstack/react-query": "^5.0.0"
76
+ "zod": "^3.25.0 || ^4.0.0"
47
77
  },
48
78
  "dependencies": {
49
79
  "@base-ui/react": "^1.8.0",
@@ -89,6 +119,7 @@
89
119
  "playwright": "^1.63.0",
90
120
  "react": "^19.1.0",
91
121
  "react-dom": "^19.1.0",
122
+ "rehype-raw": "^7.0.0",
92
123
  "tailwindcss": "^4.3.3",
93
124
  "tsdown": "^0.23.0",
94
125
  "typescript": "^5.9.0",
@@ -99,13 +130,5 @@
99
130
  },
100
131
  "publishConfig": {
101
132
  "access": "public"
102
- },
103
- "peerDependenciesMeta": {
104
- "zod": {
105
- "optional": true
106
- },
107
- "@tanstack/react-query": {
108
- "optional": true
109
- }
110
133
  }
111
134
  }
@@ -25,6 +25,7 @@
25
25
  */
26
26
 
27
27
  import { z } from "zod";
28
+ import { shakeable } from "@/lib/shakeable";
28
29
  import type { A2UIComponentSpec } from "./message";
29
30
  import * as views from "./views";
30
31
  import type { A2UIView } from "./views";
@@ -74,50 +75,75 @@ function entry<P>(definition: A2UICatalogueEntry<P>): A2UICatalogueEntry<never>
74
75
  * bare `{ name, context }`, or just the name as a string; the renderer
75
76
  * normalises all three to this before validation.
76
77
  */
77
- const Action = z
78
- .object({
79
- name: z.string().describe("Event name sent back to the agent."),
80
- context: z
81
- .record(z.string(), z.unknown())
82
- .optional()
83
- .describe("Extra values merged into the action payload."),
78
+ const Action = /* @__PURE__ */ shakeable(() =>
79
+ z
80
+ .object({
81
+ name: z.string().describe("Event name sent back to the agent."),
82
+ context: z
83
+ .record(z.string(), z.unknown())
84
+ .optional()
85
+ .describe("Extra values merged into the action payload."),
86
+ })
87
+ .describe("An action reported to the agent when the user interacts.")
88
+ );
89
+
90
+ const Option = /* @__PURE__ */ shakeable(() =>
91
+ z.object({
92
+ value: z.string().describe("Value written to the data model."),
93
+ label: z.string().optional().describe("Text shown to the user; defaults to the value."),
94
+ disabled: z.boolean().optional(),
84
95
  })
85
- .describe("An action reported to the agent when the user interacts.");
86
-
87
- const Option = z.object({
88
- value: z.string().describe("Value written to the data model."),
89
- label: z.string().optional().describe("Text shown to the user; defaults to the value."),
90
- disabled: z.boolean().optional(),
91
- });
92
-
93
- const gap = z
94
- .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(8)])
95
- .describe("Spacing step between children.");
96
-
97
- const padding = z
98
- .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(8)])
99
- .describe("Inner padding step.");
100
-
101
- const alignment = z
102
- .enum(["start", "center", "end", "stretch", "baseline"])
103
- .describe("Cross-axis alignment.");
104
-
105
- const justification = z
106
- .enum(["start", "center", "end", "between"])
107
- .describe("Main-axis distribution.");
108
-
109
- const fieldChrome = {
96
+ );
97
+
98
+ const gap = /* @__PURE__ */ shakeable(() =>
99
+ z
100
+ .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(8)])
101
+ .describe("Spacing step between children.")
102
+ );
103
+
104
+ const padding = /* @__PURE__ */ shakeable(() =>
105
+ z
106
+ .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(8)])
107
+ .describe("Inner padding step.")
108
+ );
109
+
110
+ const alignment = /* @__PURE__ */ shakeable(() =>
111
+ z
112
+ .enum(["start", "center", "end", "stretch", "baseline"])
113
+ .describe("Cross-axis alignment.")
114
+ );
115
+
116
+ const justification = /* @__PURE__ */ shakeable(() =>
117
+ z
118
+ .enum(["start", "center", "end", "between"])
119
+ .describe("Main-axis distribution.")
120
+ );
121
+
122
+ const fieldChrome = /* @__PURE__ */ shakeable(() => ({
110
123
  label: z.string().optional().describe("Field label."),
111
124
  description: z.string().optional().describe("Helper text under the control."),
112
125
  error: z.string().optional().describe("Validation message; also marks the field invalid."),
113
126
  disabled: z.boolean().optional(),
114
- };
127
+ }));
115
128
 
116
- const buttonVariant = z
117
- .enum(["primary", "secondary", "outline", "ghost", "soft", "destructive", "link"])
118
- .describe("Visual weight.");
129
+ const buttonVariant = /* @__PURE__ */ shakeable(() =>
130
+ z
131
+ .enum(["primary", "secondary", "outline", "ghost", "soft", "destructive", "link"])
132
+ .describe("Visual weight.")
133
+ );
119
134
 
120
- const buttonSize = z.enum(["sm", "md", "lg"]).describe("Control size.");
135
+ const buttonSize = /* @__PURE__ */ shakeable(() =>
136
+ z.enum(["sm", "md", "lg"]).describe("Control size.")
137
+ );
138
+
139
+ /**
140
+ * Root-relative means one slash and then a path. `//evil.example/x` is
141
+ * protocol-relative — the browser resolves it against the page's scheme and
142
+ * goes off-origin — and `/\evil.example` is the same trick, because browsers
143
+ * treat a backslash after the leading slash as a second slash.
144
+ */
145
+ const rootRelative = (value: string) =>
146
+ value.startsWith("/") && value[1] !== "/" && value[1] !== "\\";
121
147
 
122
148
  /**
123
149
  * A URL an agent may point at.
@@ -126,40 +152,46 @@ const buttonSize = z.enum(["sm", "md", "lg"]).describe("Control size.");
126
152
  * friends never reach the DOM because they never pass validation, so the
127
153
  * component gets an error card instead.
128
154
  */
129
- const httpUrl = z
130
- .string()
131
- .refine(
132
- (value) => /^https?:\/\//i.test(value) || value.startsWith("/") || value.startsWith("#"),
133
- "Must be an http(s), root-relative or fragment URL.",
134
- )
135
- .describe("Destination URL (http, https, root-relative or fragment).");
136
-
137
- const imageUrl = z
138
- .string()
139
- .refine(
140
- (value) => /^https?:\/\//i.test(value) || /^data:image\//i.test(value) || value.startsWith("/"),
141
- "Must be an http(s), root-relative or data:image URL.",
142
- )
143
- .describe("Image URL (http, https, root-relative or data:image).");
155
+ const httpUrl = /* @__PURE__ */ shakeable(() =>
156
+ z
157
+ .string()
158
+ .refine(
159
+ (value) => /^https?:\/\//i.test(value) || rootRelative(value) || value.startsWith("#"),
160
+ "Must be an http(s), root-relative or fragment URL.",
161
+ )
162
+ .describe("Destination URL (http, https, root-relative or fragment).")
163
+ );
164
+
165
+ const imageUrl = /* @__PURE__ */ shakeable(() =>
166
+ z
167
+ .string()
168
+ .refine(
169
+ (value) => /^https?:\/\//i.test(value) || /^data:image\//i.test(value) || rootRelative(value),
170
+ "Must be an http(s), root-relative or data:image URL.",
171
+ )
172
+ .describe("Image URL (http, https, root-relative or data:image).")
173
+ );
144
174
 
145
175
  /** Every chart type the Chart composite draws, Recharts and Nivo alike. */
146
- const chartType = z
147
- .enum([
148
- "bar",
149
- "line",
150
- "area",
151
- "pie",
152
- "donut",
153
- "scatter",
154
- "scatterplot",
155
- "radar",
156
- "funnel",
157
- "heatmap",
158
- "calendar",
159
- "treemap",
160
- "sunburst",
161
- ])
162
- .describe("Chart type; the package picks Recharts or Nivo for it.");
176
+ const chartType = /* @__PURE__ */ shakeable(() =>
177
+ z
178
+ .enum([
179
+ "bar",
180
+ "line",
181
+ "area",
182
+ "pie",
183
+ "donut",
184
+ "scatter",
185
+ "scatterplot",
186
+ "radar",
187
+ "funnel",
188
+ "heatmap",
189
+ "calendar",
190
+ "treemap",
191
+ "sunburst",
192
+ ])
193
+ .describe("Chart type; the package picks Recharts or Nivo for it.")
194
+ );
163
195
 
164
196
  /**
165
197
  * A table's rows, or a handle to them.
@@ -169,26 +201,29 @@ const chartType = z
169
201
  * it through `resolveDataSource`, so search, sort and paging stay on the backend
170
202
  * and a large result never travels through the model.
171
203
  */
172
- const tableSource = z
173
- .union([
174
- z.object({
175
- kind: z.literal("client"),
176
- rows: z.array(z.record(z.string(), z.unknown())).describe("The rows, inline."),
177
- }),
178
- z.object({
179
- kind: z.literal("server"),
180
- sourceId: z
181
- .string()
182
- .describe("Handle obtained from a tool; the host resolves it to a server source."),
183
- }),
184
- ])
185
- .describe("Where the table's rows come from.");
204
+ const tableSource = /* @__PURE__ */ shakeable(() =>
205
+ z
206
+ .union([
207
+ z.object({
208
+ kind: z.literal("client"),
209
+ rows: z.array(z.record(z.string(), z.unknown())).describe("The rows, inline."),
210
+ }),
211
+ z.object({
212
+ kind: z.literal("server"),
213
+ sourceId: z
214
+ .string()
215
+ .describe("Handle obtained from a tool; the host resolves it to a server source."),
216
+ }),
217
+ ])
218
+ .describe("Where the table's rows come from.")
219
+ );
220
+
186
221
 
187
222
  /* ------------------------------------------------------------------ */
188
223
  /* The catalogue */
189
224
  /* ------------------------------------------------------------------ */
190
225
 
191
- const layout = {
226
+ const layout = /* @__PURE__ */ shakeable(() => ({
192
227
  Column: entry<views.ColumnProps>({
193
228
  name: "Column",
194
229
  group: "layout",
@@ -295,9 +330,9 @@ const layout = {
295
330
  example: { components: [{ id: "spacer", component: "Spacer", size: 4 }] },
296
331
  view: views.SpacerView,
297
332
  }),
298
- };
333
+ }));
299
334
 
300
- const text = {
335
+ const text = /* @__PURE__ */ shakeable(() => ({
301
336
  Text: entry<views.TextProps>({
302
337
  name: "Text",
303
338
  group: "text",
@@ -347,9 +382,9 @@ const text = {
347
382
  },
348
383
  view: views.MarkdownView,
349
384
  }),
350
- };
385
+ }));
351
386
 
352
- const input = {
387
+ const input = /* @__PURE__ */ shakeable(() => ({
353
388
  TextField: entry<views.TextFieldProps>({
354
389
  name: "TextField",
355
390
  group: "input",
@@ -620,9 +655,9 @@ const input = {
620
655
  },
621
656
  view: views.ButtonLinkView,
622
657
  }),
623
- };
658
+ }));
624
659
 
625
- const feedback = {
660
+ const feedback = /* @__PURE__ */ shakeable(() => ({
626
661
  Badge: entry<views.BadgeViewProps>({
627
662
  name: "Badge",
628
663
  group: "feedback",
@@ -736,9 +771,9 @@ const feedback = {
736
771
  },
737
772
  view: views.EmptyStateView,
738
773
  }),
739
- };
774
+ }));
740
775
 
741
- const data = {
776
+ const data = /* @__PURE__ */ shakeable(() => ({
742
777
  DataTable: entry<views.DataTableViewProps>({
743
778
  name: "DataTable",
744
779
  group: "data",
@@ -835,9 +870,9 @@ const data = {
835
870
  },
836
871
  view: views.ChartView,
837
872
  }),
838
- };
873
+ }));
839
874
 
840
- const other = {
875
+ const other = /* @__PURE__ */ shakeable(() => ({
841
876
  Tabs: entry<views.TabsViewProps>({
842
877
  name: "Tabs",
843
878
  group: "layout",
@@ -923,7 +958,7 @@ const other = {
923
958
  },
924
959
  view: views.LinkView,
925
960
  }),
926
- };
961
+ }));
927
962
 
928
963
  /**
929
964
  * The catalogue an agent draws from, and the renderer's default.
@@ -932,14 +967,16 @@ const other = {
932
967
  * with components the prompt does not describe: an agent can only usefully
933
968
  * emit what `catalogue-doc.ts` told it about.
934
969
  */
935
- export const defaultCatalogue: A2UICatalogue = Object.freeze({
936
- ...layout,
937
- ...text,
938
- ...input,
939
- ...feedback,
940
- ...data,
941
- ...other,
942
- });
970
+ export const defaultCatalogue: A2UICatalogue = /* @__PURE__ */ shakeable(() =>
971
+ Object.freeze({
972
+ ...layout,
973
+ ...text,
974
+ ...input,
975
+ ...feedback,
976
+ ...data,
977
+ ...other,
978
+ }),
979
+ );
943
980
 
944
981
  /** Catalogue id an agent may echo in `createSurface.catalogId`. */
945
982
  export const A2UI_CATALOGUE_ID = "https://cortena.ai/a2ui/catalogues/cortena-ui/v1.json";
@@ -25,8 +25,11 @@ import { Badge } from "@/components/badge";
25
25
  import { Button } from "@/components/button";
26
26
  import { ButtonLink } from "@/components/button-link";
27
27
  import { Card, CardContent } from "@/components/card";
28
- import { Chart } from "@/components/chart";
29
- import type { ChartDataFor, ChartType } from "@/components/chart";
28
+ // Straight at the composite, not at `@/components/chart`: the chart module's
29
+ // index re-exports the raw Recharts primitives, and reaching the catalogue
30
+ // through it puts them in A2UI's static graph for nothing.
31
+ import { Chart } from "@/components/chart/chart";
32
+ import type { ChartDataFor, ChartType } from "@/components/chart/types";
30
33
  import { Checkbox } from "@/components/checkbox";
31
34
  import { DataTable } from "@/components/data-table";
32
35
  import type { DataSource, DataTableColumnDef } from "@/components/data-table";
@@ -15,7 +15,7 @@ import { cn } from "@/lib/cn";
15
15
  const DESTRUCTIVE_ALERT =
16
16
  "bg-[var(--ds-destructive-soft)] border-[var(--ds-destructive)]/35 [&_[data-slot=alert-icon]]:text-[color:var(--ds-destructive)]";
17
17
 
18
- const alertVariants = cva(
18
+ const alertVariants = /* @__PURE__ */ cva(
19
19
  [
20
20
  "flex gap-3 rounded-[var(--ds-radius-md)] border px-3.5 py-3",
21
21
  "text-[length:var(--ds-text-caption-lg)] leading-[var(--ds-text-caption-lg--line-height)]",
@@ -12,7 +12,7 @@ import { cn } from "@/lib/cn";
12
12
  */
13
13
  const DESTRUCTIVE_BADGE = "bg-[var(--ds-destructive-soft)] text-[color:var(--ds-destructive)]";
14
14
 
15
- const badgeVariants = cva(
15
+ const badgeVariants = /* @__PURE__ */ cva(
16
16
  [
17
17
  "inline-flex items-center gap-1.5 px-1.5 py-0.5 whitespace-nowrap",
18
18
  "rounded-[var(--ds-radius-sm)]",
@@ -15,7 +15,7 @@ import { cn } from "@/lib/cn";
15
15
  * Radix users: `asChild` is gone. Pass `render={<a href=... />}` to change the
16
16
  * rendered element, which is Base UI's equivalent.
17
17
  */
18
- const buttonVariants = cva(
18
+ const buttonVariants = /* @__PURE__ */ cva(
19
19
  [
20
20
  "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap",
21
21
  "font-medium",