@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
@@ -1 +1 @@
1
- {"version":3,"file":"chart-legend.d.ts","names":[],"sources":["../../../src/components/chart-legend.tsx"],"mappings":";;;;cAOa,iBAAA,SAAiB,iBAAA,CAAA,MAAA;AAAA,cAEjB,wBAAA,EAAwB,OAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,OAAA,CAAA,eAAA,CAAA,cAAA,IAAA,OAAA,CAAA,cAAA,CAAA,cAAA,IAAA,IAAA,CAAA,iBAAA,CAAA,WAAA"}
1
+ {"version":3,"file":"chart-legend.d.ts","names":[],"sources":["../../../src/components/chart-legend.tsx"],"mappings":";;;;cAOa,wBAAA,EAAwB,OAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,OAAA,CAAA,eAAA,CAAA,cAAA,IAAA,OAAA,CAAA,cAAA,CAAA,cAAA,IAAA,IAAA,CAAA,iBAAA,CAAA,WAAA"}
@@ -3,11 +3,9 @@
3
3
  import { cn } from "@stackframe/stack-ui";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import * as React$1 from "react";
6
- import * as RechartsPrimitive from "recharts";
7
6
  import { getPayloadConfigFromPayload, useDesignChart } from "./chart-container.js";
8
7
 
9
8
  //#region src/components/chart-legend.tsx
10
- const DesignChartLegend = RechartsPrimitive.Legend;
11
9
  const DesignChartLegendContent = React$1.forwardRef(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => {
12
10
  const { config } = useDesignChart();
13
11
  if (!payload?.length) return null;
@@ -32,5 +30,5 @@ const DesignChartLegendContent = React$1.forwardRef(({ className, hideIcon = fal
32
30
  DesignChartLegendContent.displayName = "DesignChartLegendContent";
33
31
 
34
32
  //#endregion
35
- export { DesignChartLegend, DesignChartLegendContent };
33
+ export { DesignChartLegendContent };
36
34
  //# sourceMappingURL=chart-legend.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-legend.js","names":["React"],"sources":["../../../src/components/chart-legend.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport { cn } from \"@stackframe/stack-ui\";\nimport { useDesignChart, getPayloadConfigFromPayload } from \"./chart-container\";\n\nexport const DesignChartLegend = RechartsPrimitive.Legend;\n\nexport const DesignChartLegendContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> &\n Pick<RechartsPrimitive.LegendProps, \"payload\" | \"verticalAlign\"> & {\n hideIcon?: boolean,\n nameKey?: string,\n }\n>(\n (\n { className, hideIcon = false, payload, verticalAlign = \"bottom\", nameKey },\n ref\n ) => {\n const { config } = useDesignChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center justify-center gap-2\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className\n )}\n >\n {payload.map((item) => {\n const key = `${nameKey || item.dataKey || \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={item.value}\n className={cn(\n \"flex items-center gap-1.5 rounded-full bg-foreground/[0.03] ring-1 ring-foreground/[0.06] px-3 py-1.5 text-xs\",\n \"transition-colors duration-150 hover:transition-none hover:bg-foreground/[0.05]\"\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: item.color }}\n />\n )}\n <span className=\"font-medium text-foreground\">\n {itemConfig?.label || item.value}\n </span>\n </div>\n );\n })}\n </div>\n );\n }\n);\nDesignChartLegendContent.displayName = \"DesignChartLegendContent\";\n"],"mappings":";;;;;;;;;AAOA,MAAa,oBAAoB,kBAAkB;AAEnD,MAAa,2BAA2BA,QAAM,YAS1C,EAAE,WAAW,WAAW,OAAO,SAAS,gBAAgB,UAAU,WAClE,QACG;CACH,MAAM,EAAE,WAAW,gBAAgB;AAEnC,KAAI,CAAC,SAAS,OACZ,QAAO;AAGT,QACE,oBAAC;EACM;EACL,WAAW,GACT,oDACA,kBAAkB,QAAQ,SAAS,QACnC,UACD;YAEA,QAAQ,KAAK,SAAS;GAErB,MAAM,aAAa,4BAA4B,QAAQ,MAD3C,GAAG,WAAW,KAAK,WAAW,UACuB;AAEjE,UACE,qBAAC;IAEC,WAAW,GACT,iHACA,kFACD;eAEA,YAAY,QAAQ,CAAC,WACpB,oBAAC,WAAW,SAAO,GAEnB,oBAAC;KACC,WAAU;KACV,OAAO,EAAE,iBAAiB,KAAK,OAAO;MACtC,EAEJ,oBAAC;KAAK,WAAU;eACb,YAAY,SAAS,KAAK;MACtB;MAhBF,KAAK,MAiBN;IAER;GACE;EAGX;AACD,yBAAyB,cAAc"}
1
+ {"version":3,"file":"chart-legend.js","names":["React"],"sources":["../../../src/components/chart-legend.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport { cn } from \"@stackframe/stack-ui\";\nimport { useDesignChart, getPayloadConfigFromPayload } from \"./chart-container\";\n\nexport const DesignChartLegendContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> &\n Pick<RechartsPrimitive.LegendProps, \"payload\" | \"verticalAlign\"> & {\n hideIcon?: boolean,\n nameKey?: string,\n }\n>(\n (\n { className, hideIcon = false, payload, verticalAlign = \"bottom\", nameKey },\n ref\n ) => {\n const { config } = useDesignChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-wrap items-center justify-center gap-2\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className\n )}\n >\n {payload.map((item) => {\n const key = `${nameKey || item.dataKey || \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={item.value}\n className={cn(\n \"flex items-center gap-1.5 rounded-full bg-foreground/[0.03] ring-1 ring-foreground/[0.06] px-3 py-1.5 text-xs\",\n \"transition-colors duration-150 hover:transition-none hover:bg-foreground/[0.05]\"\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: item.color }}\n />\n )}\n <span className=\"font-medium text-foreground\">\n {itemConfig?.label || item.value}\n </span>\n </div>\n );\n })}\n </div>\n );\n }\n);\nDesignChartLegendContent.displayName = \"DesignChartLegendContent\";\n"],"mappings":";;;;;;;;AAOA,MAAa,2BAA2BA,QAAM,YAS1C,EAAE,WAAW,WAAW,OAAO,SAAS,gBAAgB,UAAU,WAClE,QACG;CACH,MAAM,EAAE,WAAW,gBAAgB;AAEnC,KAAI,CAAC,SAAS,OACZ,QAAO;AAGT,QACE,oBAAC;EACM;EACL,WAAW,GACT,oDACA,kBAAkB,QAAQ,SAAS,QACnC,UACD;YAEA,QAAQ,KAAK,SAAS;GAErB,MAAM,aAAa,4BAA4B,QAAQ,MAD3C,GAAG,WAAW,KAAK,WAAW,UACuB;AAEjE,UACE,qBAAC;IAEC,WAAW,GACT,iHACA,kFACD;eAEA,YAAY,QAAQ,CAAC,WACpB,oBAAC,WAAW,SAAO,GAEnB,oBAAC;KACC,WAAU;KACV,OAAO,EAAE,iBAAiB,KAAK,OAAO;MACtC,EAEJ,oBAAC;KAAK,WAAU;eACb,YAAY,SAAS,KAAK;MACtB;MAhBF,KAAK,MAiBN;IAER;GACE;EAGX;AACD,yBAAyB,cAAc"}
@@ -0,0 +1,11 @@
1
+ import { CSSProperties } from "react";
2
+ import { DataGridColumnDef } from "./types";
3
+
4
+ //#region src/components/data-grid/data-grid-sizing.d.ts
5
+ declare function getColumnSizingStyle<TRow>(col: DataGridColumnDef<TRow>): CSSProperties;
6
+ declare function createGridSizingStyle(widths: ReadonlyMap<string, number>, totalWidth: number): Record<string, string>;
7
+ declare function applyDraggedColumnWidth(el: HTMLElement, columnId: string, width: number, totalWidth: number): void;
8
+ declare function clampColumnWidth<TRow>(col: DataGridColumnDef<TRow>, width: number): number;
9
+ //#endregion
10
+ export { applyDraggedColumnWidth, clampColumnWidth, createGridSizingStyle, getColumnSizingStyle };
11
+ //# sourceMappingURL=data-grid-sizing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-grid-sizing.d.ts","names":[],"sources":["../../../../src/components/data-grid/data-grid-sizing.ts"],"mappings":";;;;iBAWgB,oBAAA,MAAA,CAA2B,GAAA,EAAK,iBAAA,CAAkB,IAAA,IAAQ,aAAA;AAAA,iBAK1D,qBAAA,CACd,MAAA,EAAQ,WAAA,kBACR,UAAA,WACC,MAAA;AAAA,iBAQa,uBAAA,CACd,EAAA,EAAI,WAAA,EACJ,QAAA,UACA,KAAA,UACA,UAAA;AAAA,iBAMc,gBAAA,MAAA,CAAuB,GAAA,EAAK,iBAAA,CAAkB,IAAA,GAAO,KAAA"}
@@ -0,0 +1,29 @@
1
+ //#region src/components/data-grid/data-grid-sizing.ts
2
+ function colVar(id) {
3
+ return `--col-${id}`;
4
+ }
5
+ function getColumnSizingStyle(col) {
6
+ const w = `var(${colVar(col.id)})`;
7
+ return {
8
+ flex: `0 0 ${w}`,
9
+ width: w,
10
+ minWidth: col.minWidth ?? 50,
11
+ maxWidth: col.maxWidth ?? 800
12
+ };
13
+ }
14
+ function createGridSizingStyle(widths, totalWidth) {
15
+ const style = { "--grid-total-w": `${totalWidth}px` };
16
+ for (const [id, w] of widths) style[colVar(id)] = `${w}px`;
17
+ return style;
18
+ }
19
+ function applyDraggedColumnWidth(el, columnId, width, totalWidth) {
20
+ el.style.setProperty(colVar(columnId), `${width}px`);
21
+ el.style.setProperty("--grid-total-w", `${totalWidth}px`);
22
+ }
23
+ function clampColumnWidth(col, width) {
24
+ return Math.max(col.minWidth ?? 50, Math.min(col.maxWidth ?? 800, width));
25
+ }
26
+
27
+ //#endregion
28
+ export { applyDraggedColumnWidth, clampColumnWidth, createGridSizingStyle, getColumnSizingStyle };
29
+ //# sourceMappingURL=data-grid-sizing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-grid-sizing.js","names":[],"sources":["../../../../src/components/data-grid/data-grid-sizing.ts"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { DataGridColumnDef } from \"./types\";\n\n// CSS variable names for column widths set on the grid container.\n// Cells read these via var(...) so a single setProperty during drag\n// resizes every cell in a column with zero React re-renders.\n\nfunction colVar(id: string): `--col-${string}` {\n return `--col-${id}`;\n}\n\nexport function getColumnSizingStyle<TRow>(col: DataGridColumnDef<TRow>): CSSProperties {\n const w = `var(${colVar(col.id)})`;\n return { flex: `0 0 ${w}`, width: w, minWidth: col.minWidth ?? 50, maxWidth: col.maxWidth ?? 800 };\n}\n\nexport function createGridSizingStyle(\n widths: ReadonlyMap<string, number>,\n totalWidth: number,\n): Record<string, string> {\n const style: Record<string, string> = { \"--grid-total-w\": `${totalWidth}px` };\n for (const [id, w] of widths) {\n style[colVar(id)] = `${w}px`;\n }\n return style;\n}\n\nexport function applyDraggedColumnWidth(\n el: HTMLElement,\n columnId: string,\n width: number,\n totalWidth: number,\n) {\n el.style.setProperty(colVar(columnId), `${width}px`);\n el.style.setProperty(\"--grid-total-w\", `${totalWidth}px`);\n}\n\nexport function clampColumnWidth<TRow>(col: DataGridColumnDef<TRow>, width: number): number {\n return Math.max(col.minWidth ?? 50, Math.min(col.maxWidth ?? 800, width));\n}\n"],"mappings":";AAOA,SAAS,OAAO,IAA+B;AAC7C,QAAO,SAAS;;AAGlB,SAAgB,qBAA2B,KAA6C;CACtF,MAAM,IAAI,OAAO,OAAO,IAAI,GAAG,CAAC;AAChC,QAAO;EAAE,MAAM,OAAO;EAAK,OAAO;EAAG,UAAU,IAAI,YAAY;EAAI,UAAU,IAAI,YAAY;EAAK;;AAGpG,SAAgB,sBACd,QACA,YACwB;CACxB,MAAM,QAAgC,EAAE,kBAAkB,GAAG,WAAW,KAAK;AAC7E,MAAK,MAAM,CAAC,IAAI,MAAM,OACpB,OAAM,OAAO,GAAG,IAAI,GAAG,EAAE;AAE3B,QAAO;;AAGT,SAAgB,wBACd,IACA,UACA,OACA,YACA;AACA,IAAG,MAAM,YAAY,OAAO,SAAS,EAAE,GAAG,MAAM,IAAI;AACpD,IAAG,MAAM,YAAY,kBAAkB,GAAG,WAAW,IAAI;;AAG3D,SAAgB,iBAAuB,KAA8B,OAAuB;AAC1F,QAAO,KAAK,IAAI,IAAI,YAAY,IAAI,KAAK,IAAI,IAAI,YAAY,KAAK,MAAM,CAAC"}
@@ -0,0 +1,31 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { DataGridToolbarContext } from "./types";
4
+
5
+ //#region src/components/data-grid/data-grid-toolbar.d.ts
6
+ declare function DataGridToolbar<TRow>({
7
+ ctx,
8
+ extra,
9
+ extraLeading,
10
+ hideQuickSearch
11
+ }: {
12
+ ctx: DataGridToolbarContext<TRow>;
13
+ /** Extra content rendered inside the toolbar row, to the left of the
14
+ * built-in columns / export actions. Use this to add table-specific
15
+ * affordances (refresh, custom toggles, row counts) without giving up
16
+ * the default actions. */
17
+ extra?: React.ReactNode;
18
+ /** Extra content rendered at the START of the toolbar row — occupies
19
+ * the same position as the built-in quick search (after it, if the
20
+ * quick search is visible). Use this together with `hideQuickSearch`
21
+ * to fully replace the quick search with a custom input, e.g. an
22
+ * AI-powered search bar. */
23
+ extraLeading?: React.ReactNode;
24
+ /** Whether to hide the built-in quick-search input. When `true`,
25
+ * callers are expected to provide their own search UI via
26
+ * `extraLeading`. */
27
+ hideQuickSearch?: boolean;
28
+ }): react_jsx_runtime0.JSX.Element;
29
+ //#endregion
30
+ export { DataGridToolbar };
31
+ //# sourceMappingURL=data-grid-toolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-grid-toolbar.d.ts","names":[],"sources":["../../../../src/components/data-grid/data-grid-toolbar.tsx"],"mappings":";;;;;iBA6QgB,eAAA,MAAA,CAAA;EACd,GAAA;EACA,KAAA;EACA,YAAA;EACA;AAAA;EAEA,GAAA,EAAK,sBAAA,CAAuB,IAAA;;AAN9B;;;EAWE,KAAA,GAAQ,KAAA,CAAM,SAAA;EATd;;;;;EAeA,YAAA,GAAe,KAAA,CAAM,SAAA;EAAN;;;EAIf,eAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,223 @@
1
+ "use client";
2
+
3
+ import { Check, DownloadSimple, Eye, EyeSlash, MagnifyingGlass, X } from "@phosphor-icons/react";
4
+ import { cn } from "@stackframe/stack-ui";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import React, { useCallback, useMemo, useRef, useState } from "react";
7
+
8
+ //#region src/components/data-grid/data-grid-toolbar.tsx
9
+ function usePopover() {
10
+ const [open, setOpen] = useState(false);
11
+ const ref = useRef(null);
12
+ React.useEffect(() => {
13
+ if (!open) return;
14
+ const handler = (e) => {
15
+ if (ref.current && !ref.current.contains(e.target)) setOpen(false);
16
+ };
17
+ document.addEventListener("mousedown", handler);
18
+ return () => document.removeEventListener("mousedown", handler);
19
+ }, [open]);
20
+ React.useEffect(() => {
21
+ if (!open) return;
22
+ const handler = (e) => {
23
+ if (e.key === "Escape") setOpen(false);
24
+ };
25
+ document.addEventListener("keydown", handler);
26
+ return () => document.removeEventListener("keydown", handler);
27
+ }, [open]);
28
+ return {
29
+ open,
30
+ setOpen,
31
+ ref
32
+ };
33
+ }
34
+ function PopoverPanel({ children, className, popoverRef }) {
35
+ return /* @__PURE__ */ jsx("div", {
36
+ ref: popoverRef,
37
+ className: cn("absolute top-full left-0 mt-1 z-50", "bg-popover text-popover-foreground rounded-xl shadow-lg", "ring-1 ring-black/[0.08] dark:ring-white/[0.1]", "backdrop-blur-xl", className),
38
+ children
39
+ });
40
+ }
41
+ function QuickSearch({ value, onChange, placeholder }) {
42
+ return /* @__PURE__ */ jsxs("div", {
43
+ className: "relative flex min-w-0 flex-1 items-center sm:flex-initial",
44
+ children: [
45
+ /* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-2.5 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" }),
46
+ /* @__PURE__ */ jsx("input", {
47
+ type: "text",
48
+ className: cn("h-8 w-full sm:w-52 pl-8 pr-7 rounded-xl text-xs", "bg-background", "border border-black/[0.08] dark:border-white/[0.08]", "placeholder:text-muted-foreground/40", "focus:outline-none focus:ring-1 focus:ring-foreground/[0.1]", "transition-all duration-150"),
49
+ placeholder,
50
+ value,
51
+ onChange: (e) => onChange(e.target.value)
52
+ }),
53
+ value && /* @__PURE__ */ jsx("button", {
54
+ className: "absolute right-2 text-muted-foreground/40 hover:text-muted-foreground",
55
+ onClick: () => onChange(""),
56
+ "aria-label": "Clear search",
57
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
58
+ })
59
+ ]
60
+ });
61
+ }
62
+ function ToolbarButton({ children, onClick, active, title, className: extraClassName }) {
63
+ return /* @__PURE__ */ jsx("button", {
64
+ className: cn("relative flex items-center justify-center rounded-lg text-xs font-medium", "h-7 w-7", "transition-colors duration-75", active ? "bg-foreground/[0.06] text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-foreground/[0.04]", extraClassName),
65
+ onClick,
66
+ title,
67
+ children
68
+ });
69
+ }
70
+ function ColumnManager({ columns, visibility, onChange, strings, dateDisplay, onDateDisplayChange, hasDateColumns }) {
71
+ const hideableColumns = useMemo(() => columns.filter((c) => c.hideable !== false), [columns]);
72
+ const toggleColumn = (id) => {
73
+ const current = visibility[id] !== false;
74
+ onChange({
75
+ ...visibility,
76
+ [id]: !current
77
+ });
78
+ };
79
+ const showAll = () => {
80
+ const next = { ...visibility };
81
+ for (const col of hideableColumns) next[col.id] = true;
82
+ onChange(next);
83
+ };
84
+ const hideAll = () => {
85
+ const next = { ...visibility };
86
+ for (const col of hideableColumns) next[col.id] = false;
87
+ onChange(next);
88
+ };
89
+ return /* @__PURE__ */ jsxs("div", {
90
+ className: "p-2 min-w-[240px] max-w-[300px]",
91
+ children: [
92
+ /* @__PURE__ */ jsx("div", {
93
+ className: "max-h-[280px] overflow-y-auto space-y-0.5",
94
+ children: hideableColumns.map((col) => {
95
+ const visible = visibility[col.id] !== false;
96
+ return /* @__PURE__ */ jsxs("button", {
97
+ className: cn("flex items-center gap-2 w-full px-2.5 py-1.5 rounded-lg text-xs", "hover:bg-foreground/[0.06] transition-colors duration-75", visible ? "text-foreground" : "text-muted-foreground/50"),
98
+ onClick: () => toggleColumn(col.id),
99
+ children: [
100
+ visible ? /* @__PURE__ */ jsx(Eye, { className: "h-3.5 w-3.5 flex-shrink-0 text-blue-500" }) : /* @__PURE__ */ jsx(EyeSlash, { className: "h-3.5 w-3.5 flex-shrink-0" }),
101
+ /* @__PURE__ */ jsx("span", {
102
+ className: "truncate text-left",
103
+ children: typeof col.header === "string" ? col.header : col.id
104
+ }),
105
+ visible && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3 ml-auto flex-shrink-0 text-blue-500" })
106
+ ]
107
+ }, col.id);
108
+ })
109
+ }),
110
+ /* @__PURE__ */ jsxs("div", {
111
+ className: "flex items-center gap-2 mt-2 pt-2 border-t border-foreground/[0.06]",
112
+ children: [
113
+ /* @__PURE__ */ jsx("button", {
114
+ className: "text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75",
115
+ onClick: showAll,
116
+ children: strings.showAll
117
+ }),
118
+ /* @__PURE__ */ jsx("span", {
119
+ className: "text-muted-foreground/20",
120
+ children: "|"
121
+ }),
122
+ /* @__PURE__ */ jsx("button", {
123
+ className: "text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75",
124
+ onClick: hideAll,
125
+ children: strings.hideAll
126
+ })
127
+ ]
128
+ }),
129
+ hasDateColumns && /* @__PURE__ */ jsx("div", {
130
+ className: "mt-2 pt-2 border-t border-foreground/[0.06]",
131
+ children: /* @__PURE__ */ jsxs("div", {
132
+ className: "flex items-center justify-between gap-2 px-1",
133
+ children: [/* @__PURE__ */ jsx("span", {
134
+ className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground",
135
+ children: strings.dateFormat
136
+ }), /* @__PURE__ */ jsxs("div", {
137
+ className: "inline-flex items-center gap-0.5 rounded-lg bg-foreground/[0.04] p-0.5",
138
+ children: [/* @__PURE__ */ jsx("button", {
139
+ className: cn("px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-75", dateDisplay === "relative" ? "bg-background text-foreground shadow-sm ring-1 ring-foreground/[0.06]" : "text-muted-foreground hover:text-foreground"),
140
+ onClick: () => onDateDisplayChange("relative"),
141
+ children: strings.dateFormatRelative
142
+ }), /* @__PURE__ */ jsx("button", {
143
+ className: cn("px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-75", dateDisplay === "absolute" ? "bg-background text-foreground shadow-sm ring-1 ring-foreground/[0.06]" : "text-muted-foreground hover:text-foreground"),
144
+ onClick: () => onDateDisplayChange("absolute"),
145
+ children: strings.dateFormatAbsolute
146
+ })]
147
+ })]
148
+ })
149
+ })
150
+ ]
151
+ });
152
+ }
153
+ function DataGridToolbar({ ctx, extra, extraLeading, hideQuickSearch }) {
154
+ const { state, onChange, columns, strings, exportCsv } = ctx;
155
+ const columnPopover = usePopover();
156
+ const updateVisibility = useCallback((visibility) => {
157
+ onChange((s) => ({
158
+ ...s,
159
+ columnVisibility: visibility
160
+ }));
161
+ }, [onChange]);
162
+ const updateDateDisplay = useCallback((mode) => {
163
+ onChange((s) => ({
164
+ ...s,
165
+ dateDisplay: mode
166
+ }));
167
+ }, [onChange]);
168
+ const updateQuickSearch = useCallback((value) => {
169
+ onChange((s) => ({
170
+ ...s,
171
+ quickSearch: value,
172
+ pagination: {
173
+ ...s.pagination,
174
+ pageIndex: 0
175
+ }
176
+ }));
177
+ }, [onChange]);
178
+ const hasDateColumns = useMemo(() => columns.some((c) => c.type === "date" || c.type === "dateTime"), [columns]);
179
+ return /* @__PURE__ */ jsxs("div", {
180
+ className: "flex items-center gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06]",
181
+ children: [
182
+ !hideQuickSearch && /* @__PURE__ */ jsx(QuickSearch, {
183
+ value: state.quickSearch,
184
+ onChange: updateQuickSearch,
185
+ placeholder: strings.searchPlaceholder
186
+ }),
187
+ extraLeading,
188
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0" }),
189
+ extra,
190
+ /* @__PURE__ */ jsxs("div", {
191
+ className: "relative shrink-0",
192
+ ref: columnPopover.ref,
193
+ children: [/* @__PURE__ */ jsx(ToolbarButton, {
194
+ onClick: () => columnPopover.setOpen(!columnPopover.open),
195
+ active: columnPopover.open,
196
+ title: strings.columns,
197
+ children: /* @__PURE__ */ jsx(Eye, { className: "h-3.5 w-3.5" })
198
+ }), columnPopover.open && /* @__PURE__ */ jsx(PopoverPanel, {
199
+ popoverRef: columnPopover.ref,
200
+ className: "right-0 left-auto",
201
+ children: /* @__PURE__ */ jsx(ColumnManager, {
202
+ columns,
203
+ visibility: state.columnVisibility,
204
+ onChange: updateVisibility,
205
+ strings,
206
+ dateDisplay: state.dateDisplay,
207
+ onDateDisplayChange: updateDateDisplay,
208
+ hasDateColumns
209
+ })
210
+ })]
211
+ }),
212
+ /* @__PURE__ */ jsx(ToolbarButton, {
213
+ onClick: exportCsv,
214
+ title: strings.export,
215
+ children: /* @__PURE__ */ jsx(DownloadSimple, { className: "h-3.5 w-3.5" })
216
+ })
217
+ ]
218
+ });
219
+ }
220
+
221
+ //#endregion
222
+ export { DataGridToolbar };
223
+ //# sourceMappingURL=data-grid-toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-grid-toolbar.js","names":[],"sources":["../../../../src/components/data-grid/data-grid-toolbar.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"@stackframe/stack-ui\";\nimport {\n Check,\n DownloadSimple,\n Eye,\n EyeSlash,\n MagnifyingGlass,\n X,\n} from \"@phosphor-icons/react\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n DataGridColumnDef,\n DataGridDateDisplay,\n DataGridStrings,\n DataGridToolbarContext,\n} from \"./types\";\n\n// ─── Popover primitive ───────────────────────────────────────────────\n\nfunction usePopover() {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open]);\n\n return { open, setOpen, ref };\n}\n\nfunction PopoverPanel({\n children,\n className,\n popoverRef,\n}: {\n children: React.ReactNode;\n className?: string;\n popoverRef: React.Ref<HTMLDivElement>;\n}) {\n return (\n <div\n ref={popoverRef}\n className={cn(\n \"absolute top-full left-0 mt-1 z-50\",\n \"bg-popover text-popover-foreground rounded-xl shadow-lg\",\n \"ring-1 ring-black/[0.08] dark:ring-white/[0.1]\",\n \"backdrop-blur-xl\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// ─── Quick search ────────────────────────────────────────────────────\n\nfunction QuickSearch({\n value,\n onChange,\n placeholder,\n}: {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}) {\n return (\n <div className=\"relative flex min-w-0 flex-1 items-center sm:flex-initial\">\n <MagnifyingGlass className=\"absolute left-2.5 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none\" />\n <input\n type=\"text\"\n className={cn(\n \"h-8 w-full sm:w-52 pl-8 pr-7 rounded-xl text-xs\",\n \"bg-background\",\n \"border border-black/[0.08] dark:border-white/[0.08]\",\n \"placeholder:text-muted-foreground/40\",\n \"focus:outline-none focus:ring-1 focus:ring-foreground/[0.1]\",\n \"transition-all duration-150\",\n )}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n />\n {value && (\n <button\n className=\"absolute right-2 text-muted-foreground/40 hover:text-muted-foreground\"\n onClick={() => onChange(\"\")}\n aria-label=\"Clear search\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n );\n}\n\n// ─── Toolbar button ──────────────────────────────────────────────────\n\nfunction ToolbarButton({\n children,\n onClick,\n active,\n title,\n className: extraClassName,\n}: {\n children: React.ReactNode;\n onClick?: () => void;\n active?: boolean;\n title?: string;\n className?: string;\n}) {\n return (\n <button\n className={cn(\n \"relative flex items-center justify-center rounded-lg text-xs font-medium\",\n \"h-7 w-7\",\n \"transition-colors duration-75\",\n active\n ? \"bg-foreground/[0.06] text-foreground\"\n : \"text-muted-foreground hover:text-foreground hover:bg-foreground/[0.04]\",\n extraClassName,\n )}\n onClick={onClick}\n title={title}\n >\n {children}\n </button>\n );\n}\n\n// ─── Column manager ──────────────────────────────────────────────────\n\nfunction ColumnManager<TRow>({\n columns,\n visibility,\n onChange,\n strings,\n dateDisplay,\n onDateDisplayChange,\n hasDateColumns,\n}: {\n columns: readonly DataGridColumnDef<TRow>[];\n visibility: Record<string, boolean>;\n onChange: (visibility: Record<string, boolean>) => void;\n strings: DataGridStrings;\n dateDisplay: DataGridDateDisplay;\n onDateDisplayChange: (mode: DataGridDateDisplay) => void;\n hasDateColumns: boolean;\n}) {\n const hideableColumns = useMemo(\n () => columns.filter((c) => c.hideable !== false),\n [columns],\n );\n\n const toggleColumn = (id: string) => {\n const current = visibility[id] !== false;\n onChange({ ...visibility, [id]: !current });\n };\n\n const showAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = true;\n onChange(next);\n };\n\n const hideAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = false;\n onChange(next);\n };\n\n return (\n <div className=\"p-2 min-w-[240px] max-w-[300px]\">\n <div className=\"max-h-[280px] overflow-y-auto space-y-0.5\">\n {hideableColumns.map((col) => {\n const visible = visibility[col.id] !== false;\n return (\n <button\n key={col.id}\n className={cn(\n \"flex items-center gap-2 w-full px-2.5 py-1.5 rounded-lg text-xs\",\n \"hover:bg-foreground/[0.06] transition-colors duration-75\",\n visible ? \"text-foreground\" : \"text-muted-foreground/50\",\n )}\n onClick={() => toggleColumn(col.id)}\n >\n {visible ? (\n <Eye className=\"h-3.5 w-3.5 flex-shrink-0 text-blue-500\" />\n ) : (\n <EyeSlash className=\"h-3.5 w-3.5 flex-shrink-0\" />\n )}\n <span className=\"truncate text-left\">\n {typeof col.header === \"string\" ? col.header : col.id}\n </span>\n {visible && <Check className=\"h-3 w-3 ml-auto flex-shrink-0 text-blue-500\" />}\n </button>\n );\n })}\n </div>\n <div className=\"flex items-center gap-2 mt-2 pt-2 border-t border-foreground/[0.06]\">\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={showAll}>\n {strings.showAll}\n </button>\n <span className=\"text-muted-foreground/20\">|</span>\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={hideAll}>\n {strings.hideAll}\n </button>\n </div>\n\n {/* Date format toggle — only rendered when at least one column\n uses `type: \"date\"` or `\"dateTime\"`. Toggling writes to\n `state.dateDisplay` and the grid re-renders every date cell. */}\n {hasDateColumns && (\n <div className=\"mt-2 pt-2 border-t border-foreground/[0.06]\">\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {strings.dateFormat}\n </span>\n <div className=\"inline-flex items-center gap-0.5 rounded-lg bg-foreground/[0.04] p-0.5\">\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-75\",\n dateDisplay === \"relative\"\n ? \"bg-background text-foreground shadow-sm ring-1 ring-foreground/[0.06]\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n onClick={() => onDateDisplayChange(\"relative\")}\n >\n {strings.dateFormatRelative}\n </button>\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-75\",\n dateDisplay === \"absolute\"\n ? \"bg-background text-foreground shadow-sm ring-1 ring-foreground/[0.06]\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n onClick={() => onDateDisplayChange(\"absolute\")}\n >\n {strings.dateFormatAbsolute}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ─── Main toolbar ────────────────────────────────────────────────────\n\nexport function DataGridToolbar<TRow>({\n ctx,\n extra,\n extraLeading,\n hideQuickSearch,\n}: {\n ctx: DataGridToolbarContext<TRow>;\n /** Extra content rendered inside the toolbar row, to the left of the\n * built-in columns / export actions. Use this to add table-specific\n * affordances (refresh, custom toggles, row counts) without giving up\n * the default actions. */\n extra?: React.ReactNode;\n /** Extra content rendered at the START of the toolbar row — occupies\n * the same position as the built-in quick search (after it, if the\n * quick search is visible). Use this together with `hideQuickSearch`\n * to fully replace the quick search with a custom input, e.g. an\n * AI-powered search bar. */\n extraLeading?: React.ReactNode;\n /** Whether to hide the built-in quick-search input. When `true`,\n * callers are expected to provide their own search UI via\n * `extraLeading`. */\n hideQuickSearch?: boolean;\n}) {\n const { state, onChange, columns, strings, exportCsv } = ctx;\n\n const columnPopover = usePopover();\n\n const updateVisibility = useCallback(\n (visibility: Record<string, boolean>) => {\n onChange((s) => ({ ...s, columnVisibility: visibility }));\n },\n [onChange],\n );\n\n const updateDateDisplay = useCallback(\n (mode: DataGridDateDisplay) => {\n onChange((s) => ({ ...s, dateDisplay: mode }));\n },\n [onChange],\n );\n\n const updateQuickSearch = useCallback(\n (value: string) => {\n onChange((s) => ({\n ...s,\n quickSearch: value,\n // Reset to first page whenever the search text changes,\n // otherwise you can end up on a page index that no longer\n // exists in the filtered / refetched result set.\n pagination: { ...s.pagination, pageIndex: 0 },\n }));\n },\n [onChange],\n );\n\n const hasDateColumns = useMemo(\n () => columns.some((c) => c.type === \"date\" || c.type === \"dateTime\"),\n [columns],\n );\n\n return (\n <div className=\"flex items-center gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06]\">\n {!hideQuickSearch && (\n <QuickSearch\n value={state.quickSearch}\n onChange={updateQuickSearch}\n placeholder={strings.searchPlaceholder}\n />\n )}\n {extraLeading}\n <div className=\"flex-1 min-w-0\" />\n\n {extra}\n\n <div className=\"relative shrink-0\" ref={columnPopover.ref}>\n <ToolbarButton\n onClick={() => columnPopover.setOpen(!columnPopover.open)}\n active={columnPopover.open}\n title={strings.columns}\n >\n <Eye className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n {columnPopover.open && (\n <PopoverPanel popoverRef={columnPopover.ref} className=\"right-0 left-auto\">\n <ColumnManager\n columns={columns}\n visibility={state.columnVisibility}\n onChange={updateVisibility}\n strings={strings}\n dateDisplay={state.dateDisplay}\n onDateDisplayChange={updateDateDisplay}\n hasDateColumns={hasDateColumns}\n />\n </PopoverPanel>\n )}\n </div>\n\n <ToolbarButton onClick={exportCsv} title={strings.export}>\n <DownloadSimple className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,233 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { DataGridProps } from "./types";
3
+
4
+ //#region src/components/data-grid/data-grid.d.ts
5
+ /**
6
+ * Interactive table with sorting, quick search, pagination, selection,
7
+ * and virtualization. Handles 10k+ rows smoothly. Pair with
8
+ * `useDataSource` for client-side data; use an async `dataSource`
9
+ * generator for server or infinite-scroll modes.
10
+ *
11
+ * ## Mental model (read this first — everything else depends on it)
12
+ *
13
+ * DataGrid is a **display** component. It does NOT sort, search, or
14
+ * paginate your data directly — you own that, but `useDataSource` does
15
+ * it for you. The `rows` prop is always the already-processed slice to
16
+ * show. The grid tracks user intent in `state` (sort model, quick
17
+ * search text, page index). You feed that state into `useDataSource`,
18
+ * and its output goes back in as `rows`.
19
+ *
20
+ * `useDataSource` IS the processor. Given your full dataset and the
21
+ * grid's state, it returns the searched + sorted + paginated rows
22
+ * ready to pass to DataGrid. This is the ONLY correct pattern for
23
+ * client-side data — do NOT pass a raw array to `rows`.
24
+ *
25
+ * ## Search (client vs async)
26
+ *
27
+ * - **Client mode** (`useDataSource` with `data`): a case-insensitive
28
+ * substring match across every column is applied automatically.
29
+ * Override the matcher with `matchRow` for fuzzy / weighted search,
30
+ * or disable by passing `matchRow: () => true`.
31
+ * - **Async mode** (`useDataSource` with `dataSource`): `state.quickSearch`
32
+ * is forwarded to the generator as `params.quickSearch`. Same
33
+ * mechanism as `params.sorting` — a change triggers a refetch, and
34
+ * the generator is the "matching logic" (typically a WHERE / ILIKE
35
+ * clause in the backend query). The grid does NO client-side
36
+ * filtering in async mode.
37
+ *
38
+ * ## The canonical pattern
39
+ *
40
+ * ```tsx
41
+ * // 1. Columns — define OUTSIDE the component or inside a useMemo. Must be stable.
42
+ * const columns = React.useMemo(() => [
43
+ * { id: "name", header: "Name", accessor: "name", width: 180, type: "string" },
44
+ * { id: "email", header: "Email", accessor: "email", width: 240, type: "string" },
45
+ * { id: "role", header: "Role", accessor: "role", width: 120, type: "singleSelect",
46
+ * valueOptions: [{ value: "admin", label: "Admin" }, { value: "member", label: "Member" }] },
47
+ * { id: "signUps", header: "Sign-ups", accessor: "signUps", width: 120, type: "number", align: "right",
48
+ * renderCell: ({ value }) => <span className="tabular-nums">{Number(value).toLocaleString()}</span> },
49
+ * ], []);
50
+ *
51
+ * // 2. Grid state — one hook, initialized from the columns. NEVER build the state object by hand.
52
+ * const [gridState, setGridState] = React.useState(() => createDefaultDataGridState(columns));
53
+ *
54
+ * // 3. Data source — wires your raw array through the grid state. ALWAYS call this
55
+ * // hook unconditionally at the top level (no if/return before it).
56
+ * const gridData = useDataSource({
57
+ * data: users, // your raw array (can be [] while loading)
58
+ * columns,
59
+ * getRowId: (row) => row.id,
60
+ * sorting: gridState.sorting,
61
+ * quickSearch: gridState.quickSearch,
62
+ * pagination: gridState.pagination,
63
+ * paginationMode: "client", // "client" | "server" | "infinite"
64
+ * });
65
+ *
66
+ * // 4. Render — `rows` comes from gridData.rows, NOT from your raw array.
67
+ * <DataGrid
68
+ * columns={columns}
69
+ * rows={gridData.rows}
70
+ * getRowId={(row) => row.id}
71
+ * totalRowCount={gridData.totalRowCount}
72
+ * isLoading={gridData.isLoading}
73
+ * state={gridState}
74
+ * onChange={setGridState}
75
+ * selectionMode="none" // "none" | "single" | "multiple"
76
+ * maxHeight={480}
77
+ * />
78
+ * ```
79
+ *
80
+ * ## Iron rules (violating any of these breaks the grid)
81
+ *
82
+ * 1. The prop is `rows`, NOT `data`. There is no `data` prop on DataGrid.
83
+ * `data` belongs on `useDataSource`.
84
+ * 2. `rows` is ALWAYS `gridData.rows`. Never pass your raw array to
85
+ * `rows` — the grid won't search, sort, or paginate it.
86
+ * 3. Columns must be stable across renders. Define them outside the
87
+ * component or wrap in `React.useMemo`. A fresh columns array every
88
+ * render will reset sorting state.
89
+ * 4. Initialize grid state with `createDefaultDataGridState(columns)`.
90
+ * Do NOT spell out the state object manually — you will miss fields
91
+ * and crash.
92
+ * 5. `onChange` takes a `SetStateAction` (the setter you got from
93
+ * `useState`). Pass `setGridState` directly. Do NOT wrap it unless
94
+ * you know exactly what you're doing.
95
+ * 6. Call `useDataSource` ONCE per grid, at the top level, before any
96
+ * early return. It contains hooks.
97
+ * 7. `renderCell` is a PURE function of its context. NEVER call React
98
+ * hooks inside it (no `useState`, `useMemo`, `useEffect`, nothing).
99
+ * If you need derived data per row, compute it BEFORE the render —
100
+ * e.g. build a `Map<rowId, sparklineData>` in a `useMemo` and look
101
+ * it up in `renderCell`.
102
+ * 8. `toolbar` accepts `false` (hide it) or a render function
103
+ * `(ctx) => ReactNode`. Anything else — `true`, `undefined`, a state
104
+ * variable — will either show the default toolbar or crash. If you
105
+ * just want the default toolbar, omit the prop entirely.
106
+ * 9. The toolbar's search input writes to `state.quickSearch`. That
107
+ * value is consumed by `useDataSource` — client mode filters
108
+ * client-side, async mode forwards to the generator. Do NOT wire
109
+ * a separate "controlled" search prop, everything flows through
110
+ * grid state.
111
+ *
112
+ * ## renderCell — what you can and cannot do inside it
113
+ *
114
+ * ```tsx
115
+ * // OK — pure rendering from ctx:
116
+ * renderCell: ({ value }) => <span className="tabular-nums">{Number(value).toLocaleString()}</span>
117
+ * renderCell: ({ row }) => <Badge variant={row.active ? "default" : "outline"}>{row.status}</Badge>
118
+ *
119
+ * // OK — looking up pre-computed data by row id:
120
+ * // BEFORE the return, in the component body:
121
+ * const sparklinesById = React.useMemo(() => {
122
+ * const m = new Map();
123
+ * for (const u of users) {
124
+ * m.set(u.id, u.recentActivity.map((n, i) => ({ ts: i, values: { primary: n } })));
125
+ * }
126
+ * return m;
127
+ * }, [users]);
128
+ * // Then inside the column def:
129
+ * renderCell: ({ rowId }) => <MiniSparkline data={sparklinesById.get(rowId) ?? []} />
130
+ *
131
+ * // NOT OK — hooks inside renderCell:
132
+ * renderCell: ({ row }) => {
133
+ * const [hovered, setHovered] = React.useState(false); // ← crashes the grid
134
+ * const data = React.useMemo(() => ..., []); // ← crashes the grid
135
+ * return ...;
136
+ * }
137
+ *
138
+ * // NOT OK — embedding AnalyticsChart (or any other controlled, stateful chart) per row:
139
+ * // AnalyticsChart owns its own state, tooltips, zoom, and virtualized data
140
+ * // pipeline. Instantiating one per row is expensive and fights the grid's
141
+ * // virtualizer. Don't do it.
142
+ * ```
143
+ *
144
+ * ## Sparklines and mini-charts in cells — use raw Recharts
145
+ *
146
+ * If you want a tiny chart (sparkline, micro bar chart, trend line) inside
147
+ * a cell, drop down to raw `Recharts.*` components — they are lightweight
148
+ * and stateless, so they render cleanly per row without owning any state.
149
+ * Read pre-computed points off the row (or off a `Map<rowId, points>` you
150
+ * built in a `useMemo` above) and pass them directly to the Recharts
151
+ * primitive. Do NOT wrap them in `DesignChartContainer` or
152
+ * `DesignChartCard` inside a cell — those add chrome meant for full-size
153
+ * charts.
154
+ *
155
+ * ```tsx
156
+ * // OK — raw Recharts sparkline per row:
157
+ * renderCell: ({ rowId }) => {
158
+ * const points = sparklinesById.get(rowId) ?? [];
159
+ * return (
160
+ * <Recharts.ResponsiveContainer width="100%" height={28}>
161
+ * <Recharts.LineChart data={points} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>
162
+ * <Recharts.Line type="monotone" dataKey="v" stroke="currentColor" strokeWidth={1.5} dot={false} isAnimationActive={false} />
163
+ * </Recharts.LineChart>
164
+ * </Recharts.ResponsiveContainer>
165
+ * );
166
+ * }
167
+ * ```
168
+ *
169
+ * Keep in-cell Recharts configs minimal: no axes, no tooltips, no animation
170
+ * (`isAnimationActive={false}`), tight margins, fixed height. The goal is a
171
+ * visual summary, not an interactive chart.
172
+ *
173
+ * ## State shape (from `createDefaultDataGridState`)
174
+ *
175
+ * ```ts
176
+ * {
177
+ * sorting: [], // { columnId, direction: "asc" | "desc" }[]
178
+ * quickSearch: "", // search input text
179
+ * dateDisplay: "relative", // "relative" | "absolute"
180
+ * columnVisibility: {}, columnWidths: {...},
181
+ * columnPinning: { left: [], right: [] }, columnOrder: [...],
182
+ * pagination: { pageIndex: 0, pageSize: 50 },
183
+ * selection: { selectedIds: new Set(), anchorId: null },
184
+ * }
185
+ * ```
186
+ *
187
+ * Everything is updated through `setGridState` — the toolbar, header,
188
+ * and footer all call it for you. You do not need to wire any of this
189
+ * manually.
190
+ *
191
+ * ## Height and scrolling
192
+ *
193
+ * DataGrid is NOT a card. It has no border, rounded corners, or shadow of
194
+ * its own. Wrap it in whatever chrome you want — a `DesignCard`, a section,
195
+ * or just raw layout. The grid itself fills its parent's height via
196
+ * `h-full`.
197
+ *
198
+ * How the grid gets its height (pick ONE):
199
+ * 1. Bounded parent — put the grid inside a flex/grid container with a
200
+ * definite height (e.g. `flex-1 min-h-0` inside a page-filling flex
201
+ * column). The grid stretches to that height and scrolls its body.
202
+ * 2. `maxHeight` prop — pass a number (pixels) or CSS string
203
+ * (`"480px"`, `"60vh"`, `"100%"`). The grid caps at that size and
204
+ * scrolls its body.
205
+ * 3. Unbounded — omit `maxHeight` and let the parent grow freely. The
206
+ * grid renders at its full content height and the page scrolls. Fine
207
+ * for small lists; bad UX for thousands of rows.
208
+ *
209
+ * The toolbar, header, and footer are always `shrink-0`; only the body
210
+ * scrolls. You do NOT need to subtract toolbar/footer heights from
211
+ * `maxHeight` — the grid's internal flex layout handles that.
212
+ *
213
+ * ## When to use what
214
+ *
215
+ * - Simple static list, < 20 rows, no interaction → use a plain table component instead.
216
+ * - Interactive table, sortable + searchable, any size → `DataGrid` +
217
+ * `useDataSource` with `paginationMode: "client"`.
218
+ * - Infinite scroll over a huge dataset you fetch in pages → `dataSource` async
219
+ * generator + `paginationMode: "infinite"`. Only reach for this if you actually
220
+ * need pagination over a remote source. For anything that fits in memory,
221
+ * `"client"` is simpler and faster.
222
+ *
223
+ * ## Features you get for free
224
+ *
225
+ * Quick search, sortable columns (shift-click for multi-sort), column
226
+ * visibility toggle, column resize, CSV export, virtualized rendering
227
+ * for 10k+ rows, keyboard navigation, and a relative/absolute date
228
+ * toggle for `date` / `dateTime` columns.
229
+ */
230
+ declare function DataGrid<TRow>(props: DataGridProps<TRow>): react_jsx_runtime0.JSX.Element;
231
+ //#endregion
232
+ export { DataGrid };
233
+ //# sourceMappingURL=data-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-grid.d.ts","names":[],"sources":["../../../../src/components/data-grid/data-grid.tsx"],"mappings":";;;;;;;AA2wBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,QAAA,MAAA,CAAe,KAAA,EAAO,aAAA,CAAc,IAAA,IAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}