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,400 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../../lib/cn.js";
4
+ import { Button } from "../button.js";
5
+ import { Input } from "../input.js";
6
+ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "../dropdown-menu.js";
7
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../select.js";
8
+ import { columnLabel, downloadCsv, downloadExcel } from "./export.js";
9
+ import { ArrowDown, ArrowUp, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, ChevronsUpDown, Download, EyeOff, ListFilter, PinOff, Search, Settings2, X } from "lucide-react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import "react";
12
+ //#region src/components/data-table/parts.tsx
13
+ /**
14
+ * Header content for one column: the title as a sort toggle when the column
15
+ * sorts, and a menu with sort, pin and hide when any of those apply. The
16
+ * table renders it for every string `header` automatically; use it inside a
17
+ * custom header function to keep the same affordances.
18
+ */
19
+ function DataTableColumnHeader({ column, title, className, ...props }) {
20
+ const canSort = column.getCanSort();
21
+ const canHide = column.getCanHide();
22
+ const canPin = column.getCanPin();
23
+ const sorted = column.getIsSorted();
24
+ const align = column.columnDef.meta?.align ?? "start";
25
+ if (!canSort && !canHide && !canPin) return /* @__PURE__ */ jsx("div", {
26
+ "data-slot": "data-table-column-header",
27
+ className: cn("truncate", className),
28
+ ...props,
29
+ children: title
30
+ });
31
+ const label = typeof title === "string" ? title : columnLabel(column);
32
+ return /* @__PURE__ */ jsxs("div", {
33
+ "data-slot": "data-table-column-header",
34
+ className: cn("group/header -mx-2 flex min-w-0 items-center", align === "end" ? "justify-end group-hover/head:pl-6" : "group-hover/head:pr-6", align === "center" && "justify-center", className),
35
+ ...props,
36
+ children: [/* @__PURE__ */ jsxs("button", {
37
+ type: "button",
38
+ "data-slot": "data-table-sort",
39
+ disabled: !canSort,
40
+ onClick: canSort ? column.getToggleSortingHandler() : void 0,
41
+ "aria-label": canSort ? sorted ? `Sort by ${label}, sorted ${sorted === "asc" ? "ascending" : "descending"}` : `Sort by ${label}` : void 0,
42
+ className: cn("inline-flex h-7 min-w-0 items-center gap-1 rounded-[var(--ds-radius-sm)] px-2 outline-none", "text-inherit transition-colors duration-[var(--ds-duration-fast)]", canSort && "hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]", "focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40", "disabled:cursor-default"),
43
+ children: [/* @__PURE__ */ jsx("span", {
44
+ className: "truncate",
45
+ children: title
46
+ }), canSort ? sorted === "asc" ? /* @__PURE__ */ jsx(ArrowUp, {
47
+ "aria-hidden": true,
48
+ className: "size-3.5 shrink-0 text-[color:var(--ds-primary)]"
49
+ }) : sorted === "desc" ? /* @__PURE__ */ jsx(ArrowDown, {
50
+ "aria-hidden": true,
51
+ className: "size-3.5 shrink-0 text-[color:var(--ds-primary)]"
52
+ }) : /* @__PURE__ */ jsx(ChevronsUpDown, {
53
+ "aria-hidden": true,
54
+ className: "hidden size-3.5 shrink-0 opacity-60 group-hover/head:inline-block"
55
+ }) : null]
56
+ }), /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
57
+ "aria-label": `${label} column options`,
58
+ className: cn("absolute top-1/2 z-[1] inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-[var(--ds-radius-sm)] outline-none", align === "end" ? "left-1" : "right-1", "bg-[var(--ds-muted)] opacity-0 transition-opacity duration-[var(--ds-duration-fast)]", "group-hover/head:opacity-100 focus-visible:opacity-100 data-[popup-open]:opacity-100", "hover:bg-[var(--ds-hover)] focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40"),
59
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-3.5" })
60
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
61
+ align: align === "end" ? "end" : "start",
62
+ children: [
63
+ canSort ? /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
64
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
65
+ onClick: () => column.toggleSorting(false),
66
+ children: [/* @__PURE__ */ jsx(ArrowUp, {}), " Sort ascending"]
67
+ }),
68
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
69
+ onClick: () => column.toggleSorting(true),
70
+ children: [/* @__PURE__ */ jsx(ArrowDown, {}), " Sort descending"]
71
+ }),
72
+ sorted ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
73
+ onClick: () => column.clearSorting(),
74
+ children: [/* @__PURE__ */ jsx(ChevronsUpDown, {}), " Clear sort"]
75
+ }) : null
76
+ ] }) : null,
77
+ canSort && (canPin || canHide) ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
78
+ canPin ? /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
79
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
80
+ onClick: () => column.pin("start"),
81
+ children: [/* @__PURE__ */ jsx(ChevronsLeft, {}), " Pin left"]
82
+ }),
83
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
84
+ onClick: () => column.pin("end"),
85
+ children: [/* @__PURE__ */ jsx(ChevronsRight, {}), " Pin right"]
86
+ }),
87
+ column.getIsPinned() ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
88
+ onClick: () => column.pin(false),
89
+ children: [/* @__PURE__ */ jsx(PinOff, {}), " Unpin"]
90
+ }) : null
91
+ ] }) : null,
92
+ canPin && canHide ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
93
+ canHide ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
94
+ onClick: () => column.toggleVisibility(false),
95
+ children: [/* @__PURE__ */ jsx(EyeOff, {}), " Hide column"]
96
+ }) : null
97
+ ]
98
+ })] })]
99
+ });
100
+ }
101
+ /**
102
+ * A checkbox list of a column's values. The filter value is the array of
103
+ * picked values; the column's `filterFn` (`oneOf` by default for
104
+ * `meta.filter: "faceted"`) decides what that means, and a server source
105
+ * receives it verbatim in `TableQuery.filters`.
106
+ */
107
+ function DataTableFacetedFilter({ column, title, options, className }) {
108
+ const raw = column.getFilterValue();
109
+ const selected = new Set(Array.isArray(raw) ? raw : raw == null ? [] : [raw]);
110
+ const facets = options ? null : column.getFacetedUniqueValues();
111
+ const items = options ?? column.columnDef.meta?.filterOptions ?? Array.from(facets?.keys() ?? []).filter((v) => v != null && typeof v !== "object").sort((a, b) => String(a).localeCompare(String(b))).map((value) => ({ value }));
112
+ const label = title ?? columnLabel(column);
113
+ const toggle = (value, checked) => {
114
+ const next = new Set(selected);
115
+ if (checked) next.add(value);
116
+ else next.delete(value);
117
+ column.setFilterValue(next.size ? Array.from(next) : void 0);
118
+ };
119
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
120
+ "data-slot": "data-table-faceted-filter",
121
+ render: /* @__PURE__ */ jsx(Button, {
122
+ variant: "outline",
123
+ size: "sm",
124
+ className: cn("border-dashed", className)
125
+ }),
126
+ children: [
127
+ /* @__PURE__ */ jsx(ListFilter, {}),
128
+ label,
129
+ selected.size ? /* @__PURE__ */ jsx("span", {
130
+ "data-slot": "data-table-filter-count",
131
+ className: cn("ml-1 inline-flex h-5 min-w-5 items-center justify-center rounded-[var(--ds-radius-sm)] px-1.5", "bg-[var(--ds-primary-soft)] text-[length:var(--ds-text-caption-sm)] font-medium text-[color:var(--ds-primary-soft-foreground)]"),
132
+ children: selected.size
133
+ }) : null
134
+ ]
135
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
136
+ align: "start",
137
+ className: "max-h-80 min-w-48 overflow-y-auto",
138
+ children: [/* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
139
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { children: label }),
140
+ items.length === 0 ? /* @__PURE__ */ jsx("div", {
141
+ className: "px-2 py-1.5 text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]",
142
+ children: "No values"
143
+ }) : null,
144
+ items.map((item) => {
145
+ const Icon = item.icon;
146
+ const count = facets?.get(item.value);
147
+ return /* @__PURE__ */ jsxs(DropdownMenuCheckboxItem, {
148
+ closeOnClick: false,
149
+ checked: selected.has(item.value),
150
+ onCheckedChange: (checked) => toggle(item.value, checked),
151
+ children: [
152
+ Icon ? /* @__PURE__ */ jsx(Icon, { className: "size-4 text-[color:var(--ds-muted-foreground)]" }) : null,
153
+ /* @__PURE__ */ jsx("span", {
154
+ className: "flex-1 truncate",
155
+ children: item.label ?? String(item.value)
156
+ }),
157
+ count !== void 0 ? /* @__PURE__ */ jsx("span", {
158
+ className: "ml-auto font-[family-name:var(--ds-font-mono)] text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]",
159
+ children: count
160
+ }) : null
161
+ ]
162
+ }, String(item.value));
163
+ })
164
+ ] }), selected.size ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsx(DropdownMenuItem, {
165
+ onClick: () => column.setFilterValue(void 0),
166
+ className: "justify-center",
167
+ children: "Clear filter"
168
+ })] }) : null]
169
+ })] });
170
+ }
171
+ /** Column visibility menu. */
172
+ function DataTableViewOptions({ table, className }) {
173
+ const columns = table.getAllLeafColumns().filter((c) => c.getCanHide());
174
+ if (columns.length === 0) return null;
175
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
176
+ "data-slot": "data-table-view-options",
177
+ "aria-label": "Toggle columns",
178
+ render: /* @__PURE__ */ jsx(Button, {
179
+ variant: "outline",
180
+ size: "sm",
181
+ className
182
+ }),
183
+ children: [/* @__PURE__ */ jsx(Settings2, {}), "View"]
184
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
185
+ align: "end",
186
+ className: "max-h-80 min-w-40 overflow-y-auto",
187
+ children: [/* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Toggle columns" }), columns.map((column) => /* @__PURE__ */ jsx(DropdownMenuCheckboxItem, {
188
+ closeOnClick: false,
189
+ checked: column.getIsVisible(),
190
+ onCheckedChange: (checked) => column.toggleVisibility(checked),
191
+ children: columnLabel(column)
192
+ }, column.id))] }), !table.getIsAllColumnsVisible() ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsx(DropdownMenuItem, {
193
+ onClick: () => table.toggleAllColumnsVisible(true),
194
+ children: "Show all"
195
+ })] }) : null]
196
+ })] });
197
+ }
198
+ function DataTableExportMenu({ table, fileName, className }) {
199
+ const selected = table.getSelectedRowModel().rows;
200
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
201
+ "data-slot": "data-table-export",
202
+ "aria-label": "Export",
203
+ render: /* @__PURE__ */ jsx(Button, {
204
+ variant: "outline",
205
+ size: "sm",
206
+ className
207
+ }),
208
+ children: [/* @__PURE__ */ jsx(Download, {}), "Export"]
209
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
210
+ align: "end",
211
+ children: [
212
+ /* @__PURE__ */ jsx(DropdownMenuItem, {
213
+ onClick: () => downloadCsv(table, fileName),
214
+ children: "CSV"
215
+ }),
216
+ /* @__PURE__ */ jsx(DropdownMenuItem, {
217
+ onClick: () => void downloadExcel(table, fileName),
218
+ children: "Excel"
219
+ }),
220
+ selected.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
221
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
222
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
223
+ onClick: () => downloadCsv(table, fileName, selected),
224
+ children: [
225
+ "CSV of ",
226
+ selected.length,
227
+ " selected"
228
+ ]
229
+ }),
230
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
231
+ onClick: () => void downloadExcel(table, fileName, selected),
232
+ children: [
233
+ "Excel of ",
234
+ selected.length,
235
+ " selected"
236
+ ]
237
+ })
238
+ ] }) : null
239
+ ]
240
+ })] });
241
+ }
242
+ /**
243
+ * Search box, one faceted filter per `meta.filter: "faceted"` column, a reset
244
+ * when anything is filtered, and the view / export menus. While rows are
245
+ * selected the left side becomes the selection summary and `bulkActions`.
246
+ */
247
+ function DataTableToolbar({ table, searchPlaceholder = "Search…", bulkActions, children, enableExport = true, exportFileName, className, ...props }) {
248
+ const globalFilter = table.state.globalFilter ?? "";
249
+ const canSearch = table.options.enableGlobalFilter !== false;
250
+ const facetedColumns = table.getAllLeafColumns().filter((c) => c.columnDef.meta?.filter === "faceted" && c.getCanFilter());
251
+ const isFiltered = table.state.columnFilters.length > 0 || globalFilter !== "";
252
+ const selectedRows = table.options.enableRowSelection ? table.getSelectedRowModel().rows : [];
253
+ return /* @__PURE__ */ jsxs("div", {
254
+ "data-slot": "data-table-toolbar",
255
+ className: cn("flex flex-wrap items-center gap-2", className),
256
+ ...props,
257
+ children: [selectedRows.length ? /* @__PURE__ */ jsxs("div", {
258
+ "data-slot": "data-table-bulk-actions",
259
+ className: "flex min-w-0 flex-1 flex-wrap items-center gap-2",
260
+ children: [
261
+ /* @__PURE__ */ jsxs("span", {
262
+ className: "text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]",
263
+ children: [/* @__PURE__ */ jsx("span", {
264
+ className: "font-medium text-[color:var(--ds-foreground)]",
265
+ children: selectedRows.length
266
+ }), " selected"]
267
+ }),
268
+ bulkActions?.({
269
+ rows: selectedRows.map((r) => r.original),
270
+ table
271
+ }),
272
+ /* @__PURE__ */ jsxs(Button, {
273
+ variant: "ghost",
274
+ size: "sm",
275
+ onClick: () => table.resetRowSelection(),
276
+ children: ["Clear", /* @__PURE__ */ jsx(X, {})]
277
+ })
278
+ ]
279
+ }) : /* @__PURE__ */ jsxs("div", {
280
+ className: "flex min-w-0 flex-1 flex-wrap items-center gap-2",
281
+ children: [
282
+ canSearch ? /* @__PURE__ */ jsxs("div", {
283
+ className: "relative w-full max-w-64",
284
+ children: [/* @__PURE__ */ jsx(Search, {
285
+ "aria-hidden": true,
286
+ className: "pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-[color:var(--ds-text-tertiary)]"
287
+ }), /* @__PURE__ */ jsx(Input, {
288
+ "data-slot": "data-table-search",
289
+ type: "search",
290
+ "aria-label": "Search",
291
+ placeholder: searchPlaceholder,
292
+ value: globalFilter,
293
+ onChange: (e) => table.setGlobalFilter(e.target.value),
294
+ className: "h-8 pl-8 text-[length:var(--ds-text-caption-lg)]"
295
+ })]
296
+ }) : null,
297
+ facetedColumns.map((column) => /* @__PURE__ */ jsx(DataTableFacetedFilter, { column }, column.id)),
298
+ isFiltered ? /* @__PURE__ */ jsxs(Button, {
299
+ variant: "ghost",
300
+ size: "sm",
301
+ onClick: () => {
302
+ table.resetColumnFilters();
303
+ table.setGlobalFilter("");
304
+ },
305
+ children: ["Reset", /* @__PURE__ */ jsx(X, {})]
306
+ }) : null
307
+ ]
308
+ }), /* @__PURE__ */ jsxs("div", {
309
+ className: "flex items-center gap-2",
310
+ children: [
311
+ children,
312
+ /* @__PURE__ */ jsx(DataTableViewOptions, { table }),
313
+ enableExport ? /* @__PURE__ */ jsx(DataTableExportMenu, {
314
+ table,
315
+ fileName: exportFileName
316
+ }) : null
317
+ ]
318
+ })]
319
+ });
320
+ }
321
+ const DEFAULT_PAGE_SIZES = [
322
+ 10,
323
+ 25,
324
+ 50,
325
+ 100
326
+ ];
327
+ function DataTablePagination({ table, pageSizeOptions = DEFAULT_PAGE_SIZES, className, ...props }) {
328
+ const { pageIndex, pageSize } = table.state.pagination;
329
+ const total = table.getRowCount();
330
+ const pageCount = table.getPageCount();
331
+ const from = total === 0 ? 0 : pageIndex * pageSize + 1;
332
+ const to = Math.min(total, (pageIndex + 1) * pageSize);
333
+ const sizeItems = (pageSizeOptions.includes(pageSize) ? pageSizeOptions : [...pageSizeOptions, pageSize].sort((a, b) => a - b)).map((s) => ({
334
+ value: String(s),
335
+ label: String(s)
336
+ }));
337
+ const navButton = (label, icon, onClick, disabled) => /* @__PURE__ */ jsx(Button, {
338
+ variant: "outline",
339
+ size: "icon-sm",
340
+ "aria-label": label,
341
+ onClick,
342
+ disabled,
343
+ children: icon
344
+ });
345
+ return /* @__PURE__ */ jsxs("div", {
346
+ "data-slot": "data-table-pagination",
347
+ className: cn("flex flex-wrap items-center justify-between gap-3", "text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]", className),
348
+ ...props,
349
+ children: [/* @__PURE__ */ jsxs("div", {
350
+ className: "flex items-center gap-2",
351
+ children: [/* @__PURE__ */ jsx("span", { children: "Rows per page" }), /* @__PURE__ */ jsxs(Select, {
352
+ items: sizeItems,
353
+ value: String(pageSize),
354
+ onValueChange: (value) => table.setPageSize(Number(value)),
355
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
356
+ size: "sm",
357
+ "aria-label": "Rows per page",
358
+ className: "min-w-0 w-[4.5rem]",
359
+ children: /* @__PURE__ */ jsx(SelectValue, {})
360
+ }), /* @__PURE__ */ jsx(SelectContent, { children: sizeItems.map((item) => /* @__PURE__ */ jsx(SelectItem, {
361
+ value: item.value,
362
+ children: item.label
363
+ }, item.value)) })]
364
+ })]
365
+ }), /* @__PURE__ */ jsxs("div", {
366
+ className: "flex items-center gap-4",
367
+ children: [/* @__PURE__ */ jsxs("span", {
368
+ "data-slot": "data-table-range",
369
+ "aria-live": "polite",
370
+ children: [
371
+ from,
372
+ "–",
373
+ to,
374
+ " of ",
375
+ total
376
+ ]
377
+ }), /* @__PURE__ */ jsxs("div", {
378
+ className: "flex items-center gap-1",
379
+ children: [
380
+ navButton("First page", /* @__PURE__ */ jsx(ChevronsLeft, {}), () => table.firstPage(), !table.getCanPreviousPage()),
381
+ navButton("Previous page", /* @__PURE__ */ jsx(ChevronLeft, {}), () => table.previousPage(), !table.getCanPreviousPage()),
382
+ /* @__PURE__ */ jsxs("span", {
383
+ className: "px-1 tabular-nums",
384
+ children: [
385
+ pageCount === 0 ? 0 : pageIndex + 1,
386
+ " / ",
387
+ pageCount
388
+ ]
389
+ }),
390
+ navButton("Next page", /* @__PURE__ */ jsx(ChevronRight, {}), () => table.nextPage(), !table.getCanNextPage()),
391
+ navButton("Last page", /* @__PURE__ */ jsx(ChevronsRight, {}), () => table.lastPage(), !table.getCanNextPage())
392
+ ]
393
+ })]
394
+ })]
395
+ });
396
+ }
397
+ //#endregion
398
+ export { DataTableColumnHeader, DataTableExportMenu, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions };
399
+
400
+ //# sourceMappingURL=parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts.js","names":[],"sources":["../../../src/components/data-table/parts.tsx"],"sourcesContent":["\"use client\";\n\nimport type { RowData } from \"@tanstack/react-table\";\nimport {\n ArrowDown,\n ArrowUp,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n ChevronsUpDown,\n Download,\n EyeOff,\n ListFilter,\n PinOff,\n Search,\n Settings2,\n X,\n} from \"lucide-react\";\nimport * as React from \"react\";\nimport { Button } from \"@/components/button\";\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/dropdown-menu\";\nimport { Input } from \"@/components/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@/components/select\";\nimport { cn } from \"@/lib/cn\";\nimport { columnLabel, downloadCsv, downloadExcel } from \"./export\";\nimport type { DataTableColumn, DataTableTable } from \"./types\";\n\n/* ------------------------------------------------------------------------ */\n/* Column header */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTableColumnHeaderProps<Row extends RowData>\n extends Omit<React.ComponentProps<\"div\">, \"title\"> {\n column: DataTableColumn<Row, any>;\n title: React.ReactNode;\n}\n\n/**\n * Header content for one column: the title as a sort toggle when the column\n * sorts, and a menu with sort, pin and hide when any of those apply. The\n * table renders it for every string `header` automatically; use it inside a\n * custom header function to keep the same affordances.\n */\nfunction DataTableColumnHeader<Row extends RowData>({\n column,\n title,\n className,\n ...props\n}: DataTableColumnHeaderProps<Row>) {\n const canSort = column.getCanSort();\n const canHide = column.getCanHide();\n const canPin = column.getCanPin();\n const sorted = column.getIsSorted();\n const align = column.columnDef.meta?.align ?? \"start\";\n\n if (!canSort && !canHide && !canPin) {\n return (\n <div data-slot=\"data-table-column-header\" className={cn(\"truncate\", className)} {...props}>\n {title}\n </div>\n );\n }\n\n const label = typeof title === \"string\" ? title : columnLabel(column);\n\n return (\n <div\n data-slot=\"data-table-column-header\"\n className={cn(\n \"group/header -mx-2 flex min-w-0 items-center\",\n // Leave room for the floating options trigger only while it shows;\n // anchored text does not move, it truncates if it must.\n align === \"end\" ? \"justify-end group-hover/head:pl-6\" : \"group-hover/head:pr-6\",\n align === \"center\" && \"justify-center\",\n className,\n )}\n {...props}\n >\n <button\n type=\"button\"\n data-slot=\"data-table-sort\"\n disabled={!canSort}\n onClick={canSort ? column.getToggleSortingHandler() : undefined}\n // Without a name of its own the button announces as just the column\n // title, which tells a screen-reader user the word \"Name\" and nothing\n // about there being a control or what it would do. The `aria-sort` on\n // the `<th>` (data-table.tsx) states the column's current order; this\n // states the action, and repeats the order because a button reached by\n // tabbing is not necessarily read with its header cell. Only when the\n // column sorts: on a column that only hides or pins, the button is\n // disabled and \"Sort by\" would be a lie.\n aria-label={\n canSort\n ? sorted\n ? `Sort by ${label}, sorted ${sorted === \"asc\" ? \"ascending\" : \"descending\"}`\n : `Sort by ${label}`\n : undefined\n }\n className={cn(\n \"inline-flex h-7 min-w-0 items-center gap-1 rounded-[var(--ds-radius-sm)] px-2 outline-none\",\n \"text-inherit transition-colors duration-[var(--ds-duration-fast)]\",\n canSort && \"hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]\",\n \"focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40\",\n \"disabled:cursor-default\",\n )}\n >\n <span className=\"truncate\">{title}</span>\n {canSort ? (\n sorted === \"asc\" ? (\n <ArrowUp aria-hidden className=\"size-3.5 shrink-0 text-[color:var(--ds-primary)]\" />\n ) : sorted === \"desc\" ? (\n <ArrowDown aria-hidden className=\"size-3.5 shrink-0 text-[color:var(--ds-primary)]\" />\n ) : (\n // Out of flow until hover so narrow headers keep their full title.\n <ChevronsUpDown\n aria-hidden\n className=\"hidden size-3.5 shrink-0 opacity-60 group-hover/head:inline-block\"\n />\n )\n ) : null}\n </button>\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={`${label} column options`}\n className={cn(\n // Floats over the cell edge so it costs the title no width.\n \"absolute top-1/2 z-[1] inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-[var(--ds-radius-sm)] outline-none\",\n align === \"end\" ? \"left-1\" : \"right-1\",\n \"bg-[var(--ds-muted)] opacity-0 transition-opacity duration-[var(--ds-duration-fast)]\",\n \"group-hover/head:opacity-100 focus-visible:opacity-100 data-[popup-open]:opacity-100\",\n \"hover:bg-[var(--ds-hover)] focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40\",\n )}\n >\n <ChevronDown className=\"size-3.5\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align={align === \"end\" ? \"end\" : \"start\"}>\n {canSort ? (\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={() => column.toggleSorting(false)}>\n <ArrowUp /> Sort ascending\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => column.toggleSorting(true)}>\n <ArrowDown /> Sort descending\n </DropdownMenuItem>\n {sorted ? (\n <DropdownMenuItem onClick={() => column.clearSorting()}>\n <ChevronsUpDown /> Clear sort\n </DropdownMenuItem>\n ) : null}\n </DropdownMenuGroup>\n ) : null}\n {canSort && (canPin || canHide) ? <DropdownMenuSeparator /> : null}\n {canPin ? (\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={() => column.pin(\"start\")}>\n <ChevronsLeft /> Pin left\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => column.pin(\"end\")}>\n <ChevronsRight /> Pin right\n </DropdownMenuItem>\n {column.getIsPinned() ? (\n <DropdownMenuItem onClick={() => column.pin(false)}>\n <PinOff /> Unpin\n </DropdownMenuItem>\n ) : null}\n </DropdownMenuGroup>\n ) : null}\n {canPin && canHide ? <DropdownMenuSeparator /> : null}\n {canHide ? (\n <DropdownMenuItem onClick={() => column.toggleVisibility(false)}>\n <EyeOff /> Hide column\n </DropdownMenuItem>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------------ */\n/* Faceted filter */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTableFacetedFilterOption {\n value: string | number | boolean;\n label?: string;\n icon?: React.ComponentType<{ className?: string }>;\n}\n\nexport interface DataTableFacetedFilterProps<Row extends RowData> {\n column: DataTableColumn<Row, any>;\n title?: React.ReactNode;\n /** Fixed options; defaults to the column's distinct values with counts (client source only). */\n options?: DataTableFacetedFilterOption[];\n className?: string;\n}\n\n/**\n * A checkbox list of a column's values. The filter value is the array of\n * picked values; the column's `filterFn` (`oneOf` by default for\n * `meta.filter: \"faceted\"`) decides what that means, and a server source\n * receives it verbatim in `TableQuery.filters`.\n */\nfunction DataTableFacetedFilter<Row extends RowData>({\n column,\n title,\n options,\n className,\n}: DataTableFacetedFilterProps<Row>) {\n const raw = column.getFilterValue();\n const selected = new Set<unknown>(Array.isArray(raw) ? raw : raw == null ? [] : [raw]);\n const facets = options ? null : column.getFacetedUniqueValues();\n const items: DataTableFacetedFilterOption[] =\n options ??\n column.columnDef.meta?.filterOptions ??\n Array.from(facets?.keys() ?? [])\n .filter((v): v is string | number | boolean => v != null && typeof v !== \"object\")\n .sort((a, b) => String(a).localeCompare(String(b)))\n .map((value) => ({ value }));\n const label = title ?? columnLabel(column);\n\n const toggle = (value: unknown, checked: boolean) => {\n const next = new Set(selected);\n if (checked) next.add(value);\n else next.delete(value);\n column.setFilterValue(next.size ? Array.from(next) : undefined);\n };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n data-slot=\"data-table-faceted-filter\"\n render={<Button variant=\"outline\" size=\"sm\" className={cn(\"border-dashed\", className)} />}\n >\n <ListFilter />\n {label}\n {selected.size ? (\n <span\n data-slot=\"data-table-filter-count\"\n className={cn(\n \"ml-1 inline-flex h-5 min-w-5 items-center justify-center rounded-[var(--ds-radius-sm)] px-1.5\",\n \"bg-[var(--ds-primary-soft)] text-[length:var(--ds-text-caption-sm)] font-medium text-[color:var(--ds-primary-soft-foreground)]\",\n )}\n >\n {selected.size}\n </span>\n ) : null}\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"max-h-80 min-w-48 overflow-y-auto\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>{label}</DropdownMenuLabel>\n {items.length === 0 ? (\n <div className=\"px-2 py-1.5 text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]\">\n No values\n </div>\n ) : null}\n {items.map((item) => {\n const Icon = item.icon;\n const count = facets?.get(item.value);\n return (\n <DropdownMenuCheckboxItem\n key={String(item.value)}\n closeOnClick={false}\n checked={selected.has(item.value)}\n onCheckedChange={(checked) => toggle(item.value, checked)}\n >\n {Icon ? <Icon className=\"size-4 text-[color:var(--ds-muted-foreground)]\" /> : null}\n <span className=\"flex-1 truncate\">{item.label ?? String(item.value)}</span>\n {count !== undefined ? (\n <span className=\"ml-auto font-[family-name:var(--ds-font-mono)] text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]\">\n {count}\n </span>\n ) : null}\n </DropdownMenuCheckboxItem>\n );\n })}\n </DropdownMenuGroup>\n {selected.size ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={() => column.setFilterValue(undefined)} className=\"justify-center\">\n Clear filter\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/* ------------------------------------------------------------------------ */\n/* View options */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTableViewOptionsProps<Row extends RowData> {\n table: DataTableTable<Row>;\n className?: string;\n}\n\n/** Column visibility menu. */\nfunction DataTableViewOptions<Row extends RowData>({ table, className }: DataTableViewOptionsProps<Row>) {\n const columns = table.getAllLeafColumns().filter((c) => c.getCanHide());\n if (columns.length === 0) return null;\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n data-slot=\"data-table-view-options\"\n aria-label=\"Toggle columns\"\n render={<Button variant=\"outline\" size=\"sm\" className={className} />}\n >\n <Settings2 />\n View\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"max-h-80 min-w-40 overflow-y-auto\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n {columns.map((column) => (\n <DropdownMenuCheckboxItem\n key={column.id}\n closeOnClick={false}\n checked={column.getIsVisible()}\n onCheckedChange={(checked) => column.toggleVisibility(checked)}\n >\n {columnLabel(column)}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuGroup>\n {!table.getIsAllColumnsVisible() ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={() => table.toggleAllColumnsVisible(true)}>Show all</DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/* ------------------------------------------------------------------------ */\n/* Export menu */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTableExportMenuProps<Row extends RowData> {\n table: DataTableTable<Row>;\n fileName?: string;\n className?: string;\n}\n\nfunction DataTableExportMenu<Row extends RowData>({ table, fileName, className }: DataTableExportMenuProps<Row>) {\n const selected = table.getSelectedRowModel().rows;\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n data-slot=\"data-table-export\"\n aria-label=\"Export\"\n render={<Button variant=\"outline\" size=\"sm\" className={className} />}\n >\n <Download />\n Export\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => downloadCsv(table, fileName)}>CSV</DropdownMenuItem>\n <DropdownMenuItem onClick={() => void downloadExcel(table, fileName)}>Excel</DropdownMenuItem>\n {selected.length ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={() => downloadCsv(table, fileName, selected)}>\n CSV of {selected.length} selected\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => void downloadExcel(table, fileName, selected)}>\n Excel of {selected.length} selected\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/* ------------------------------------------------------------------------ */\n/* Toolbar */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTableToolbarProps<Row extends RowData>\n extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n table: DataTableTable<Row>;\n /** Placeholder for the search box. @default \"Search…\" */\n searchPlaceholder?: string;\n /** Rendered while rows are selected, in place of the filters. */\n bulkActions?: (ctx: { rows: Row[]; table: DataTableTable<Row> }) => React.ReactNode;\n /** Extra controls on the right, before the view and export menus. */\n children?: React.ReactNode;\n /** @default true */\n enableExport?: boolean;\n exportFileName?: string;\n}\n\n/**\n * Search box, one faceted filter per `meta.filter: \"faceted\"` column, a reset\n * when anything is filtered, and the view / export menus. While rows are\n * selected the left side becomes the selection summary and `bulkActions`.\n */\nfunction DataTableToolbar<Row extends RowData>({\n table,\n searchPlaceholder = \"Search…\",\n bulkActions,\n children,\n enableExport = true,\n exportFileName,\n className,\n ...props\n}: DataTableToolbarProps<Row>) {\n const globalFilter = (table.state.globalFilter as string | undefined) ?? \"\";\n const canSearch = table.options.enableGlobalFilter !== false;\n const facetedColumns = table\n .getAllLeafColumns()\n .filter((c) => c.columnDef.meta?.filter === \"faceted\" && c.getCanFilter());\n const isFiltered = table.state.columnFilters.length > 0 || globalFilter !== \"\";\n const selectedRows = table.options.enableRowSelection ? table.getSelectedRowModel().rows : [];\n\n return (\n <div\n data-slot=\"data-table-toolbar\"\n className={cn(\"flex flex-wrap items-center gap-2\", className)}\n {...props}\n >\n {selectedRows.length ? (\n <div data-slot=\"data-table-bulk-actions\" className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n <span className=\"text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]\">\n <span className=\"font-medium text-[color:var(--ds-foreground)]\">{selectedRows.length}</span> selected\n </span>\n {bulkActions?.({ rows: selectedRows.map((r) => r.original), table })}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => table.resetRowSelection()}>\n Clear\n <X />\n </Button>\n </div>\n ) : (\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n {canSearch ? (\n <div className=\"relative w-full max-w-64\">\n <Search\n aria-hidden\n className=\"pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-[color:var(--ds-text-tertiary)]\"\n />\n <Input\n data-slot=\"data-table-search\"\n type=\"search\"\n aria-label=\"Search\"\n placeholder={searchPlaceholder}\n value={globalFilter}\n onChange={(e) => table.setGlobalFilter(e.target.value)}\n className=\"h-8 pl-8 text-[length:var(--ds-text-caption-lg)]\"\n />\n </div>\n ) : null}\n {facetedColumns.map((column) => (\n <DataTableFacetedFilter key={column.id} column={column} />\n ))}\n {isFiltered ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n table.resetColumnFilters();\n table.setGlobalFilter(\"\");\n }}\n >\n Reset\n <X />\n </Button>\n ) : null}\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n {children}\n <DataTableViewOptions table={table} />\n {enableExport ? <DataTableExportMenu table={table} fileName={exportFileName} /> : null}\n </div>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------------ */\n/* Pagination */\n/* ------------------------------------------------------------------------ */\n\nexport interface DataTablePaginationProps<Row extends RowData> extends React.ComponentProps<\"div\"> {\n table: DataTableTable<Row>;\n /** @default [10, 25, 50, 100] */\n pageSizeOptions?: number[];\n}\n\nconst DEFAULT_PAGE_SIZES = [10, 25, 50, 100];\n\nfunction DataTablePagination<Row extends RowData>({\n table,\n pageSizeOptions = DEFAULT_PAGE_SIZES,\n className,\n ...props\n}: DataTablePaginationProps<Row>) {\n const { pageIndex, pageSize } = table.state.pagination;\n const total = table.getRowCount();\n const pageCount = table.getPageCount();\n const from = total === 0 ? 0 : pageIndex * pageSize + 1;\n const to = Math.min(total, (pageIndex + 1) * pageSize);\n const sizes = pageSizeOptions.includes(pageSize)\n ? pageSizeOptions\n : [...pageSizeOptions, pageSize].sort((a, b) => a - b);\n const sizeItems = sizes.map((s) => ({ value: String(s), label: String(s) }));\n\n const navButton = (label: string, icon: React.ReactNode, onClick: () => void, disabled: boolean) => (\n <Button variant=\"outline\" size=\"icon-sm\" aria-label={label} onClick={onClick} disabled={disabled}>\n {icon}\n </Button>\n );\n\n return (\n <div\n data-slot=\"data-table-pagination\"\n className={cn(\n \"flex flex-wrap items-center justify-between gap-3\",\n \"text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]\",\n className,\n )}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n <span>Rows per page</span>\n <Select\n items={sizeItems}\n value={String(pageSize)}\n onValueChange={(value) => table.setPageSize(Number(value))}\n >\n <SelectTrigger size=\"sm\" aria-label=\"Rows per page\" className=\"min-w-0 w-[4.5rem]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {sizeItems.map((item) => (\n <SelectItem key={item.value} value={item.value}>\n {item.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center gap-4\">\n <span data-slot=\"data-table-range\" aria-live=\"polite\">\n {from}–{to} of {total}\n </span>\n <div className=\"flex items-center gap-1\">\n {navButton(\"First page\", <ChevronsLeft />, () => table.firstPage(), !table.getCanPreviousPage())}\n {navButton(\"Previous page\", <ChevronLeft />, () => table.previousPage(), !table.getCanPreviousPage())}\n <span className=\"px-1 tabular-nums\">\n {pageCount === 0 ? 0 : pageIndex + 1} / {pageCount}\n </span>\n {navButton(\"Next page\", <ChevronRight />, () => table.nextPage(), !table.getCanNextPage())}\n {navButton(\"Last page\", <ChevronsRight />, () => table.lastPage(), !table.getCanNextPage())}\n </div>\n </div>\n </div>\n );\n}\n\nexport {\n DataTableColumnHeader,\n DataTableExportMenu,\n DataTableFacetedFilter,\n DataTablePagination,\n DataTableToolbar,\n DataTableViewOptions,\n};\n"],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../../lib/cn.js";
4
+ import { Checkbox } from "../checkbox.js";
5
+ import { ChevronRight } from "lucide-react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ //#region src/components/data-table/system-columns.tsx
8
+ /**
9
+ * Columns the table adds on the consumer's behalf: the selection checkbox
10
+ * when `enableRowSelection` is set, the expander when a `renderSubComponent`
11
+ * is given. Both are display columns, neither sorts, hides, resizes or
12
+ * exports, and a consumer column with the same id replaces them.
13
+ */
14
+ function selectColumn(helper) {
15
+ return helper.display({
16
+ id: "select",
17
+ header: ({ table }) => {
18
+ const all = table.getIsAllPageRowsSelected();
19
+ const some = table.getIsSomePageRowsSelected() && !all;
20
+ return /* @__PURE__ */ jsx(Checkbox, {
21
+ "aria-label": "Select all rows on this page",
22
+ checked: all,
23
+ indeterminate: some,
24
+ onCheckedChange: (checked) => table.toggleAllPageRowsSelected(Boolean(checked))
25
+ });
26
+ },
27
+ cell: ({ row }) => /* @__PURE__ */ jsx(Checkbox, {
28
+ "aria-label": "Select row",
29
+ checked: row.getIsSelected(),
30
+ disabled: !row.getCanSelect(),
31
+ onCheckedChange: (checked) => row.toggleSelected(Boolean(checked))
32
+ }),
33
+ size: 40,
34
+ minSize: 40,
35
+ maxSize: 40,
36
+ enableSorting: false,
37
+ enableHiding: false,
38
+ enableResizing: false,
39
+ enableColumnFilter: false,
40
+ enableGlobalFilter: false,
41
+ meta: {
42
+ exportable: false,
43
+ align: "center",
44
+ cellClassName: "px-2",
45
+ headerClassName: "px-2"
46
+ }
47
+ });
48
+ }
49
+ function expandColumn(helper) {
50
+ return helper.display({
51
+ id: "expand",
52
+ header: () => /* @__PURE__ */ jsx("span", {
53
+ className: "sr-only",
54
+ children: "Expand"
55
+ }),
56
+ cell: ({ row }) => row.getCanExpand() ? /* @__PURE__ */ jsx("button", {
57
+ type: "button",
58
+ "data-slot": "data-table-expander",
59
+ "aria-label": row.getIsExpanded() ? "Collapse row" : "Expand row",
60
+ "aria-expanded": row.getIsExpanded(),
61
+ onClick: row.getToggleExpandedHandler(),
62
+ className: cn("inline-flex size-6 items-center justify-center rounded-[var(--ds-radius-sm)]", "text-[color:var(--ds-muted-foreground)] hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]", "outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40"),
63
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: cn("size-4 transition-transform duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]", row.getIsExpanded() && "rotate-90") })
64
+ }) : null,
65
+ size: 40,
66
+ minSize: 40,
67
+ maxSize: 40,
68
+ enableSorting: false,
69
+ enableHiding: false,
70
+ enableResizing: false,
71
+ enableColumnFilter: false,
72
+ enableGlobalFilter: false,
73
+ meta: {
74
+ exportable: false,
75
+ align: "center",
76
+ cellClassName: "px-2",
77
+ headerClassName: "px-2"
78
+ }
79
+ });
80
+ }
81
+ //#endregion
82
+ export { expandColumn, selectColumn };
83
+
84
+ //# sourceMappingURL=system-columns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-columns.js","names":[],"sources":["../../../src/components/data-table/system-columns.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ColumnHelper, RowData } from \"@tanstack/react-table\";\nimport { ChevronRight } from \"lucide-react\";\nimport { Checkbox } from \"@/components/checkbox\";\nimport { cn } from \"@/lib/cn\";\nimport type { DataTableFeatures } from \"./features\";\nimport type { DataTableColumnDef } from \"./types\";\n\n/**\n * Columns the table adds on the consumer's behalf: the selection checkbox\n * when `enableRowSelection` is set, the expander when a `renderSubComponent`\n * is given. Both are display columns, neither sorts, hides, resizes or\n * exports, and a consumer column with the same id replaces them.\n */\nexport function selectColumn<Row extends RowData>(\n helper: ColumnHelper<DataTableFeatures<Row>, Row>,\n): DataTableColumnDef<Row, unknown> {\n return helper.display({\n id: \"select\",\n header: ({ table }) => {\n const all = table.getIsAllPageRowsSelected();\n const some = table.getIsSomePageRowsSelected() && !all;\n return (\n <Checkbox\n aria-label=\"Select all rows on this page\"\n checked={all}\n indeterminate={some}\n onCheckedChange={(checked) => table.toggleAllPageRowsSelected(Boolean(checked))}\n />\n );\n },\n cell: ({ row }) => (\n <Checkbox\n aria-label=\"Select row\"\n checked={row.getIsSelected()}\n disabled={!row.getCanSelect()}\n onCheckedChange={(checked) => row.toggleSelected(Boolean(checked))}\n />\n ),\n size: 40,\n minSize: 40,\n maxSize: 40,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n meta: { exportable: false, align: \"center\", cellClassName: \"px-2\", headerClassName: \"px-2\" },\n });\n}\n\nexport function expandColumn<Row extends RowData>(\n helper: ColumnHelper<DataTableFeatures<Row>, Row>,\n): DataTableColumnDef<Row, unknown> {\n return helper.display({\n id: \"expand\",\n header: () => <span className=\"sr-only\">Expand</span>,\n cell: ({ row }) =>\n row.getCanExpand() ? (\n <button\n type=\"button\"\n data-slot=\"data-table-expander\"\n aria-label={row.getIsExpanded() ? \"Collapse row\" : \"Expand row\"}\n aria-expanded={row.getIsExpanded()}\n onClick={row.getToggleExpandedHandler()}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded-[var(--ds-radius-sm)]\",\n \"text-[color:var(--ds-muted-foreground)] hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]\",\n \"outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40\",\n )}\n >\n <ChevronRight\n className={cn(\n \"size-4 transition-transform duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]\",\n row.getIsExpanded() && \"rotate-90\",\n )}\n />\n </button>\n ) : null,\n size: 40,\n minSize: 40,\n maxSize: 40,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n meta: { exportable: false, align: \"center\", cellClassName: \"px-2\", headerClassName: \"px-2\" },\n });\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAgB,aACd,QACkC;CAClC,OAAO,OAAO,QAAQ;EACpB,IAAI;EACJ,SAAS,EAAE,YAAY;GACrB,MAAM,MAAM,MAAM,yBAAyB;GAC3C,MAAM,OAAO,MAAM,0BAA0B,KAAK,CAAC;GACnD,OACE,oBAAC,UAAD;IACE,cAAW;IACX,SAAS;IACT,eAAe;IACf,kBAAkB,YAAY,MAAM,0BAA0B,QAAQ,OAAO,CAAC;GAC/E,CAAA;EAEL;EACA,OAAO,EAAE,UACP,oBAAC,UAAD;GACE,cAAW;GACX,SAAS,IAAI,cAAc;GAC3B,UAAU,CAAC,IAAI,aAAa;GAC5B,kBAAkB,YAAY,IAAI,eAAe,QAAQ,OAAO,CAAC;EAClE,CAAA;EAEH,MAAM;EACN,SAAS;EACT,SAAS;EACT,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,oBAAoB;EACpB,oBAAoB;EACpB,MAAM;GAAE,YAAY;GAAO,OAAO;GAAU,eAAe;GAAQ,iBAAiB;EAAO;CAC7F,CAAC;AACH;AAEA,SAAgB,aACd,QACkC;CAClC,OAAO,OAAO,QAAQ;EACpB,IAAI;EACJ,cAAc,oBAAC,QAAD;GAAM,WAAU;GAAU,UAAA;EAAY,CAAA;EACpD,OAAO,EAAE,UACP,IAAI,aAAa,IACf,oBAAC,UAAD;GACE,MAAK;GACL,aAAU;GACV,cAAY,IAAI,cAAc,IAAI,iBAAiB;GACnD,iBAAe,IAAI,cAAc;GACjC,SAAS,IAAI,yBAAyB;GACtC,WAAW,GACT,gFACA,8GACA,8EACF;GAEA,UAAA,oBAAC,cAAD,EACE,WAAW,GACT,4FACA,IAAI,cAAc,KAAK,WACzB,EACD,CAAA;EACK,CAAA,IACN;EACN,MAAM;EACN,SAAS;EACT,SAAS;EACT,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,oBAAoB;EACpB,oBAAoB;EACpB,MAAM;GAAE,YAAY;GAAO,OAAO;GAAU,eAAe;GAAQ,iBAAiB;EAAO;CAC7F,CAAC;AACH"}