@stackframe/dashboard-ui-components 2.8.84 → 2.8.86

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 (229) hide show
  1. package/dist/components/analytics-chart/analytics-chart-pie.d.ts +67 -0
  2. package/dist/components/analytics-chart/analytics-chart-pie.d.ts.map +1 -0
  3. package/dist/components/analytics-chart/analytics-chart-pie.js +253 -0
  4. package/dist/components/analytics-chart/analytics-chart-pie.js.map +1 -0
  5. package/dist/components/analytics-chart/analytics-chart.d.ts +554 -0
  6. package/dist/components/analytics-chart/analytics-chart.d.ts.map +1 -0
  7. package/dist/components/analytics-chart/analytics-chart.js +1021 -0
  8. package/dist/components/analytics-chart/analytics-chart.js.map +1 -0
  9. package/dist/components/analytics-chart/default-analytics-chart-tooltip.d.ts +66 -0
  10. package/dist/components/analytics-chart/default-analytics-chart-tooltip.d.ts.map +1 -0
  11. package/dist/components/analytics-chart/default-analytics-chart-tooltip.js +179 -0
  12. package/dist/components/analytics-chart/default-analytics-chart-tooltip.js.map +1 -0
  13. package/dist/components/analytics-chart/format.d.ts +13 -0
  14. package/dist/components/analytics-chart/format.d.ts.map +1 -0
  15. package/dist/components/analytics-chart/format.js +138 -0
  16. package/dist/components/analytics-chart/format.js.map +1 -0
  17. package/dist/components/analytics-chart/index.d.ts +8 -0
  18. package/dist/components/analytics-chart/index.js +184 -0
  19. package/dist/components/analytics-chart/palette.d.ts +15 -0
  20. package/dist/components/analytics-chart/palette.d.ts.map +1 -0
  21. package/dist/components/analytics-chart/palette.js +60 -0
  22. package/dist/components/analytics-chart/palette.js.map +1 -0
  23. package/dist/components/analytics-chart/render-data-series.d.ts +28 -0
  24. package/dist/components/analytics-chart/render-data-series.d.ts.map +1 -0
  25. package/dist/components/analytics-chart/render-data-series.js +109 -0
  26. package/dist/components/analytics-chart/render-data-series.js.map +1 -0
  27. package/dist/components/analytics-chart/state.d.ts +54 -0
  28. package/dist/components/analytics-chart/state.d.ts.map +1 -0
  29. package/dist/components/analytics-chart/state.js +142 -0
  30. package/dist/components/analytics-chart/state.js.map +1 -0
  31. package/dist/components/analytics-chart/strings.d.ts +33 -0
  32. package/dist/components/analytics-chart/strings.d.ts.map +1 -0
  33. package/dist/components/analytics-chart/strings.js +37 -0
  34. package/dist/components/analytics-chart/strings.js.map +1 -0
  35. package/dist/components/analytics-chart/types.d.ts +157 -0
  36. package/dist/components/analytics-chart/types.d.ts.map +1 -0
  37. package/dist/components/analytics-chart/types.js +21 -0
  38. package/dist/components/analytics-chart/types.js.map +1 -0
  39. package/dist/components/badge.d.ts +16 -0
  40. package/dist/components/badge.d.ts.map +1 -1
  41. package/dist/components/badge.js +16 -0
  42. package/dist/components/badge.js.map +1 -1
  43. package/dist/components/button.d.ts +15 -1
  44. package/dist/components/button.d.ts.map +1 -1
  45. package/dist/components/button.js +14 -0
  46. package/dist/components/button.js.map +1 -1
  47. package/dist/components/card.d.ts +28 -0
  48. package/dist/components/card.d.ts.map +1 -1
  49. package/dist/components/card.js +28 -0
  50. package/dist/components/card.js.map +1 -1
  51. package/dist/components/chart-card.d.ts +29 -0
  52. package/dist/components/chart-card.d.ts.map +1 -1
  53. package/dist/components/chart-card.js +29 -0
  54. package/dist/components/chart-card.js.map +1 -1
  55. package/dist/components/chart-legend.d.ts +1 -2
  56. package/dist/components/chart-legend.d.ts.map +1 -1
  57. package/dist/components/chart-legend.js +0 -4
  58. package/dist/components/chart-legend.js.map +1 -1
  59. package/dist/components/data-grid/data-grid-sizing.d.ts +11 -0
  60. package/dist/components/data-grid/data-grid-sizing.d.ts.map +1 -0
  61. package/dist/components/data-grid/data-grid-sizing.js +34 -0
  62. package/dist/components/data-grid/data-grid-sizing.js.map +1 -0
  63. package/dist/components/data-grid/data-grid-toolbar.d.ts +31 -0
  64. package/dist/components/data-grid/data-grid-toolbar.d.ts.map +1 -0
  65. package/dist/components/data-grid/data-grid-toolbar.js +226 -0
  66. package/dist/components/data-grid/data-grid-toolbar.js.map +1 -0
  67. package/dist/components/data-grid/data-grid.d.ts +233 -0
  68. package/dist/components/data-grid/data-grid.d.ts.map +1 -0
  69. package/dist/components/data-grid/data-grid.js +871 -0
  70. package/dist/components/data-grid/data-grid.js.map +1 -0
  71. package/dist/components/data-grid/index.d.ts +7 -0
  72. package/dist/components/data-grid/index.js +176 -0
  73. package/dist/components/data-grid/state.d.ts +91 -0
  74. package/dist/components/data-grid/state.d.ts.map +1 -0
  75. package/dist/components/data-grid/state.js +329 -0
  76. package/dist/components/data-grid/state.js.map +1 -0
  77. package/dist/components/data-grid/strings.d.ts +8 -0
  78. package/dist/components/data-grid/strings.d.ts.map +1 -0
  79. package/dist/components/data-grid/strings.js +42 -0
  80. package/dist/components/data-grid/strings.js.map +1 -0
  81. package/dist/components/data-grid/types.d.ts +242 -0
  82. package/dist/components/data-grid/types.d.ts.map +1 -0
  83. package/dist/components/data-grid/types.js +0 -0
  84. package/dist/components/data-grid/use-data-source.d.ts +79 -0
  85. package/dist/components/data-grid/use-data-source.d.ts.map +1 -0
  86. package/dist/components/data-grid/use-data-source.js +236 -0
  87. package/dist/components/data-grid/use-data-source.js.map +1 -0
  88. package/dist/components/empty-state.d.ts +16 -0
  89. package/dist/components/empty-state.d.ts.map +1 -1
  90. package/dist/components/empty-state.js +16 -0
  91. package/dist/components/empty-state.js.map +1 -1
  92. package/dist/components/metric-card.d.ts +24 -0
  93. package/dist/components/metric-card.d.ts.map +1 -1
  94. package/dist/components/metric-card.js +24 -0
  95. package/dist/components/metric-card.js.map +1 -1
  96. package/dist/components/progress-bar.d.ts +10 -0
  97. package/dist/components/progress-bar.d.ts.map +1 -1
  98. package/dist/components/progress-bar.js +10 -0
  99. package/dist/components/progress-bar.js.map +1 -1
  100. package/dist/components/separator.d.ts +9 -0
  101. package/dist/components/separator.d.ts.map +1 -1
  102. package/dist/components/separator.js +9 -0
  103. package/dist/components/separator.js.map +1 -1
  104. package/dist/components/skeleton.d.ts +12 -0
  105. package/dist/components/skeleton.d.ts.map +1 -1
  106. package/dist/components/skeleton.js +12 -0
  107. package/dist/components/skeleton.js.map +1 -1
  108. package/dist/components/table.d.ts +25 -0
  109. package/dist/components/table.d.ts.map +1 -1
  110. package/dist/components/table.js +25 -0
  111. package/dist/components/table.js.map +1 -1
  112. package/dist/dashboard-ui-components.global.js +8562 -2857
  113. package/dist/dashboard-ui-components.global.js.map +4 -4
  114. package/dist/esm/components/analytics-chart/analytics-chart-pie.d.ts +67 -0
  115. package/dist/esm/components/analytics-chart/analytics-chart-pie.d.ts.map +1 -0
  116. package/dist/esm/components/analytics-chart/analytics-chart-pie.js +251 -0
  117. package/dist/esm/components/analytics-chart/analytics-chart-pie.js.map +1 -0
  118. package/dist/esm/components/analytics-chart/analytics-chart.d.ts +554 -0
  119. package/dist/esm/components/analytics-chart/analytics-chart.d.ts.map +1 -0
  120. package/dist/esm/components/analytics-chart/analytics-chart.js +1019 -0
  121. package/dist/esm/components/analytics-chart/analytics-chart.js.map +1 -0
  122. package/dist/esm/components/analytics-chart/default-analytics-chart-tooltip.d.ts +66 -0
  123. package/dist/esm/components/analytics-chart/default-analytics-chart-tooltip.d.ts.map +1 -0
  124. package/dist/esm/components/analytics-chart/default-analytics-chart-tooltip.js +176 -0
  125. package/dist/esm/components/analytics-chart/default-analytics-chart-tooltip.js.map +1 -0
  126. package/dist/esm/components/analytics-chart/format.d.ts +13 -0
  127. package/dist/esm/components/analytics-chart/format.d.ts.map +1 -0
  128. package/dist/esm/components/analytics-chart/format.js +133 -0
  129. package/dist/esm/components/analytics-chart/format.js.map +1 -0
  130. package/dist/esm/components/analytics-chart/index.d.ts +8 -0
  131. package/dist/esm/components/analytics-chart/index.js +9 -0
  132. package/dist/esm/components/analytics-chart/palette.d.ts +15 -0
  133. package/dist/esm/components/analytics-chart/palette.d.ts.map +1 -0
  134. package/dist/esm/components/analytics-chart/palette.js +55 -0
  135. package/dist/esm/components/analytics-chart/palette.js.map +1 -0
  136. package/dist/esm/components/analytics-chart/render-data-series.d.ts +28 -0
  137. package/dist/esm/components/analytics-chart/render-data-series.d.ts.map +1 -0
  138. package/dist/esm/components/analytics-chart/render-data-series.js +107 -0
  139. package/dist/esm/components/analytics-chart/render-data-series.js.map +1 -0
  140. package/dist/esm/components/analytics-chart/state.d.ts +54 -0
  141. package/dist/esm/components/analytics-chart/state.d.ts.map +1 -0
  142. package/dist/esm/components/analytics-chart/state.js +126 -0
  143. package/dist/esm/components/analytics-chart/state.js.map +1 -0
  144. package/dist/esm/components/analytics-chart/strings.d.ts +33 -0
  145. package/dist/esm/components/analytics-chart/strings.d.ts.map +1 -0
  146. package/dist/esm/components/analytics-chart/strings.js +34 -0
  147. package/dist/esm/components/analytics-chart/strings.js.map +1 -0
  148. package/dist/esm/components/analytics-chart/types.d.ts +157 -0
  149. package/dist/esm/components/analytics-chart/types.d.ts.map +1 -0
  150. package/dist/esm/components/analytics-chart/types.js +18 -0
  151. package/dist/esm/components/analytics-chart/types.js.map +1 -0
  152. package/dist/esm/components/badge.d.ts +16 -0
  153. package/dist/esm/components/badge.d.ts.map +1 -1
  154. package/dist/esm/components/badge.js +16 -0
  155. package/dist/esm/components/badge.js.map +1 -1
  156. package/dist/esm/components/button.d.ts +14 -0
  157. package/dist/esm/components/button.d.ts.map +1 -1
  158. package/dist/esm/components/button.js +14 -0
  159. package/dist/esm/components/button.js.map +1 -1
  160. package/dist/esm/components/card.d.ts +28 -0
  161. package/dist/esm/components/card.d.ts.map +1 -1
  162. package/dist/esm/components/card.js +28 -0
  163. package/dist/esm/components/card.js.map +1 -1
  164. package/dist/esm/components/chart-card.d.ts +29 -0
  165. package/dist/esm/components/chart-card.d.ts.map +1 -1
  166. package/dist/esm/components/chart-card.js +29 -0
  167. package/dist/esm/components/chart-card.js.map +1 -1
  168. package/dist/esm/components/chart-legend.d.ts +1 -2
  169. package/dist/esm/components/chart-legend.d.ts.map +1 -1
  170. package/dist/esm/components/chart-legend.js +1 -3
  171. package/dist/esm/components/chart-legend.js.map +1 -1
  172. package/dist/esm/components/data-grid/data-grid-sizing.d.ts +11 -0
  173. package/dist/esm/components/data-grid/data-grid-sizing.d.ts.map +1 -0
  174. package/dist/esm/components/data-grid/data-grid-sizing.js +29 -0
  175. package/dist/esm/components/data-grid/data-grid-sizing.js.map +1 -0
  176. package/dist/esm/components/data-grid/data-grid-toolbar.d.ts +31 -0
  177. package/dist/esm/components/data-grid/data-grid-toolbar.d.ts.map +1 -0
  178. package/dist/esm/components/data-grid/data-grid-toolbar.js +223 -0
  179. package/dist/esm/components/data-grid/data-grid-toolbar.js.map +1 -0
  180. package/dist/esm/components/data-grid/data-grid.d.ts +233 -0
  181. package/dist/esm/components/data-grid/data-grid.d.ts.map +1 -0
  182. package/dist/esm/components/data-grid/data-grid.js +868 -0
  183. package/dist/esm/components/data-grid/data-grid.js.map +1 -0
  184. package/dist/esm/components/data-grid/index.d.ts +7 -0
  185. package/dist/esm/components/data-grid/index.js +7 -0
  186. package/dist/esm/components/data-grid/state.d.ts +91 -0
  187. package/dist/esm/components/data-grid/state.d.ts.map +1 -0
  188. package/dist/esm/components/data-grid/state.js +305 -0
  189. package/dist/esm/components/data-grid/state.js.map +1 -0
  190. package/dist/esm/components/data-grid/strings.d.ts +8 -0
  191. package/dist/esm/components/data-grid/strings.d.ts.map +1 -0
  192. package/dist/esm/components/data-grid/strings.js +39 -0
  193. package/dist/esm/components/data-grid/strings.js.map +1 -0
  194. package/dist/esm/components/data-grid/types.d.ts +242 -0
  195. package/dist/esm/components/data-grid/types.d.ts.map +1 -0
  196. package/dist/esm/components/data-grid/types.js +1 -0
  197. package/dist/esm/components/data-grid/use-data-source.d.ts +79 -0
  198. package/dist/esm/components/data-grid/use-data-source.d.ts.map +1 -0
  199. package/dist/esm/components/data-grid/use-data-source.js +234 -0
  200. package/dist/esm/components/data-grid/use-data-source.js.map +1 -0
  201. package/dist/esm/components/empty-state.d.ts +16 -0
  202. package/dist/esm/components/empty-state.d.ts.map +1 -1
  203. package/dist/esm/components/empty-state.js +16 -0
  204. package/dist/esm/components/empty-state.js.map +1 -1
  205. package/dist/esm/components/metric-card.d.ts +24 -0
  206. package/dist/esm/components/metric-card.d.ts.map +1 -1
  207. package/dist/esm/components/metric-card.js +24 -0
  208. package/dist/esm/components/metric-card.js.map +1 -1
  209. package/dist/esm/components/progress-bar.d.ts +10 -0
  210. package/dist/esm/components/progress-bar.d.ts.map +1 -1
  211. package/dist/esm/components/progress-bar.js +10 -0
  212. package/dist/esm/components/progress-bar.js.map +1 -1
  213. package/dist/esm/components/separator.d.ts +9 -0
  214. package/dist/esm/components/separator.d.ts.map +1 -1
  215. package/dist/esm/components/separator.js +9 -0
  216. package/dist/esm/components/separator.js.map +1 -1
  217. package/dist/esm/components/skeleton.d.ts +12 -0
  218. package/dist/esm/components/skeleton.d.ts.map +1 -1
  219. package/dist/esm/components/skeleton.js +12 -0
  220. package/dist/esm/components/skeleton.js.map +1 -1
  221. package/dist/esm/components/table.d.ts +25 -0
  222. package/dist/esm/components/table.d.ts.map +1 -1
  223. package/dist/esm/components/table.js +25 -0
  224. package/dist/esm/components/table.js.map +1 -1
  225. package/dist/esm/index.d.ts +4 -2
  226. package/dist/esm/index.js +6 -2
  227. package/dist/index.d.ts +15 -2
  228. package/dist/index.js +16 -7
  229. package/package.json +4 -3
@@ -0,0 +1,242 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/components/data-grid/types.d.ts
4
+ /** Every row must be uniquely identifiable. The grid resolves identity
5
+ * through the top-level `getRowId` prop. */
6
+ type RowId = string;
7
+ type DataGridColumnType = "string" | "number" | "date" | "dateTime" | "boolean" | "singleSelect" | "custom";
8
+ type DataGridColumnAlign = "left" | "center" | "right";
9
+ type DataGridColumnPin = "left" | "right" | false;
10
+ /** How `date` / `dateTime` cells render their value. `"relative"` shows
11
+ * "1 day ago"–style text with the full datetime in a tooltip; `"absolute"`
12
+ * shows the full datetime inline. */
13
+ type DataGridDateDisplay = "relative" | "absolute";
14
+ /** Per-column overrides for how a `date` / `dateTime` cell is formatted.
15
+ * If either function is omitted the grid falls back to its default
16
+ * (Intl.RelativeTimeFormat + `toLocaleString()`). */
17
+ type DataGridDateFormat = {
18
+ relative?: (date: Date) => string;
19
+ absolute?: (date: Date) => string;
20
+ };
21
+ /** Context passed to `renderCell`. */
22
+ type DataGridCellContext<TRow> = {
23
+ row: TRow;
24
+ rowId: RowId;
25
+ rowIndex: number;
26
+ value: unknown;
27
+ columnId: string;
28
+ isSelected: boolean;
29
+ /** Current date display mode — consumers writing custom `renderCell`
30
+ * for `date` / `dateTime` columns should branch on this to match the
31
+ * grid's built-in behaviour. */
32
+ dateDisplay: DataGridDateDisplay;
33
+ };
34
+ /** Context passed to `renderHeader`. */
35
+ type DataGridHeaderContext<TRow> = {
36
+ columnId: string;
37
+ columnDef: DataGridColumnDef<TRow>;
38
+ isSorted: false | "asc" | "desc";
39
+ sortIndex: number | null;
40
+ };
41
+ /** A single column's full configuration. Generic over the row type. */
42
+ type DataGridColumnDef<TRow> = {
43
+ /** Unique identifier for this column. */id: string; /** Display label. If a function is given it receives the header context. */
44
+ header: string | ((ctx: DataGridHeaderContext<TRow>) => ReactNode);
45
+ /** Accessor — either a key of TRow or a function. If omitted, `id` is
46
+ * used as the key. */
47
+ accessor?: keyof TRow | ((row: TRow) => unknown); /** Custom cell renderer. Falls back to plain text of the resolved value. */
48
+ renderCell?: (ctx: DataGridCellContext<TRow>) => ReactNode; /** Initial width in pixels. Defaults to 150. */
49
+ width?: number; /** Minimum width during resize. Defaults to 50. */
50
+ minWidth?: number; /** Maximum width during resize. Defaults to 800. */
51
+ maxWidth?: number;
52
+ /** Flex grow factor. When set, remaining space is distributed among flex
53
+ * columns proportionally. */
54
+ flex?: number;
55
+ sortable?: boolean;
56
+ resizable?: boolean;
57
+ hideable?: boolean; /** Pin position. Defaults to `false` (unpinned). */
58
+ pin?: DataGridColumnPin;
59
+ align?: DataGridColumnAlign; /** Column type affects default sorting. */
60
+ type?: DataGridColumnType; /** For `singleSelect` type — available value options. */
61
+ valueOptions?: readonly DataGridSelectOption[];
62
+ /** Custom sort comparator. Receives two resolved cell values.
63
+ * Return negative if a < b, positive if a > b, 0 if equal. */
64
+ sortComparator?: (a: unknown, b: unknown) => number;
65
+ /** Format a cell value to a plain string — used for export and
66
+ * clipboard copy. Defaults to `String(value)`. */
67
+ formatValue?: (value: unknown, row: TRow) => string;
68
+ /** Parse a raw cell value into a `Date`. Only consulted when `type` is
69
+ * `"date"` or `"dateTime"`. Defaults to `new Date(value)` with graceful
70
+ * handling of `null` / `undefined` / invalid dates. Override for
71
+ * non-standard formats (e.g. ClickHouse's space-separated UTC strings). */
72
+ parseValue?: (value: unknown) => Date | null; /** Per-column override for the relative / absolute date formatters. */
73
+ dateFormat?: DataGridDateFormat; /** Fired when a cell in this column is clicked. */
74
+ onCellClick?: (ctx: DataGridCellContext<TRow>, event: React.MouseEvent) => void; /** Fired when a cell in this column is double-clicked. */
75
+ onCellDoubleClick?: (ctx: DataGridCellContext<TRow>, event: React.MouseEvent) => void;
76
+ };
77
+ type DataGridSelectOption = {
78
+ value: string;
79
+ label: string;
80
+ };
81
+ type DataGridSortItem = {
82
+ columnId: string;
83
+ direction: "asc" | "desc";
84
+ };
85
+ type DataGridSortModel = readonly DataGridSortItem[];
86
+ type DataGridSelectionMode = "none" | "single" | "multiple";
87
+ type DataGridSelectionModel = {
88
+ selectedIds: ReadonlySet<RowId>; /** Tracks the last-clicked row for shift-range selection. */
89
+ anchorId: RowId | null;
90
+ };
91
+ type DataGridColumnVisibility = Record<string, boolean>;
92
+ type DataGridColumnPinning = {
93
+ left: readonly string[];
94
+ right: readonly string[];
95
+ };
96
+ /** UI display mode — "paginated" shows page controls, "infinite" shows scroll sentinel. */
97
+ type DataGridPaginationMode = "paginated" | "infinite";
98
+ /** Data-fetching strategy used by `useDataSource`. */
99
+ type DataGridDataPaginationMode = "client" | "server" | "infinite";
100
+ type DataGridPaginationModel = {
101
+ pageIndex: number;
102
+ pageSize: number;
103
+ };
104
+ type DataGridState = {
105
+ sorting: DataGridSortModel;
106
+ columnVisibility: DataGridColumnVisibility;
107
+ columnWidths: Record<string, number>;
108
+ columnPinning: DataGridColumnPinning;
109
+ columnOrder: readonly string[];
110
+ pagination: DataGridPaginationModel;
111
+ selection: DataGridSelectionModel;
112
+ /** How `date` / `dateTime` columns render. Defaults to `"relative"`
113
+ * via `createDefaultDataGridState`. Toggled from the Columns popover
114
+ * whenever the grid has at least one date column. */
115
+ dateDisplay: DataGridDateDisplay;
116
+ /** Current quick-search text. Written by the built-in search input in
117
+ * the toolbar. `useDataSource` in client mode auto-filters by this
118
+ * value (via `applyQuickSearch`); in async mode it's passed through
119
+ * to the generator as `params.quickSearch`, where the consumer owns
120
+ * the "how do I match?" decision (typically by modifying the backend
121
+ * query). Defaults to `""`. */
122
+ quickSearch: string;
123
+ };
124
+ /** Params sent to the async data source on each fetch. */
125
+ type DataGridFetchParams = {
126
+ sorting: DataGridSortModel;
127
+ pagination: DataGridPaginationModel;
128
+ /** Current quick-search text. Passed through from `state.quickSearch`
129
+ * so the async generator can fold it into its query (e.g. a SQL WHERE
130
+ * clause). Empty string when the search box is empty. A change in
131
+ * this value triggers a refetch, same mechanism as sorting. */
132
+ quickSearch: string; /** For cursor-based: the last row of the previous page. */
133
+ cursor: unknown;
134
+ };
135
+ /** Return type from a data source fetch. */
136
+ type DataGridFetchResult<TRow> = {
137
+ rows: TRow[]; /** Total row count if known. `-1` or `undefined` for unknown (infinite). */
138
+ totalRowCount?: number; /** Cursor for the next page (for cursor-based pagination). */
139
+ nextCursor?: unknown; /** If `false`, there are no more pages. */
140
+ hasMore?: boolean;
141
+ };
142
+ /** An async-generator data source yields pages of rows. The generator
143
+ * receives fetch params as its argument and yields pages. Yielding
144
+ * allows the grid to display partial results during loading. */
145
+ type DataGridDataSource<TRow> = (params: DataGridFetchParams) => AsyncGenerator<DataGridFetchResult<TRow>, void, undefined>;
146
+ type DataGridCallbacks<TRow> = {
147
+ onRowClick?: (row: TRow, rowId: RowId, event: React.MouseEvent) => void;
148
+ onRowDoubleClick?: (row: TRow, rowId: RowId, event: React.MouseEvent) => void;
149
+ onCellClick?: (row: TRow, columnId: string, value: unknown, event: React.MouseEvent) => void;
150
+ onSelectionChange?: (selectedIds: ReadonlySet<RowId>, selectedRows: TRow[]) => void;
151
+ onSortChange?: (model: DataGridSortModel) => void;
152
+ onColumnResize?: (columnId: string, width: number) => void;
153
+ onColumnVisibilityChange?: (model: DataGridColumnVisibility) => void;
154
+ };
155
+ type DataGridProps<TRow> = {
156
+ /** Column definitions. */columns: readonly DataGridColumnDef<TRow>[];
157
+ /** The rows to display. The consumer is responsible for sorting
158
+ * and paginating before passing them in. */
159
+ rows: readonly TRow[]; /** Extract a unique identifier from each row. */
160
+ getRowId: (row: TRow) => RowId; /** Total row count across all pages (used for pagination UI). */
161
+ totalRowCount?: number; /** True while the initial data load is in progress (shows skeleton). */
162
+ isLoading?: boolean; /** True during a background refetch (shows subtle indicator, keeps rows). */
163
+ isRefetching?: boolean; /** Whether more rows can be loaded (shows infinite scroll sentinel). */
164
+ hasMore?: boolean; /** True while loading the next page of infinite scroll. */
165
+ isLoadingMore?: boolean; /** Called when the infinite scroll sentinel becomes visible. */
166
+ onLoadMore?: () => void;
167
+ state: DataGridState;
168
+ onChange: React.Dispatch<React.SetStateAction<DataGridState>>;
169
+ /** UI mode for pagination. "paginated" shows page controls in the
170
+ * footer. "infinite" shows a scroll sentinel instead. Defaults to
171
+ * "paginated". */
172
+ paginationMode?: "paginated" | "infinite"; /** Selection behaviour. Defaults to "none". */
173
+ selectionMode?: DataGridSelectionMode; /** Whether columns can be resized by dragging. Defaults to true. */
174
+ resizable?: boolean; /** Row height in pixels. Defaults to 44. */
175
+ rowHeight?: number; /** Header row height in pixels. Defaults to 44. */
176
+ headerHeight?: number; /** Number of rows to render outside the visible area. Defaults to 5. */
177
+ overscan?: number; /** Grid max height. If omitted, grid takes available space. */
178
+ maxHeight?: number | string;
179
+ } & DataGridCallbacks<TRow> & {
180
+ /** Custom toolbar renderer. When `false`, toolbar is hidden entirely. */toolbar?: false | ((ctx: DataGridToolbarContext<TRow>) => ReactNode);
181
+ /** Extra content rendered inside the default toolbar row, to the left of
182
+ * the built-in columns / export actions. Use this to slot in
183
+ * refresh buttons, custom toggles, row counts, etc. without giving up
184
+ * the built-in actions. Ignored if a custom `toolbar` render function
185
+ * is provided — that function owns the entire row. */
186
+ toolbarExtra?: ReactNode | ((ctx: DataGridToolbarContext<TRow>) => ReactNode); /** Custom empty state. Defaults to a centered "No data" message. */
187
+ emptyState?: ReactNode; /** Custom loading state. Defaults to skeleton rows. */
188
+ loadingState?: ReactNode; /** Custom footer. When `false`, footer is hidden. */
189
+ footer?: false | ((ctx: DataGridFooterContext<TRow>) => ReactNode); /** Extra content rendered to the right of the default footer info. */
190
+ footerExtra?: ReactNode | ((ctx: DataGridFooterContext<TRow>) => ReactNode); /** Filename stem for CSV export (without extension). */
191
+ exportFilename?: string; /** i18n overrides. */
192
+ strings?: Partial<DataGridStrings>;
193
+ className?: string;
194
+ };
195
+ type DataGridToolbarContext<TRow> = {
196
+ state: DataGridState;
197
+ onChange: React.Dispatch<React.SetStateAction<DataGridState>>;
198
+ columns: readonly DataGridColumnDef<TRow>[];
199
+ visibleColumns: readonly DataGridColumnDef<TRow>[];
200
+ totalRowCount: number | undefined;
201
+ selectedRowCount: number;
202
+ strings: DataGridStrings; /** Trigger a CSV export. */
203
+ exportCsv: () => void;
204
+ };
205
+ type DataGridFooterContext<TRow> = {
206
+ state: DataGridState;
207
+ totalRowCount: number | undefined;
208
+ visibleRowCount: number;
209
+ selectedRowCount: number;
210
+ paginationMode: DataGridPaginationMode;
211
+ strings: DataGridStrings;
212
+ };
213
+ type DataGridStrings = {
214
+ searchPlaceholder: string;
215
+ columns: string;
216
+ export: string;
217
+ density: string;
218
+ showAll: string;
219
+ hideAll: string;
220
+ resetColumns: string;
221
+ dateFormat: string;
222
+ dateFormatRelative: string;
223
+ dateFormatAbsolute: string;
224
+ rowsSelected: (count: number) => string;
225
+ rowsPerPage: string;
226
+ pageOf: (page: number, total: number) => string;
227
+ noData: string;
228
+ loading: string;
229
+ loadingMore: string;
230
+ exportCsv: string;
231
+ exportCopied: string;
232
+ sortAsc: string;
233
+ sortDesc: string;
234
+ unsort: string;
235
+ pinLeft: string;
236
+ pinRight: string;
237
+ unpin: string;
238
+ hideColumn: string;
239
+ };
240
+ //#endregion
241
+ export { DataGridCallbacks, DataGridCellContext, DataGridColumnAlign, DataGridColumnDef, DataGridColumnPin, DataGridColumnPinning, DataGridColumnType, DataGridColumnVisibility, DataGridDataPaginationMode, DataGridDataSource, DataGridDateDisplay, DataGridDateFormat, DataGridFetchParams, DataGridFetchResult, DataGridFooterContext, DataGridHeaderContext, DataGridPaginationMode, DataGridPaginationModel, DataGridProps, DataGridSelectOption, DataGridSelectionMode, DataGridSelectionModel, DataGridSortItem, DataGridSortModel, DataGridState, DataGridStrings, DataGridToolbarContext, RowId };
242
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/components/data-grid/types.ts"],"mappings":";;;;;KAKY,KAAA;AAAA,KAGA,kBAAA;AAAA,KASA,mBAAA;AAAA,KAEA,iBAAA;;AAXZ;;KAgBY,mBAAA;;;AAPZ;KAYY,kBAAA;EACV,QAAA,IAAY,IAAA,EAAM,IAAA;EAClB,QAAA,IAAY,IAAA,EAAM,IAAA;AAAA;AAZpB;AAAA,KAgBY,mBAAA;EACV,GAAA,EAAK,IAAA;EACL,KAAA,EAAO,KAAA;EACP,QAAA;EACA,KAAA;EACA,QAAA;EACA,UAAA;EAjB6B;;AAK/B;EAgBE,WAAA,EAAa,mBAAA;AAAA;;KAIH,qBAAA;EACV,QAAA;EACA,SAAA,EAAW,iBAAA,CAAkB,IAAA;EAC7B,QAAA;EACA,SAAA;AAAA;;KAIU,iBAAA;EAtBA,yCAwBV,EAAA,UAxB6B;EA2B7B,MAAA,aAAmB,GAAA,EAAK,qBAAA,CAAsB,IAAA,MAAU,SAAA;EAzBjD;;EA6BP,QAAA,SAAiB,IAAA,KAAS,GAAA,EAAK,IAAA,eArBC;EAwBhC,UAAA,IAAc,GAAA,EAAK,mBAAA,CAAoB,IAAA,MAAU,SAAA,EAjCjD;EAqCA,KAAA,WApCA;EAsCA,QAAA,WArCA;EAuCA,QAAA;EArCA;;EAwCA,IAAA;EAGA,QAAA;EACA,SAAA;EACA,QAAA,YApCU;EAsCV,GAAA,GAAM,iBAAA;EAGN,KAAA,GAAQ,mBAAA,EAvCoB;EAyC5B,IAAA,GAAO,kBAAA,EA1CP;EA4CA,YAAA,YAAwB,oBAAA;EA3Cb;;EAgDX,cAAA,IAAkB,CAAA,WAAY,CAAA;EA9C9B;;EAiDA,WAAA,IAAe,KAAA,WAAgB,GAAA,EAAK,IAAA;EA7C1B;;;;EAoDV,UAAA,IAAc,KAAA,cAAmB,IAAA,SA/CuB;EAiDxD,UAAA,GAAa,kBAAA,EA7CkB;EAiD/B,WAAA,IAAe,GAAA,EAAK,mBAAA,CAAoB,IAAA,GAAO,KAAA,EAAO,KAAA,CAAM,UAAA,WA9CzC;EAgDnB,iBAAA,IAAqB,GAAA,EAAK,mBAAA,CAAoB,IAAA,GAAO,KAAA,EAAO,KAAA,CAAM,UAAA;AAAA;AAAA,KAGxD,oBAAA;EACV,KAAA;EACA,KAAA;AAAA;AAAA,KAIU,gBAAA;EACV,QAAA;EACA,SAAA;AAAA;AAAA,KAEU,iBAAA,YAA6B,gBAAA;AAAA,KAG7B,qBAAA;AAAA,KAEA,sBAAA;EACV,WAAA,EAAa,WAAA,CAAY,KAAA,GAnBmD;EAqB5E,QAAA,EAAU,KAAA;AAAA;AAAA,KAIA,wBAAA,GAA2B,MAAA;AAAA,KAE3B,qBAAA;EACV,IAAA;EACA,KAAA;AAAA;;KAKU,sBAAA;;KAGA,0BAAA;AAAA,KAEA,uBAAA;EACV,SAAA;EACA,QAAA;AAAA;AAAA,KAIU,aAAA;EACV,OAAA,EAAS,iBAAA;EACT,gBAAA,EAAkB,wBAAA;EAClB,YAAA,EAAc,MAAA;EACd,aAAA,EAAe,qBAAA;EACf,WAAA;EACA,UAAA,EAAY,uBAAA;EACZ,SAAA,EAAW,sBAAA;EApFX;;;EAwFA,WAAA,EAAa,mBAAA;EAnFL;;;;;;EA0FR,WAAA;AAAA;;KAKU,mBAAA;EACV,OAAA,EAAS,iBAAA;EACT,UAAA,EAAY,uBAAA;EA9EZ;;;;EAmFA,WAAA,UA7EA;EA+EA,MAAA;AAAA;;KAIU,mBAAA;EACV,IAAA,EAAM,IAAA,IApFyC;EAsF/C,aAAA,WApF0B;EAsF1B,UAAA,YAtFqB;EAwFrB,OAAA;AAAA;;;;KAMU,kBAAA,UACV,MAAA,EAAQ,mBAAA,KACL,cAAA,CAAe,mBAAA,CAAoB,IAAA;AAAA,KAG5B,iBAAA;EACV,UAAA,IAAc,GAAA,EAAK,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,UAAA;EACpD,gBAAA,IAAoB,GAAA,EAAK,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,UAAA;EAC1D,WAAA,IAAe,GAAA,EAAK,IAAA,EAAM,QAAA,UAAkB,KAAA,WAAgB,KAAA,EAAO,KAAA,CAAM,UAAA;EACzE,iBAAA,IAAqB,WAAA,EAAa,WAAA,CAAY,KAAA,GAAQ,YAAA,EAAc,IAAA;EACpE,YAAA,IAAgB,KAAA,EAAO,iBAAA;EACvB,cAAA,IAAkB,QAAA,UAAkB,KAAA;EACpC,wBAAA,IAA4B,KAAA,EAAO,wBAAA;AAAA;AAAA,KAIzB,aAAA;EAjGiB,0BAmG3B,OAAA,WAAkB,iBAAA,CAAkB,IAAA;EAnGG;;EAwGvC,IAAA,WAAe,IAAA,IArGgB;EAuG/B,QAAA,GAAW,GAAA,EAAK,IAAA,KAAS,KAAA,EAvGM;EAyG/B,aAAA,WAvGU;EAyGV,SAAA;EAEA,YAAA,YA1Ga;EA8Gb,OAAA,YA5Ge;EA8Gf,aAAA,YAhHA;EAkHA,UAAA;EAGA,KAAA,EAAO,aAAA;EACP,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,cAAA,CAAe,aAAA;EApHpC;;;EA0HV,cAAA,6BAtHkC;EAwHlC,aAAA,GAAgB,qBAAA,EAxHqB;EA0HrC,SAAA,YAxHU;EA4HV,SAAA;EAEA,YAAA,WA5HK;EA8HL,QAAA,WAzHgC;EA2HhC,SAAA;AAAA,IAGE,iBAAA,CAAkB,IAAA;EA9HY,yEAiIhC,OAAA,aAAoB,GAAA,EAAK,sBAAA,CAAuB,IAAA,MAAU,SAAA;EA9HtB;;;;AAEtC;EAkIE,YAAA,GAAe,SAAA,KAAc,GAAA,EAAK,sBAAA,CAAuB,IAAA,MAAU,SAAA;EAEnE,UAAA,GAAa,SAAA,EAlIL;EAoIR,YAAA,GAAe,SAAA,EAhIQ;EAkIvB,MAAA,aAAmB,GAAA,EAAK,qBAAA,CAAsB,IAAA,MAAU,SAAA,GAjI/C;EAmIT,WAAA,GAAc,SAAA,KAAc,GAAA,EAAK,qBAAA,CAAsB,IAAA,MAAU,SAAA,GAjInD;EAoId,cAAA,WAjIY;EAmIZ,OAAA,GAAU,OAAA,CAAQ,eAAA;EAElB,SAAA;AAAA;AAAA,KAIU,sBAAA;EACV,KAAA,EAAO,aAAA;EACP,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,cAAA,CAAe,aAAA;EAC9C,OAAA,WAAkB,iBAAA,CAAkB,IAAA;EACpC,cAAA,WAAyB,iBAAA,CAAkB,IAAA;EAC3C,aAAA;EACA,gBAAA;EACA,OAAA,EAAS,eAAA,EAlJM;EAoJf,SAAA;AAAA;AAAA,KAGU,qBAAA;EACV,KAAA,EAAO,aAAA;EACP,aAAA;EACA,eAAA;EACA,gBAAA;EACA,cAAA,EAAgB,sBAAA;EAChB,OAAA,EAAS,eAAA;AAAA;AAAA,KAIC,eAAA;EAEV,iBAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EAEA,OAAA;EACA,OAAA;EACA,YAAA;EAEA,UAAA;EACA,kBAAA;EACA,kBAAA;EAEA,YAAA,GAAe,KAAA;EAEf,WAAA;EACA,MAAA,GAAS,IAAA,UAAc,KAAA;EAEvB,MAAA;EACA,OAAA;EACA,WAAA;EAEA,SAAA;EACA,YAAA;EAEA,OAAA;EACA,QAAA;EACA,MAAA;EAEA,OAAA;EACA,QAAA;EACA,KAAA;EACA,UAAA;AAAA"}
File without changes
@@ -0,0 +1,79 @@
1
+ import { DataGridColumnDef, DataGridDataPaginationMode, DataGridDataSource, DataGridPaginationModel, DataGridSortModel, RowId } from "./types.js";
2
+
3
+ //#region src/components/data-grid/use-data-source.d.ts
4
+ type UseDataSourceResult<TRow> = {
5
+ /** All rows currently loaded (for infinite mode, the accumulated set). */rows: readonly TRow[]; /** Total row count if known. */
6
+ totalRowCount: number | undefined; /** Whether the initial load is in progress (no data at all yet). */
7
+ isLoading: boolean; /** Whether a background refetch is happening (data already shown). */
8
+ isRefetching: boolean; /** Whether more rows are being fetched (infinite scroll). */
9
+ isLoadingMore: boolean; /** Request the next page (infinite scroll). */
10
+ loadMore: () => void; /** Whether there are more pages to load. */
11
+ hasMore: boolean; /** Reload from scratch. */
12
+ reload: () => void;
13
+ };
14
+ /**
15
+ * Hook that processes raw data through the grid's sort/pagination state
16
+ * and returns the `rows` slice ready to pass to `DataGrid`. This is the
17
+ * only correct way to feed client-side data into a grid.
18
+ *
19
+ * Two modes, picked by which prop you pass:
20
+ * - `data: TRow[]` → client-side mode. In-memory sort + paginate.
21
+ * - `dataSource: (params) => AsyncGenerator` → server / infinite mode.
22
+ * The generator yields pages as you scroll or change pages.
23
+ *
24
+ * ```tsx
25
+ * // Client-side (most common):
26
+ * const gridData = useDataSource({
27
+ * data: users,
28
+ * columns,
29
+ * getRowId: (row) => row.id,
30
+ * sorting: gridState.sorting,
31
+ * quickSearch: gridState.quickSearch,
32
+ * pagination: gridState.pagination,
33
+ * paginationMode: "client",
34
+ * });
35
+ *
36
+ * <DataGrid
37
+ * columns={columns}
38
+ * rows={gridData.rows}
39
+ * totalRowCount={gridData.totalRowCount}
40
+ * isLoading={gridData.isLoading}
41
+ * state={gridState}
42
+ * onChange={setGridState}
43
+ * getRowId={(row) => row.id}
44
+ * />
45
+ * ```
46
+ *
47
+ * Rules:
48
+ * - Call this hook unconditionally at the top level, before any early return.
49
+ * - `rows` on `DataGrid` must ALWAYS be `gridData.rows`, never your raw array.
50
+ * - For server or infinite pagination, use `dataSource` — see the
51
+ * `DataGridDataSource` type for the generator signature.
52
+ *
53
+ * Quick search:
54
+ * - Client mode (`data` prop): the hook auto-filters rows via
55
+ * `applyQuickSearch` using a default case-insensitive substring match
56
+ * across every column. Override with `matchRow` for custom matching
57
+ * (fuzzy, weighted, field-specific, etc.).
58
+ * - Async mode (`dataSource` prop): the hook passes `quickSearch` into
59
+ * `params.quickSearch` and re-runs the generator whenever the search
60
+ * string changes. The consumer owns the matching logic (typically by
61
+ * folding it into a backend query). The grid performs NO client-side
62
+ * filtering in async mode.
63
+ */
64
+ declare function useDataSource<TRow>(opts: {
65
+ data?: readonly TRow[];
66
+ dataSource?: DataGridDataSource<TRow>;
67
+ columns: readonly DataGridColumnDef<TRow>[];
68
+ getRowId: (row: TRow) => RowId;
69
+ sorting: DataGridSortModel; /** Current quick-search text, typically `gridState.quickSearch`. */
70
+ quickSearch: string;
71
+ /** Override the default client-mode matcher. Ignored in async mode
72
+ * (there the generator is the matcher). */
73
+ matchRow?: (row: TRow, query: string, columns: readonly DataGridColumnDef<TRow>[]) => boolean;
74
+ pagination: DataGridPaginationModel;
75
+ paginationMode: DataGridDataPaginationMode;
76
+ }): UseDataSourceResult<TRow>;
77
+ //#endregion
78
+ export { UseDataSourceResult, useDataSource };
79
+ //# sourceMappingURL=use-data-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-data-source.d.ts","names":[],"sources":["../../../src/components/data-grid/use-data-source.ts"],"mappings":";;;KAiBY,mBAAA;4EAEV,IAAA,WAAe,IAAA,IAFc;EAI7B,aAAA,sBAFmB;EAInB,SAAA,WAJA;EAMA,YAAA,WAJA;EAMA,aAAA,WAFA;EAIA,QAAA;EAEA,OAAA,WAEA;EAAA,MAAA;AAAA;AAoRF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAAgB,aAAA,MAAA,CAAoB,IAAA;EAClC,IAAA,YAAgB,IAAA;EAChB,UAAA,GAAa,kBAAA,CAAmB,IAAA;EAChC,OAAA,WAAkB,iBAAA,CAAkB,IAAA;EACpC,QAAA,GAAW,GAAA,EAAK,IAAA,KAAS,KAAA;EACzB,OAAA,EAAS,iBAAA;EAET,WAAA;;;EAGA,QAAA,IACE,GAAA,EAAK,IAAA,EACL,KAAA,UACA,OAAA,WAAkB,iBAAA,CAAkB,IAAA;EAEtC,UAAA,EAAY,uBAAA;EACZ,cAAA,EAAgB,0BAAA;AAAA,IACd,mBAAA,CAAoB,IAAA"}
@@ -0,0 +1,236 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../../chunk-BE-pF4vm.js');
3
+ let react = require("react");
4
+ let __state_js = require("./state.js");
5
+
6
+ //#region src/components/data-grid/use-data-source.ts
7
+ function useClientDataSource(opts) {
8
+ const { data, columns, sorting, quickSearch, matchRow, pagination, paginationMode } = opts;
9
+ const processed = (0, react.useMemo)(() => {
10
+ const searched = (0, __state_js.applyQuickSearch)(data, quickSearch, columns, matchRow);
11
+ const comparator = (0, __state_js.buildRowComparator)(sorting, columns);
12
+ const sorted = comparator ? [...searched].sort(comparator) : searched;
13
+ const totalRowCount = sorted.length;
14
+ return {
15
+ rows: paginationMode === "client" ? (0, __state_js.paginateRows)(sorted, pagination) : sorted,
16
+ totalRowCount
17
+ };
18
+ }, [
19
+ data,
20
+ JSON.stringify(sorting),
21
+ quickSearch,
22
+ matchRow,
23
+ pagination.pageIndex,
24
+ pagination.pageSize,
25
+ paginationMode,
26
+ columns
27
+ ]);
28
+ return (0, react.useMemo)(() => ({
29
+ rows: processed.rows,
30
+ totalRowCount: processed.totalRowCount,
31
+ isLoading: false,
32
+ isRefetching: false,
33
+ isLoadingMore: false,
34
+ loadMore: () => {},
35
+ hasMore: false,
36
+ reload: () => {}
37
+ }), [processed]);
38
+ }
39
+ function useAsyncDataSource(opts) {
40
+ const { dataSource, getRowId, sorting, quickSearch, pagination, paginationMode } = opts;
41
+ const [rows, setRows] = (0, react.useState)([]);
42
+ const [totalRowCount, setTotalRowCount] = (0, react.useState)(void 0);
43
+ const [isLoading, setIsLoading] = (0, react.useState)(true);
44
+ const [isRefetching, setIsRefetching] = (0, react.useState)(false);
45
+ const [isLoadingMore, setIsLoadingMore] = (0, react.useState)(false);
46
+ const [hasMore, setHasMore] = (0, react.useState)(true);
47
+ const cursorRef = (0, react.useRef)(void 0);
48
+ const abortRef = (0, react.useRef)(null);
49
+ const pageIndexRef = (0, react.useRef)(0);
50
+ const hasDataRef = (0, react.useRef)(false);
51
+ const hasMountedServerPaginationRef = (0, react.useRef)(false);
52
+ const latestArgsRef = (0, react.useRef)({
53
+ dataSource,
54
+ getRowId,
55
+ sorting,
56
+ quickSearch,
57
+ pagination
58
+ });
59
+ latestArgsRef.current = {
60
+ dataSource,
61
+ getRowId,
62
+ sorting,
63
+ quickSearch,
64
+ pagination
65
+ };
66
+ const sortingKey = JSON.stringify(sorting);
67
+ const quickSearchKey = quickSearch;
68
+ const fetchPage = (0, react.useCallback)(async (append) => {
69
+ const { dataSource: currentDataSource, getRowId: currentGetRowId, sorting: currentSorting, quickSearch: currentQuickSearch, pagination: currentPagination } = latestArgsRef.current;
70
+ abortRef.current?.abort();
71
+ const controller = new AbortController();
72
+ abortRef.current = controller;
73
+ if (append) setIsLoadingMore(true);
74
+ else {
75
+ if (hasDataRef.current) setIsRefetching(true);
76
+ else setIsLoading(true);
77
+ cursorRef.current = void 0;
78
+ pageIndexRef.current = 0;
79
+ }
80
+ try {
81
+ const gen = currentDataSource({
82
+ sorting: currentSorting,
83
+ quickSearch: currentQuickSearch,
84
+ pagination: append ? {
85
+ pageIndex: pageIndexRef.current,
86
+ pageSize: currentPagination.pageSize
87
+ } : currentPagination,
88
+ cursor: cursorRef.current
89
+ });
90
+ for await (const result of gen) {
91
+ if (controller.signal.aborted) return;
92
+ if (result.totalRowCount != null) setTotalRowCount(result.totalRowCount);
93
+ if (result.nextCursor !== void 0) cursorRef.current = result.nextCursor;
94
+ setHasMore(result.hasMore !== false);
95
+ if (append) setRows((prev) => {
96
+ const existingIds = new Set(prev.map(currentGetRowId));
97
+ const newRows = result.rows.filter((r) => !existingIds.has(currentGetRowId(r)));
98
+ return [...prev, ...newRows];
99
+ });
100
+ else setRows(result.rows);
101
+ hasDataRef.current = true;
102
+ pageIndexRef.current++;
103
+ }
104
+ } catch (err) {
105
+ if (controller.signal.aborted) return;
106
+ console.error("[DataGrid] Data source error:", err);
107
+ } finally {
108
+ if (!controller.signal.aborted) {
109
+ setIsLoading(false);
110
+ setIsRefetching(false);
111
+ setIsLoadingMore(false);
112
+ }
113
+ }
114
+ }, []);
115
+ (0, react.useEffect)(() => {
116
+ fetchPage(false).catch(() => {});
117
+ return () => abortRef.current?.abort();
118
+ }, [
119
+ fetchPage,
120
+ sortingKey,
121
+ quickSearchKey,
122
+ pagination.pageSize
123
+ ]);
124
+ (0, react.useEffect)(() => {
125
+ if (paginationMode !== "server") {
126
+ hasMountedServerPaginationRef.current = false;
127
+ return;
128
+ }
129
+ if (!hasMountedServerPaginationRef.current) {
130
+ hasMountedServerPaginationRef.current = true;
131
+ return;
132
+ }
133
+ fetchPage(false).catch(() => {});
134
+ }, [
135
+ fetchPage,
136
+ paginationMode,
137
+ pagination.pageIndex
138
+ ]);
139
+ return {
140
+ rows,
141
+ totalRowCount,
142
+ isLoading,
143
+ isRefetching,
144
+ isLoadingMore,
145
+ loadMore: (0, react.useCallback)(() => {
146
+ if (!isLoadingMore && hasMore && paginationMode === "infinite") fetchPage(true).catch(() => {});
147
+ }, [
148
+ isLoadingMore,
149
+ hasMore,
150
+ paginationMode,
151
+ fetchPage
152
+ ]),
153
+ hasMore,
154
+ reload: (0, react.useCallback)(() => {
155
+ fetchPage(false).catch(() => {});
156
+ }, [fetchPage])
157
+ };
158
+ }
159
+ const NOOP_DATA_SOURCE = async function* () {};
160
+ const NOOP_GET_ROW_ID = () => "";
161
+ /**
162
+ * Hook that processes raw data through the grid's sort/pagination state
163
+ * and returns the `rows` slice ready to pass to `DataGrid`. This is the
164
+ * only correct way to feed client-side data into a grid.
165
+ *
166
+ * Two modes, picked by which prop you pass:
167
+ * - `data: TRow[]` → client-side mode. In-memory sort + paginate.
168
+ * - `dataSource: (params) => AsyncGenerator` → server / infinite mode.
169
+ * The generator yields pages as you scroll or change pages.
170
+ *
171
+ * ```tsx
172
+ * // Client-side (most common):
173
+ * const gridData = useDataSource({
174
+ * data: users,
175
+ * columns,
176
+ * getRowId: (row) => row.id,
177
+ * sorting: gridState.sorting,
178
+ * quickSearch: gridState.quickSearch,
179
+ * pagination: gridState.pagination,
180
+ * paginationMode: "client",
181
+ * });
182
+ *
183
+ * <DataGrid
184
+ * columns={columns}
185
+ * rows={gridData.rows}
186
+ * totalRowCount={gridData.totalRowCount}
187
+ * isLoading={gridData.isLoading}
188
+ * state={gridState}
189
+ * onChange={setGridState}
190
+ * getRowId={(row) => row.id}
191
+ * />
192
+ * ```
193
+ *
194
+ * Rules:
195
+ * - Call this hook unconditionally at the top level, before any early return.
196
+ * - `rows` on `DataGrid` must ALWAYS be `gridData.rows`, never your raw array.
197
+ * - For server or infinite pagination, use `dataSource` — see the
198
+ * `DataGridDataSource` type for the generator signature.
199
+ *
200
+ * Quick search:
201
+ * - Client mode (`data` prop): the hook auto-filters rows via
202
+ * `applyQuickSearch` using a default case-insensitive substring match
203
+ * across every column. Override with `matchRow` for custom matching
204
+ * (fuzzy, weighted, field-specific, etc.).
205
+ * - Async mode (`dataSource` prop): the hook passes `quickSearch` into
206
+ * `params.quickSearch` and re-runs the generator whenever the search
207
+ * string changes. The consumer owns the matching logic (typically by
208
+ * folding it into a backend query). The grid performs NO client-side
209
+ * filtering in async mode.
210
+ */
211
+ function useDataSource(opts) {
212
+ const { data, dataSource, columns, getRowId, sorting, quickSearch, matchRow = __state_js.defaultMatchRow, pagination, paginationMode } = opts;
213
+ const isClientMode = data != null && !dataSource;
214
+ const clientResult = useClientDataSource({
215
+ data: data ?? [],
216
+ columns,
217
+ sorting,
218
+ quickSearch,
219
+ matchRow,
220
+ pagination,
221
+ paginationMode
222
+ });
223
+ const asyncResult = useAsyncDataSource({
224
+ dataSource: dataSource ?? NOOP_DATA_SOURCE,
225
+ getRowId: dataSource ? getRowId : NOOP_GET_ROW_ID,
226
+ sorting,
227
+ quickSearch,
228
+ pagination,
229
+ paginationMode
230
+ });
231
+ return isClientMode ? clientResult : asyncResult;
232
+ }
233
+
234
+ //#endregion
235
+ exports.useDataSource = useDataSource;
236
+ //# sourceMappingURL=use-data-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-data-source.js","names":["defaultMatchRow"],"sources":["../../../src/components/data-grid/use-data-source.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n DataGridColumnDef,\n DataGridDataSource,\n DataGridFetchParams,\n DataGridDataPaginationMode,\n DataGridPaginationModel,\n DataGridSortModel,\n RowId,\n} from \"./types\";\nimport {\n applyQuickSearch,\n buildRowComparator,\n defaultMatchRow,\n paginateRows,\n} from \"./state\";\n\nexport type UseDataSourceResult<TRow> = {\n /** All rows currently loaded (for infinite mode, the accumulated set). */\n rows: readonly TRow[];\n /** Total row count if known. */\n totalRowCount: number | undefined;\n /** Whether the initial load is in progress (no data at all yet). */\n isLoading: boolean;\n /** Whether a background refetch is happening (data already shown). */\n isRefetching: boolean;\n /** Whether more rows are being fetched (infinite scroll). */\n isLoadingMore: boolean;\n /** Request the next page (infinite scroll). */\n loadMore: () => void;\n /** Whether there are more pages to load. */\n hasMore: boolean;\n /** Reload from scratch. */\n reload: () => void;\n};\n\n// ─── Client-side hook ────────────────────────────────────────────────\n// Memoised so resize / selection / other unrelated state changes\n// don't recompute or create new array references.\n\nfunction useClientDataSource<TRow>(opts: {\n data: readonly TRow[];\n columns: readonly DataGridColumnDef<TRow>[];\n sorting: DataGridSortModel;\n quickSearch: string;\n matchRow: (\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n ) => boolean;\n pagination: DataGridPaginationModel;\n paginationMode: DataGridDataPaginationMode;\n}): UseDataSourceResult<TRow> {\n const { data, columns, sorting, quickSearch, matchRow, pagination, paginationMode } = opts;\n\n // Stable serialised keys so useMemo only fires on real changes\n const sortingKey = JSON.stringify(sorting);\n\n const processed = useMemo(() => {\n // Quick search is applied FIRST, on the full input. If nothing is\n // typed this is a zero-cost no-op (applyQuickSearch returns the\n // original array reference). Sort and paginate operate on the\n // already-filtered set so the result counts are search-aware.\n const searched = applyQuickSearch(data, quickSearch, columns, matchRow);\n const comparator = buildRowComparator(sorting, columns);\n const sorted = comparator ? [...searched].sort(comparator) : searched;\n const totalRowCount = sorted.length;\n const paged =\n paginationMode === \"client\"\n ? paginateRows(sorted as readonly TRow[], pagination)\n : sorted;\n return { rows: paged, totalRowCount };\n }, [data, sortingKey, quickSearch, matchRow, pagination.pageIndex, pagination.pageSize, paginationMode, columns]);\n\n return useMemo(() => ({\n rows: processed.rows,\n totalRowCount: processed.totalRowCount,\n isLoading: false,\n isRefetching: false,\n isLoadingMore: false,\n loadMore: () => {},\n hasMore: false,\n reload: () => {},\n }), [processed]);\n}\n\n// ─── Async data source hook ──────────────────────────────────────────\n// Key behaviour: when refetching (sort change), we keep showing the old\n// rows and set `isRefetching` instead of `isLoading`. This avoids the\n// jarring flash-to-skeleton on every sort toggle.\n\nfunction useAsyncDataSource<TRow>(opts: {\n dataSource: DataGridDataSource<TRow>;\n getRowId: (row: TRow) => RowId;\n sorting: DataGridSortModel;\n quickSearch: string;\n pagination: DataGridPaginationModel;\n paginationMode: DataGridDataPaginationMode;\n}): UseDataSourceResult<TRow> {\n const {\n dataSource,\n getRowId,\n sorting,\n quickSearch,\n pagination,\n paginationMode,\n } = opts;\n\n const [rows, setRows] = useState<TRow[]>([]);\n const [totalRowCount, setTotalRowCount] = useState<number | undefined>(undefined);\n const [isLoading, setIsLoading] = useState(true);\n const [isRefetching, setIsRefetching] = useState(false);\n const [isLoadingMore, setIsLoadingMore] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n\n const cursorRef = useRef<unknown>(undefined);\n const abortRef = useRef<AbortController | null>(null);\n const pageIndexRef = useRef(0);\n const hasDataRef = useRef(false);\n const hasMountedServerPaginationRef = useRef(false);\n\n const latestArgsRef = useRef({\n dataSource,\n getRowId,\n sorting,\n quickSearch,\n pagination,\n });\n latestArgsRef.current = { dataSource, getRowId, sorting, quickSearch, pagination };\n\n const sortingKey = JSON.stringify(sorting);\n const quickSearchKey = quickSearch;\n\n const fetchPage = useCallback(\n async (append: boolean) => {\n const {\n dataSource: currentDataSource,\n getRowId: currentGetRowId,\n sorting: currentSorting,\n quickSearch: currentQuickSearch,\n pagination: currentPagination,\n } = latestArgsRef.current;\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n if (append) {\n setIsLoadingMore(true);\n } else {\n // First load → skeleton. Subsequent → subtle refetch indicator.\n if (hasDataRef.current) {\n setIsRefetching(true);\n } else {\n setIsLoading(true);\n }\n cursorRef.current = undefined;\n pageIndexRef.current = 0;\n }\n\n try {\n const params: DataGridFetchParams = {\n sorting: currentSorting,\n quickSearch: currentQuickSearch,\n pagination: append\n ? { pageIndex: pageIndexRef.current, pageSize: currentPagination.pageSize }\n : currentPagination,\n cursor: cursorRef.current,\n };\n\n const gen = currentDataSource(params);\n\n for await (const result of gen) {\n if (controller.signal.aborted) return;\n\n if (result.totalRowCount != null) {\n setTotalRowCount(result.totalRowCount);\n }\n if (result.nextCursor !== undefined) {\n cursorRef.current = result.nextCursor;\n }\n setHasMore(result.hasMore !== false);\n\n if (append) {\n setRows((prev) => {\n const existingIds = new Set(prev.map(currentGetRowId));\n const newRows = result.rows.filter(\n (r) => !existingIds.has(currentGetRowId(r)),\n );\n return [...prev, ...newRows];\n });\n } else {\n setRows(result.rows);\n }\n\n hasDataRef.current = true;\n pageIndexRef.current++;\n }\n } catch (err) {\n if (controller.signal.aborted) return;\n console.error(\"[DataGrid] Data source error:\", err);\n } finally {\n if (!controller.signal.aborted) {\n setIsLoading(false);\n setIsRefetching(false);\n setIsLoadingMore(false);\n }\n }\n },\n [],\n );\n\n useEffect(() => {\n fetchPage(false).catch(() => {});\n return () => abortRef.current?.abort();\n }, [fetchPage, sortingKey, quickSearchKey, pagination.pageSize]);\n\n useEffect(() => {\n if (paginationMode !== \"server\") {\n hasMountedServerPaginationRef.current = false;\n return;\n }\n if (!hasMountedServerPaginationRef.current) {\n hasMountedServerPaginationRef.current = true;\n return;\n }\n fetchPage(false).catch(() => {});\n }, [fetchPage, paginationMode, pagination.pageIndex]);\n\n const loadMore = useCallback(() => {\n if (!isLoadingMore && hasMore && paginationMode === \"infinite\") {\n fetchPage(true).catch(() => {});\n }\n }, [isLoadingMore, hasMore, paginationMode, fetchPage]);\n\n const reload = useCallback(() => {\n fetchPage(false).catch(() => {});\n }, [fetchPage]);\n\n return {\n rows,\n totalRowCount,\n isLoading,\n isRefetching,\n isLoadingMore,\n loadMore,\n hasMore,\n reload,\n };\n}\n\n// ─── Noop data source (stable reference) ─────────────────────────────\nconst NOOP_DATA_SOURCE: DataGridDataSource<any> = async function* () {};\nconst NOOP_GET_ROW_ID = () => \"\";\n\n// ─── Public hook ─────────────────────────────────────────────────────\n// Both inner hooks are always called (React rules-of-hooks) but only\n// one provides the returned result.\n\n/**\n * Hook that processes raw data through the grid's sort/pagination state\n * and returns the `rows` slice ready to pass to `DataGrid`. This is the\n * only correct way to feed client-side data into a grid.\n *\n * Two modes, picked by which prop you pass:\n * - `data: TRow[]` → client-side mode. In-memory sort + paginate.\n * - `dataSource: (params) => AsyncGenerator` → server / infinite mode.\n * The generator yields pages as you scroll or change pages.\n *\n * ```tsx\n * // Client-side (most common):\n * const gridData = useDataSource({\n * data: users,\n * columns,\n * getRowId: (row) => row.id,\n * sorting: gridState.sorting,\n * quickSearch: gridState.quickSearch,\n * pagination: gridState.pagination,\n * paginationMode: \"client\",\n * });\n *\n * <DataGrid\n * columns={columns}\n * rows={gridData.rows}\n * totalRowCount={gridData.totalRowCount}\n * isLoading={gridData.isLoading}\n * state={gridState}\n * onChange={setGridState}\n * getRowId={(row) => row.id}\n * />\n * ```\n *\n * Rules:\n * - Call this hook unconditionally at the top level, before any early return.\n * - `rows` on `DataGrid` must ALWAYS be `gridData.rows`, never your raw array.\n * - For server or infinite pagination, use `dataSource` — see the\n * `DataGridDataSource` type for the generator signature.\n *\n * Quick search:\n * - Client mode (`data` prop): the hook auto-filters rows via\n * `applyQuickSearch` using a default case-insensitive substring match\n * across every column. Override with `matchRow` for custom matching\n * (fuzzy, weighted, field-specific, etc.).\n * - Async mode (`dataSource` prop): the hook passes `quickSearch` into\n * `params.quickSearch` and re-runs the generator whenever the search\n * string changes. The consumer owns the matching logic (typically by\n * folding it into a backend query). The grid performs NO client-side\n * filtering in async mode.\n */\nexport function useDataSource<TRow>(opts: {\n data?: readonly TRow[];\n dataSource?: DataGridDataSource<TRow>;\n columns: readonly DataGridColumnDef<TRow>[];\n getRowId: (row: TRow) => RowId;\n sorting: DataGridSortModel;\n /** Current quick-search text, typically `gridState.quickSearch`. */\n quickSearch: string;\n /** Override the default client-mode matcher. Ignored in async mode\n * (there the generator is the matcher). */\n matchRow?: (\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n ) => boolean;\n pagination: DataGridPaginationModel;\n paginationMode: DataGridDataPaginationMode;\n}): UseDataSourceResult<TRow> {\n const {\n data,\n dataSource,\n columns,\n getRowId,\n sorting,\n quickSearch,\n matchRow = defaultMatchRow,\n pagination,\n paginationMode,\n } = opts;\n\n const isClientMode = data != null && !dataSource;\n\n const clientResult = useClientDataSource({\n data: data ?? [],\n columns,\n sorting,\n quickSearch,\n matchRow,\n pagination,\n paginationMode,\n });\n\n const asyncResult = useAsyncDataSource({\n dataSource: dataSource ?? NOOP_DATA_SOURCE,\n getRowId: dataSource ? getRowId : NOOP_GET_ROW_ID,\n sorting,\n quickSearch,\n pagination,\n paginationMode,\n });\n\n return isClientMode ? clientResult : asyncResult;\n}\n"],"mappings":"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"}
@@ -9,6 +9,22 @@ type DesignEmptyStateProps = {
9
9
  children?: React.ReactNode;
10
10
  className?: string;
11
11
  };
12
+ /**
13
+ * Centered "no data" placeholder. Show this inside a `DataGrid` via the
14
+ * `emptyState` prop, inside a chart when a query returns zero rows, or
15
+ * inside a card when a section has nothing to display.
16
+ *
17
+ * ```tsx
18
+ * <DesignEmptyState
19
+ * icon={SearchIcon}
20
+ * title="No results"
21
+ * description="Try adjusting your filters."
22
+ * />
23
+ * ```
24
+ *
25
+ * Prefer this over a raw "No data" div — it handles spacing, typography,
26
+ * and the optional icon for you. `icon` is a component type, not a rendered node.
27
+ */
12
28
  declare function DesignEmptyState({
13
29
  icon: Icon,
14
30
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"empty-state.d.ts","names":[],"sources":["../../src/components/empty-state.tsx"],"mappings":";;;;KAKY,qBAAA;EACV,IAAA,GAAO,KAAA,CAAM,WAAA;EACb,KAAA;EACA,WAAA;EACA,QAAA,GAAW,KAAA,CAAM,SAAA;EACjB,SAAA;AAAA;AAAA,iBAGc,gBAAA,CAAA;EACd,IAAA,EAAM,IAAA;EACN,KAAA;EACA,WAAA;EACA,QAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"empty-state.d.ts","names":[],"sources":["../../src/components/empty-state.tsx"],"mappings":";;;;KAKY,qBAAA;EACV,IAAA,GAAO,KAAA,CAAM,WAAA;EACb,KAAA;EACA,WAAA;EACA,QAAA,GAAW,KAAA,CAAM,SAAA;EACjB,SAAA;AAAA;;;;;;;;;;;;AAmBF;;;;;iBAAgB,gBAAA,CAAA;EACd,IAAA,EAAM,IAAA;EACN,KAAA;EACA,WAAA;EACA,QAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -8,6 +8,22 @@ let react = require("react");
8
8
  react = require_chunk.__toESM(react);
9
9
 
10
10
  //#region src/components/empty-state.tsx
11
+ /**
12
+ * Centered "no data" placeholder. Show this inside a `DataGrid` via the
13
+ * `emptyState` prop, inside a chart when a query returns zero rows, or
14
+ * inside a card when a section has nothing to display.
15
+ *
16
+ * ```tsx
17
+ * <DesignEmptyState
18
+ * icon={SearchIcon}
19
+ * title="No results"
20
+ * description="Try adjusting your filters."
21
+ * />
22
+ * ```
23
+ *
24
+ * Prefer this over a raw "No data" div — it handles spacing, typography,
25
+ * and the optional icon for you. `icon` is a component type, not a rendered node.
26
+ */
11
27
  function DesignEmptyState({ icon: Icon, title = "No data available", description, children, className }) {
12
28
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
13
29
  className: (0, _stackframe_stack_ui.cn)("flex flex-col items-center justify-center py-12 px-6 text-center", className),