@stackframe/dashboard-ui-components 2.8.89 → 2.8.91

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 (67) hide show
  1. package/dist/components/button.d.ts +4 -4
  2. package/dist/components/data-grid/data-grid-sizing.d.ts +6 -5
  3. package/dist/components/data-grid/data-grid-sizing.d.ts.map +1 -1
  4. package/dist/components/data-grid/data-grid-sizing.js +9 -28
  5. package/dist/components/data-grid/data-grid-sizing.js.map +1 -1
  6. package/dist/components/data-grid/data-grid.d.ts +17 -237
  7. package/dist/components/data-grid/data-grid.d.ts.map +1 -1
  8. package/dist/components/data-grid/data-grid.js +377 -523
  9. package/dist/components/data-grid/data-grid.js.map +1 -1
  10. package/dist/components/data-grid/data-grid.test.js +82 -0
  11. package/dist/components/data-grid/data-grid.test.js.map +1 -1
  12. package/dist/components/data-grid/index.d.ts +4 -3
  13. package/dist/components/data-grid/index.js +17 -58
  14. package/dist/components/data-grid/state.d.ts +4 -61
  15. package/dist/components/data-grid/state.d.ts.map +1 -1
  16. package/dist/components/data-grid/state.js +13 -160
  17. package/dist/components/data-grid/state.js.map +1 -1
  18. package/dist/components/data-grid/types.d.ts +9 -4
  19. package/dist/components/data-grid/types.d.ts.map +1 -1
  20. package/dist/components/data-grid/use-url-state.d.ts +38 -0
  21. package/dist/components/data-grid/use-url-state.d.ts.map +1 -0
  22. package/dist/components/data-grid/use-url-state.js +214 -0
  23. package/dist/components/data-grid/use-url-state.js.map +1 -0
  24. package/dist/components/data-grid/use-url-state.test.d.ts +1 -0
  25. package/dist/components/data-grid/use-url-state.test.js +91 -0
  26. package/dist/components/data-grid/use-url-state.test.js.map +1 -0
  27. package/dist/components/dialog.d.ts +67 -0
  28. package/dist/components/dialog.d.ts.map +1 -0
  29. package/dist/components/dialog.js +94 -0
  30. package/dist/components/dialog.js.map +1 -0
  31. package/dist/dashboard-ui-components.global.js +10648 -6394
  32. package/dist/dashboard-ui-components.global.js.map +4 -4
  33. package/dist/esm/components/button.d.ts +4 -4
  34. package/dist/esm/components/data-grid/data-grid-sizing.d.ts +6 -5
  35. package/dist/esm/components/data-grid/data-grid-sizing.d.ts.map +1 -1
  36. package/dist/esm/components/data-grid/data-grid-sizing.js +7 -26
  37. package/dist/esm/components/data-grid/data-grid-sizing.js.map +1 -1
  38. package/dist/esm/components/data-grid/data-grid.d.ts +17 -237
  39. package/dist/esm/components/data-grid/data-grid.d.ts.map +1 -1
  40. package/dist/esm/components/data-grid/data-grid.js +380 -526
  41. package/dist/esm/components/data-grid/data-grid.js.map +1 -1
  42. package/dist/esm/components/data-grid/data-grid.test.js +82 -0
  43. package/dist/esm/components/data-grid/data-grid.test.js.map +1 -1
  44. package/dist/esm/components/data-grid/index.d.ts +4 -3
  45. package/dist/esm/components/data-grid/index.js +4 -3
  46. package/dist/esm/components/data-grid/state.d.ts +4 -61
  47. package/dist/esm/components/data-grid/state.d.ts.map +1 -1
  48. package/dist/esm/components/data-grid/state.js +15 -150
  49. package/dist/esm/components/data-grid/state.js.map +1 -1
  50. package/dist/esm/components/data-grid/types.d.ts +9 -4
  51. package/dist/esm/components/data-grid/types.d.ts.map +1 -1
  52. package/dist/esm/components/data-grid/use-url-state.d.ts +38 -0
  53. package/dist/esm/components/data-grid/use-url-state.d.ts.map +1 -0
  54. package/dist/esm/components/data-grid/use-url-state.js +212 -0
  55. package/dist/esm/components/data-grid/use-url-state.js.map +1 -0
  56. package/dist/esm/components/data-grid/use-url-state.test.d.ts +1 -0
  57. package/dist/esm/components/data-grid/use-url-state.test.js +91 -0
  58. package/dist/esm/components/data-grid/use-url-state.test.js.map +1 -0
  59. package/dist/esm/components/dialog.d.ts +67 -0
  60. package/dist/esm/components/dialog.d.ts.map +1 -0
  61. package/dist/esm/components/dialog.js +86 -0
  62. package/dist/esm/components/dialog.js.map +1 -0
  63. package/dist/esm/index.d.ts +2 -1
  64. package/dist/esm/index.js +2 -1
  65. package/dist/index.d.ts +5 -3
  66. package/dist/index.js +37 -0
  67. package/package.json +4 -3
@@ -4,8 +4,8 @@ import { VariantProps } from "class-variance-authority";
4
4
 
5
5
  //#region src/components/button.d.ts
6
6
  declare const designButtonVariants: (props?: ({
7
- variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "plain" | null | undefined;
8
- size?: "default" | "sm" | "lg" | "icon" | null | undefined;
7
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "plain" | null | undefined;
8
+ size?: "sm" | "lg" | "icon" | "default" | null | undefined;
9
9
  } & class_variance_authority_types0.ClassProp) | undefined) => string;
10
10
  type DesignOriginalButtonProps = {
11
11
  asChild?: boolean;
@@ -36,8 +36,8 @@ declare const DesignButton: React.FC<{
36
36
  } & {
37
37
  asChild?: boolean;
38
38
  } & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
39
- variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "plain" | null | undefined;
40
- size?: "default" | "sm" | "lg" | "icon" | null | undefined;
39
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "plain" | null | undefined;
40
+ size?: "sm" | "lg" | "icon" | "default" | null | undefined;
41
41
  } & class_variance_authority_types0.ClassProp) | undefined) => string> & {
42
42
  ref?: React.Ref<HTMLButtonElement> | undefined;
43
43
  }>;
@@ -1,12 +1,13 @@
1
1
  import { DataGridColumnDef } from "./types.js";
2
- import { CSSProperties } from "react";
3
2
 
4
3
  //#region src/components/data-grid/data-grid-sizing.d.ts
4
+ declare const DEFAULT_MAX_COL_WIDTH = 800;
5
+ declare const DEFAULT_COL_WIDTH = 150;
6
+ /** Effective minimum column width. When `col.minWidth` is unset, derive
7
+ * one from the header label so it never gets clipped during resize. */
5
8
  declare function getEffectiveMinWidth<TRow>(col: DataGridColumnDef<TRow>): number;
6
- declare function getColumnSizingStyle<TRow>(col: DataGridColumnDef<TRow>): CSSProperties;
7
- declare function createGridSizingStyle(widths: ReadonlyMap<string, number>, totalWidth: number): Record<string, string>;
8
- declare function applyDraggedColumnWidth(el: HTMLElement, columnId: string, width: number, totalWidth: number): void;
9
+ declare function getEffectiveMaxWidth<TRow>(col: DataGridColumnDef<TRow>): number;
9
10
  declare function clampColumnWidth<TRow>(col: DataGridColumnDef<TRow>, width: number): number;
10
11
  //#endregion
11
- export { applyDraggedColumnWidth, clampColumnWidth, createGridSizingStyle, getColumnSizingStyle, getEffectiveMinWidth };
12
+ export { DEFAULT_COL_WIDTH, DEFAULT_MAX_COL_WIDTH, clampColumnWidth, getEffectiveMaxWidth, getEffectiveMinWidth };
12
13
  //# sourceMappingURL=data-grid-sizing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-grid-sizing.d.ts","names":[],"sources":["../../../src/components/data-grid/data-grid-sizing.ts"],"mappings":";;;;iBAgEgB,oBAAA,MAAA,CAA2B,GAAA,EAAK,iBAAA,CAAkB,IAAA;AAAA,iBAWlD,oBAAA,MAAA,CAA2B,GAAA,EAAK,iBAAA,CAAkB,IAAA,IAAQ,aAAA;AAAA,iBAW1D,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"}
1
+ {"version":3,"file":"data-grid-sizing.d.ts","names":[],"sources":["../../../src/components/data-grid/data-grid-sizing.ts"],"mappings":";;;cAIa,qBAAA;AAAA,cACA,iBAAA;AADb;;AAAA,iBA+BgB,oBAAA,MAAA,CAA2B,GAAA,EAAK,iBAAA,CAAkB,IAAA;AAAA,iBASlD,oBAAA,MAAA,CAA2B,GAAA,EAAK,iBAAA,CAAkB,IAAA;AAAA,iBAIlD,gBAAA,MAAA,CAAuB,GAAA,EAAK,iBAAA,CAAkB,IAAA,GAAO,KAAA"}
@@ -1,13 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  //#region src/components/data-grid/data-grid-sizing.ts
4
- function colVar(id) {
5
- if (process.env.NODE_ENV !== "production" && !/^[A-Za-z_][A-Za-z0-9_-]*$/.test(id)) console.warn(`[DataGrid] column id ${JSON.stringify(id)} contains characters that are not safe in a CSS custom property name. Prefer ascii identifiers.`);
6
- return `--col-${id}`;
7
- }
8
4
  const MIN_COL_WIDTH = 20;
9
5
  const MIN_CUSTOM_HEADER_WIDTH = 50;
10
6
  const DEFAULT_MAX_COL_WIDTH = 800;
7
+ const DEFAULT_COL_WIDTH = 150;
11
8
  const HEADER_CHROME_PX = 44;
12
9
  let measureContext = null;
13
10
  const headerWidthCache = /* @__PURE__ */ new Map();
@@ -23,41 +20,25 @@ function measureHeaderLabelWidth(label) {
23
20
  headerWidthCache.set(label, width);
24
21
  return width;
25
22
  }
23
+ /** Effective minimum column width. When `col.minWidth` is unset, derive
24
+ * one from the header label so it never gets clipped during resize. */
26
25
  function getEffectiveMinWidth(col) {
27
26
  if (col.minWidth != null) return col.minWidth;
28
27
  const label = typeof col.header === "string" ? col.header : null;
29
28
  if (label == null) return typeof col.header === "function" ? MIN_CUSTOM_HEADER_WIDTH : MIN_COL_WIDTH;
30
29
  return Math.max(MIN_COL_WIDTH, measureHeaderLabelWidth(label) + HEADER_CHROME_PX);
31
30
  }
32
- function getColumnSizingStyle(col) {
33
- const w = `var(${colVar(col.id)})`;
34
- const grow = col.flex ?? 0;
35
- return {
36
- flex: `${grow} 0 ${w}`,
37
- width: w,
38
- minWidth: getEffectiveMinWidth(col),
39
- maxWidth: grow > 0 ? void 0 : col.maxWidth ?? DEFAULT_MAX_COL_WIDTH
40
- };
41
- }
42
- function createGridSizingStyle(widths, totalWidth) {
43
- const style = { "--grid-total-w": `${totalWidth}px` };
44
- for (const [id, w] of widths) style[colVar(id)] = `${w}px`;
45
- return style;
46
- }
47
- function applyDraggedColumnWidth(el, columnId, width, totalWidth) {
48
- el.style.setProperty(colVar(columnId), `${width}px`);
49
- el.style.setProperty("--grid-total-w", `${totalWidth}px`);
31
+ function getEffectiveMaxWidth(col) {
32
+ return col.maxWidth ?? DEFAULT_MAX_COL_WIDTH;
50
33
  }
51
34
  function clampColumnWidth(col, width) {
52
- const minWidth = getEffectiveMinWidth(col);
53
- const maxWidth = col.maxWidth ?? DEFAULT_MAX_COL_WIDTH;
54
- return Math.max(minWidth, Math.min(maxWidth, width));
35
+ return Math.max(getEffectiveMinWidth(col), Math.min(getEffectiveMaxWidth(col), width));
55
36
  }
56
37
 
57
38
  //#endregion
58
- exports.applyDraggedColumnWidth = applyDraggedColumnWidth;
39
+ exports.DEFAULT_COL_WIDTH = DEFAULT_COL_WIDTH;
40
+ exports.DEFAULT_MAX_COL_WIDTH = DEFAULT_MAX_COL_WIDTH;
59
41
  exports.clampColumnWidth = clampColumnWidth;
60
- exports.createGridSizingStyle = createGridSizingStyle;
61
- exports.getColumnSizingStyle = getColumnSizingStyle;
42
+ exports.getEffectiveMaxWidth = getEffectiveMaxWidth;
62
43
  exports.getEffectiveMinWidth = getEffectiveMinWidth;
63
44
  //# sourceMappingURL=data-grid-sizing.js.map
@@ -1 +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 // Column ids flow into CSS custom-property names. Non-ident chars would\n // break the cascade silently, so fail loud in dev. Consumers should stick\n // to stable ascii-ident ids for every column.\n if (process.env.NODE_ENV !== \"production\" && !/^[A-Za-z_][A-Za-z0-9_-]*$/.test(id)) {\n // eslint-disable-next-line no-console\n console.warn(\n `[DataGrid] column id ${JSON.stringify(id)} contains characters that are not safe in a CSS custom property name. Prefer ascii identifiers.`\n );\n }\n return `--col-${id}`;\n}\n\n// When col.minWidth is not set, the effective minimum is derived from\n// the header label text width so the label is never clipped on resize.\n// Uses an offscreen canvas for zero-layout measurement; results are\n// cached per unique label string.\n\nconst MIN_COL_WIDTH = 20;\nconst MIN_CUSTOM_HEADER_WIDTH = 50;\n// Default upper bound on column width (both initial sizing + resize clamp).\n// Kept generous because consumers can override per-column via `col.maxWidth`.\nconst DEFAULT_MAX_COL_WIDTH = 800;\n// px-3 both sides + gap-1.5 + sort icon (h-3 w-3) + 2px rounding buffer\nconst HEADER_CHROME_PX = 12 + 12 + 6 + 12 + 2;\n\nlet measureContext: CanvasRenderingContext2D | null = null;\nconst headerWidthCache = new Map<string, number>();\n\nfunction measureHeaderLabelWidth(label: string): number {\n const cached = headerWidthCache.get(label);\n if (cached != null) {\n return cached;\n }\n\n if (typeof document === \"undefined\") {\n return 0;\n }\n if (measureContext == null) {\n measureContext = document.createElement(\"canvas\").getContext(\"2d\");\n }\n if (measureContext == null) {\n return 0;\n }\n\n // Match header cell: text-xs (12px) font-semibold (600) uppercase tracking-wider (0.05em)\n measureContext.font = \"600 12px system-ui, -apple-system, sans-serif\";\n const text = label.toUpperCase();\n const letterSpacingPx = 0.05 * 12;\n const width = Math.ceil(\n measureContext.measureText(text).width + letterSpacingPx * text.length,\n );\n\n headerWidthCache.set(label, width);\n return width;\n}\n\nexport function getEffectiveMinWidth<TRow>(col: DataGridColumnDef<TRow>): number {\n if (col.minWidth != null) {\n return col.minWidth;\n }\n const label = typeof col.header === \"string\" ? col.header : null;\n if (label == null) {\n return typeof col.header === \"function\" ? MIN_CUSTOM_HEADER_WIDTH : MIN_COL_WIDTH;\n }\n return Math.max(MIN_COL_WIDTH, measureHeaderLabelWidth(label) + HEADER_CHROME_PX);\n}\n\nexport function getColumnSizingStyle<TRow>(col: DataGridColumnDef<TRow>): CSSProperties {\n const w = `var(${colVar(col.id)})`;\n const grow = col.flex ?? 0;\n return {\n flex: `${grow} 0 ${w}`,\n width: w,\n minWidth: getEffectiveMinWidth(col),\n maxWidth: grow > 0 ? undefined : (col.maxWidth ?? DEFAULT_MAX_COL_WIDTH),\n };\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 const minWidth = getEffectiveMinWidth(col);\n const maxWidth = col.maxWidth ?? DEFAULT_MAX_COL_WIDTH;\n return Math.max(minWidth, Math.min(maxWidth, width));\n}\n"],"mappings":";;;AAOA,SAAS,OAAO,IAA+B;AAI7C,KAAI,QAAQ,IAAI,aAAa,gBAAgB,CAAC,4BAA4B,KAAK,GAAG,CAEhF,SAAQ,KACN,wBAAwB,KAAK,UAAU,GAAG,CAAC,iGAC5C;AAEH,QAAO,SAAS;;AAQlB,MAAM,gBAAgB;AACtB,MAAM,0BAA0B;AAGhC,MAAM,wBAAwB;AAE9B,MAAM,mBAAmB;AAEzB,IAAI,iBAAkD;AACtD,MAAM,mCAAmB,IAAI,KAAqB;AAElD,SAAS,wBAAwB,OAAuB;CACtD,MAAM,SAAS,iBAAiB,IAAI,MAAM;AAC1C,KAAI,UAAU,KACZ,QAAO;AAGT,KAAI,OAAO,aAAa,YACtB,QAAO;AAET,KAAI,kBAAkB,KACpB,kBAAiB,SAAS,cAAc,SAAS,CAAC,WAAW,KAAK;AAEpE,KAAI,kBAAkB,KACpB,QAAO;AAIT,gBAAe,OAAO;CACtB,MAAM,OAAO,MAAM,aAAa;CAEhC,MAAM,QAAQ,KAAK,KACjB,eAAe,YAAY,KAAK,CAAC,QAFX,MAAO,KAE8B,KAAK,OACjE;AAED,kBAAiB,IAAI,OAAO,MAAM;AAClC,QAAO;;AAGT,SAAgB,qBAA2B,KAAsC;AAC/E,KAAI,IAAI,YAAY,KAClB,QAAO,IAAI;CAEb,MAAM,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC5D,KAAI,SAAS,KACX,QAAO,OAAO,IAAI,WAAW,aAAa,0BAA0B;AAEtE,QAAO,KAAK,IAAI,eAAe,wBAAwB,MAAM,GAAG,iBAAiB;;AAGnF,SAAgB,qBAA2B,KAA6C;CACtF,MAAM,IAAI,OAAO,OAAO,IAAI,GAAG,CAAC;CAChC,MAAM,OAAO,IAAI,QAAQ;AACzB,QAAO;EACL,MAAM,GAAG,KAAK,KAAK;EACnB,OAAO;EACP,UAAU,qBAAqB,IAAI;EACnC,UAAU,OAAO,IAAI,SAAa,IAAI,YAAY;EACnD;;AAGH,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;CAC1F,MAAM,WAAW,qBAAqB,IAAI;CAC1C,MAAM,WAAW,IAAI,YAAY;AACjC,QAAO,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,MAAM,CAAC"}
1
+ {"version":3,"file":"data-grid-sizing.js","names":[],"sources":["../../../src/components/data-grid/data-grid-sizing.ts"],"sourcesContent":["import type { DataGridColumnDef } from \"./types\";\n\nconst MIN_COL_WIDTH = 20;\nconst MIN_CUSTOM_HEADER_WIDTH = 50;\nexport const DEFAULT_MAX_COL_WIDTH = 800;\nexport const DEFAULT_COL_WIDTH = 150;\n\n// px-3 both sides + gap-1.5 + sort icon (h-3 w-3) + 2px rounding buffer\nconst HEADER_CHROME_PX = 12 + 12 + 6 + 12 + 2;\n\nlet measureContext: CanvasRenderingContext2D | null = null;\nconst headerWidthCache = new Map<string, number>();\n\nfunction measureHeaderLabelWidth(label: string): number {\n const cached = headerWidthCache.get(label);\n if (cached != null) return cached;\n if (typeof document === \"undefined\") return 0;\n if (measureContext == null) {\n measureContext = document.createElement(\"canvas\").getContext(\"2d\");\n }\n if (measureContext == null) return 0;\n\n // Match header cell: text-xs (12px) font-semibold uppercase tracking-wider (0.05em)\n measureContext.font = \"600 12px system-ui, -apple-system, sans-serif\";\n const text = label.toUpperCase();\n const letterSpacingPx = 0.05 * 12;\n const width = Math.ceil(\n measureContext.measureText(text).width + letterSpacingPx * text.length,\n );\n headerWidthCache.set(label, width);\n return width;\n}\n\n/** Effective minimum column width. When `col.minWidth` is unset, derive\n * one from the header label so it never gets clipped during resize. */\nexport function getEffectiveMinWidth<TRow>(col: DataGridColumnDef<TRow>): number {\n if (col.minWidth != null) return col.minWidth;\n const label = typeof col.header === \"string\" ? col.header : null;\n if (label == null) {\n return typeof col.header === \"function\" ? MIN_CUSTOM_HEADER_WIDTH : MIN_COL_WIDTH;\n }\n return Math.max(MIN_COL_WIDTH, measureHeaderLabelWidth(label) + HEADER_CHROME_PX);\n}\n\nexport function getEffectiveMaxWidth<TRow>(col: DataGridColumnDef<TRow>): number {\n return col.maxWidth ?? DEFAULT_MAX_COL_WIDTH;\n}\n\nexport function clampColumnWidth<TRow>(col: DataGridColumnDef<TRow>, width: number): number {\n return Math.max(getEffectiveMinWidth(col), Math.min(getEffectiveMaxWidth(col), width));\n}\n"],"mappings":";;;AAEA,MAAM,gBAAgB;AACtB,MAAM,0BAA0B;AAChC,MAAa,wBAAwB;AACrC,MAAa,oBAAoB;AAGjC,MAAM,mBAAmB;AAEzB,IAAI,iBAAkD;AACtD,MAAM,mCAAmB,IAAI,KAAqB;AAElD,SAAS,wBAAwB,OAAuB;CACtD,MAAM,SAAS,iBAAiB,IAAI,MAAM;AAC1C,KAAI,UAAU,KAAM,QAAO;AAC3B,KAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,KAAI,kBAAkB,KACpB,kBAAiB,SAAS,cAAc,SAAS,CAAC,WAAW,KAAK;AAEpE,KAAI,kBAAkB,KAAM,QAAO;AAGnC,gBAAe,OAAO;CACtB,MAAM,OAAO,MAAM,aAAa;CAEhC,MAAM,QAAQ,KAAK,KACjB,eAAe,YAAY,KAAK,CAAC,QAFX,MAAO,KAE8B,KAAK,OACjE;AACD,kBAAiB,IAAI,OAAO,MAAM;AAClC,QAAO;;;;AAKT,SAAgB,qBAA2B,KAAsC;AAC/E,KAAI,IAAI,YAAY,KAAM,QAAO,IAAI;CACrC,MAAM,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAC5D,KAAI,SAAS,KACX,QAAO,OAAO,IAAI,WAAW,aAAa,0BAA0B;AAEtE,QAAO,KAAK,IAAI,eAAe,wBAAwB,MAAM,GAAG,iBAAiB;;AAGnF,SAAgB,qBAA2B,KAAsC;AAC/E,QAAO,IAAI,YAAY;;AAGzB,SAAgB,iBAAuB,KAA8B,OAAuB;AAC1F,QAAO,KAAK,IAAI,qBAAqB,IAAI,EAAE,KAAK,IAAI,qBAAqB,IAAI,EAAE,MAAM,CAAC"}
@@ -4,262 +4,42 @@ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
  //#region src/components/data-grid/data-grid.d.ts
5
5
  declare function isDataGridInteractiveRowClickTarget(target: EventTarget | null): boolean;
6
6
  /**
7
- * Interactive table with sorting, quick search, pagination, selection,
8
- * and virtualization. Handles 10k+ rows smoothly. Pair with
9
- * `useDataSource` for client-side data; use an async `dataSource`
10
- * generator for server or infinite-scroll modes.
7
+ * Interactive table built on TanStack Table v8. Sorting, column sizing,
8
+ * visibility, ordering, and pinning are owned by the table instance; we
9
+ * layer virtualization, sticky toolbar/header/footer, infinite scroll,
10
+ * quick search, CSV export, and date-format toggling on top.
11
11
  *
12
- * ## Mental model (read this first everything else depends on it)
13
- *
14
- * DataGrid is a **display** component. It does NOT sort, search, or
15
- * paginate your data directly — you own that, but `useDataSource` does
16
- * it for you. The `rows` prop is always the already-processed slice to
17
- * show. The grid tracks user intent in `state` (sort model, quick
18
- * search text, page index). You feed that state into `useDataSource`,
19
- * and its output goes back in as `rows`.
20
- *
21
- * `useDataSource` IS the processor. Given your full dataset and the
22
- * grid's state, it returns the searched + sorted + paginated rows
23
- * ready to pass to DataGrid. This is the ONLY correct pattern for
24
- * client-side data — do NOT pass a raw array to `rows`.
25
- *
26
- * ## Search (client vs async)
27
- *
28
- * - **Client mode** (`useDataSource` with `data`): a case-insensitive
29
- * substring match across every column is applied automatically.
30
- * Override the matcher with `matchRow` for fuzzy / weighted search,
31
- * or disable by passing `matchRow: () => true`.
32
- * - **Async mode** (`useDataSource` with `dataSource`): `state.quickSearch`
33
- * is forwarded to the generator as `params.quickSearch`. Same
34
- * mechanism as `params.sorting` — a change triggers a refetch, and
35
- * the generator is the "matching logic" (typically a WHERE / ILIKE
36
- * clause in the backend query). The grid does NO client-side
37
- * filtering in async mode.
38
- *
39
- * ## The canonical pattern
12
+ * The grid is display-only it does not fetch or page data itself. Pair
13
+ * with `useDataSource` for client- or server-side data and pass the
14
+ * already-processed slice through `rows`.
40
15
  *
41
16
  * ```tsx
42
- * // 1. Columns — define OUTSIDE the component or inside a useMemo. Must be stable.
43
- * const columns = React.useMemo(() => [
44
- * { id: "name", header: "Name", accessor: "name", width: 180, type: "string" },
45
- * { id: "email", header: "Email", accessor: "email", width: 240, type: "string" },
46
- * { id: "role", header: "Role", accessor: "role", width: 120, type: "singleSelect",
47
- * valueOptions: [{ value: "admin", label: "Admin" }, { value: "member", label: "Member" }] },
48
- * { id: "signUps", header: "Sign-ups", accessor: "signUps", width: 120, type: "number", align: "right",
49
- * renderCell: ({ value }) => <span className="tabular-nums">{Number(value).toLocaleString()}</span> },
50
- * ], []);
51
- *
52
- * // 2. Grid state — one hook, initialized from the columns. NEVER build the state object by hand.
53
- * const [gridState, setGridState] = React.useState(() => createDefaultDataGridState(columns));
54
- *
55
- * // 3. Data source — wires your raw array through the grid state. ALWAYS call this
56
- * // hook unconditionally at the top level (no if/return before it).
17
+ * const columns = useMemo(() => [...], []);
18
+ * const [gridState, setGridState] = useState(() => createDefaultDataGridState(columns));
57
19
  * const gridData = useDataSource({
58
- * data: users, // your raw array (can be [] while loading)
59
- * columns,
60
- * getRowId: (row) => row.id,
20
+ * data: users, columns, getRowId: (r) => r.id,
61
21
  * sorting: gridState.sorting,
62
22
  * quickSearch: gridState.quickSearch,
63
23
  * pagination: gridState.pagination,
64
- * paginationMode: "client", // "client" | "server" | "infinite"
24
+ * paginationMode: "client",
65
25
  * });
66
26
  *
67
- * // 4. Render — `rows` comes from gridData.rows, NOT from your raw array.
68
27
  * <DataGrid
69
28
  * columns={columns}
70
29
  * rows={gridData.rows}
71
- * getRowId={(row) => row.id}
30
+ * getRowId={(r) => r.id}
72
31
  * totalRowCount={gridData.totalRowCount}
73
32
  * isLoading={gridData.isLoading}
74
33
  * state={gridState}
75
34
  * onChange={setGridState}
76
- * selectionMode="none" // "none" | "single" | "multiple"
77
- * maxHeight={480}
78
35
  * />
79
36
  * ```
80
37
  *
81
- * ## Iron rules (violating any of these breaks the grid)
82
- *
83
- * 1. The prop is `rows`, NOT `data`. There is no `data` prop on DataGrid.
84
- * `data` belongs on `useDataSource`.
85
- * 2. `rows` is ALWAYS `gridData.rows`. Never pass your raw array to
86
- * `rows` — the grid won't search, sort, or paginate it.
87
- * 3. Columns must be stable across renders. Define them outside the
88
- * component or wrap in `React.useMemo`. A fresh columns array every
89
- * render will reset sorting state.
90
- * 4. Initialize grid state with `createDefaultDataGridState(columns)`.
91
- * Do NOT spell out the state object manually — you will miss fields
92
- * and crash.
93
- * 5. `onChange` takes a `SetStateAction` (the setter you got from
94
- * `useState`). Pass `setGridState` directly. Do NOT wrap it unless
95
- * you know exactly what you're doing.
96
- * 6. Call `useDataSource` ONCE per grid, at the top level, before any
97
- * early return. It contains hooks.
98
- * 7. `renderCell` is a PURE function of its context. NEVER call React
99
- * hooks inside it (no `useState`, `useMemo`, `useEffect`, nothing).
100
- * If you need derived data per row, compute it BEFORE the render —
101
- * e.g. build a `Map<rowId, sparklineData>` in a `useMemo` and look
102
- * it up in `renderCell`.
103
- * 8. `toolbar` accepts `false` (hide it) or a render function
104
- * `(ctx) => ReactNode`. Anything else — `true`, `undefined`, a state
105
- * variable — will either show the default toolbar or crash. If you
106
- * just want the default toolbar, omit the prop entirely.
107
- * 9. The toolbar's search input writes to `state.quickSearch`. That
108
- * value is consumed by `useDataSource` — client mode filters
109
- * client-side, async mode forwards to the generator. Do NOT wire
110
- * a separate "controlled" search prop, everything flows through
111
- * grid state.
112
- *
113
- * ## renderCell — what you can and cannot do inside it
114
- *
115
- * ```tsx
116
- * // OK — pure rendering from ctx:
117
- * renderCell: ({ value }) => <span className="tabular-nums">{Number(value).toLocaleString()}</span>
118
- * renderCell: ({ row }) => <Badge variant={row.active ? "default" : "outline"}>{row.status}</Badge>
119
- *
120
- * // OK — looking up pre-computed data by row id:
121
- * // BEFORE the return, in the component body:
122
- * const sparklinesById = React.useMemo(() => {
123
- * const m = new Map();
124
- * for (const u of users) {
125
- * m.set(u.id, u.recentActivity.map((n, i) => ({ ts: i, values: { primary: n } })));
126
- * }
127
- * return m;
128
- * }, [users]);
129
- * // Then inside the column def:
130
- * renderCell: ({ rowId }) => <MiniSparkline data={sparklinesById.get(rowId) ?? []} />
131
- *
132
- * // NOT OK — hooks inside renderCell:
133
- * renderCell: ({ row }) => {
134
- * const [hovered, setHovered] = React.useState(false); // ← crashes the grid
135
- * const data = React.useMemo(() => ..., []); // ← crashes the grid
136
- * return ...;
137
- * }
138
- *
139
- * // NOT OK — embedding AnalyticsChart (or any other controlled, stateful chart) per row:
140
- * // AnalyticsChart owns its own state, tooltips, zoom, and virtualized data
141
- * // pipeline. Instantiating one per row is expensive and fights the grid's
142
- * // virtualizer. Don't do it.
143
- * ```
144
- *
145
- * ## Sparklines and mini-charts in cells — use raw Recharts
146
- *
147
- * If you want a tiny chart (sparkline, micro bar chart, trend line) inside
148
- * a cell, drop down to raw `Recharts.*` components — they are lightweight
149
- * and stateless, so they render cleanly per row without owning any state.
150
- * Read pre-computed points off the row (or off a `Map<rowId, points>` you
151
- * built in a `useMemo` above) and pass them directly to the Recharts
152
- * primitive. Do NOT wrap them in `DesignChartContainer` or
153
- * `DesignChartCard` inside a cell — those add chrome meant for full-size
154
- * charts.
155
- *
156
- * ```tsx
157
- * // OK — raw Recharts sparkline per row:
158
- * renderCell: ({ rowId }) => {
159
- * const points = sparklinesById.get(rowId) ?? [];
160
- * return (
161
- * <Recharts.ResponsiveContainer width="100%" height={28}>
162
- * <Recharts.LineChart data={points} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>
163
- * <Recharts.Line type="monotone" dataKey="v" stroke="currentColor" strokeWidth={1.5} dot={false} isAnimationActive={false} />
164
- * </Recharts.LineChart>
165
- * </Recharts.ResponsiveContainer>
166
- * );
167
- * }
168
- * ```
169
- *
170
- * Keep in-cell Recharts configs minimal: no axes, no tooltips, no animation
171
- * (`isAnimationActive={false}`), tight margins, fixed height. The goal is a
172
- * visual summary, not an interactive chart.
173
- *
174
- * ## State shape (from `createDefaultDataGridState`)
175
- *
176
- * ```ts
177
- * {
178
- * sorting: [], // { columnId, direction: "asc" | "desc" }[]
179
- * quickSearch: "", // search input text
180
- * dateDisplay: "relative", // "relative" | "absolute"
181
- * columnVisibility: {}, columnWidths: {...},
182
- * columnPinning: { left: [], right: [] }, columnOrder: [...],
183
- * pagination: { pageIndex: 0, pageSize: 50 },
184
- * selection: { selectedIds: new Set(), anchorId: null },
185
- * }
186
- * ```
187
- *
188
- * Everything is updated through `setGridState` — the toolbar, header,
189
- * and footer all call it for you. You do not need to wire any of this
190
- * manually.
191
- *
192
- * ## Cell overflow and dynamic row heights
193
- *
194
- * By default every cell truncates its content with an ellipsis
195
- * (`cellOverflow: "truncate"`). For columns whose content should wrap
196
- * — badge lists, multi-line text, permission chips — set
197
- * `cellOverflow: "wrap"` on the column definition.
198
- *
199
- * To let rows grow to fit their tallest cell, set `rowHeight="auto"`
200
- * on the grid. The virtualizer will measure each row after render and
201
- * adjust scroll positions accordingly. Pair with `estimatedRowHeight`
202
- * (default 44) for better scroll-position estimates before measurement.
203
- *
204
- * ```tsx
205
- * // Columns: UUIDs truncate, auth-method badges wrap
206
- * const columns = [
207
- * { id: "userId", header: "User ID", width: 130 }, // default truncate
208
- * { id: "auth", header: "Auth methods", width: 150, cellOverflow: "wrap",
209
- * renderCell: ({ row }) => (
210
- * <div className="flex flex-wrap gap-1">
211
- * {row.authTypes.map((t) => <Badge key={t}>{t}</Badge>)}
212
- * </div>
213
- * ),
214
- * },
215
- * ];
216
- *
217
- * <DataGrid columns={columns} rowHeight="auto" estimatedRowHeight={48} ... />
218
- * ```
219
- *
220
- * With a fixed numeric `rowHeight` (the default), `cellOverflow: "wrap"`
221
- * still lets content wrap within the row, but anything exceeding the
222
- * fixed height is clipped. This is useful when you want controlled
223
- * wrapping without variable row heights.
224
- *
225
- * ## Height and scrolling
226
- *
227
- * DataGrid is NOT a card. It has no border, rounded corners, or shadow of
228
- * its own. Wrap it in whatever chrome you want — a `DesignCard`, a section,
229
- * or just raw layout. The grid itself fills its parent's height via
230
- * `h-full`.
231
- *
232
- * How the grid gets its height (pick ONE):
233
- * 1. Bounded parent — put the grid inside a flex/grid container with a
234
- * definite height (e.g. `flex-1 min-h-0` inside a page-filling flex
235
- * column). The grid stretches to that height and scrolls its body.
236
- * 2. `maxHeight` prop — pass a number (pixels) or CSS string
237
- * (`"480px"`, `"60vh"`, `"100%"`). The grid caps at that size and
238
- * scrolls its body.
239
- * 3. Unbounded — omit `maxHeight` and let the parent grow freely. The
240
- * grid renders at its full content height and the page scrolls. Fine
241
- * for small lists; bad UX for thousands of rows.
242
- *
243
- * The toolbar, header, and footer are always `shrink-0`; only the body
244
- * scrolls. You do NOT need to subtract toolbar/footer heights from
245
- * `maxHeight` — the grid's internal flex layout handles that.
246
- *
247
- * ## When to use what
248
- *
249
- * - Simple static list, < 20 rows, no interaction → use a plain table component instead.
250
- * - Interactive table, sortable + searchable, any size → `DataGrid` +
251
- * `useDataSource` with `paginationMode: "client"`.
252
- * - Infinite scroll over a huge dataset you fetch in pages → `dataSource` async
253
- * generator + `paginationMode: "infinite"`. Only reach for this if you actually
254
- * need pagination over a remote source. For anything that fits in memory,
255
- * `"client"` is simpler and faster.
256
- *
257
- * ## Features you get for free
258
- *
259
- * Quick search, sortable columns (shift-click for multi-sort), column
260
- * visibility toggle, column resize, CSV export, virtualized rendering
261
- * for 10k+ rows, keyboard navigation, and a relative/absolute date
262
- * toggle for `date` / `dateTime` columns.
38
+ * Iron rules:
39
+ * - `rows` is always `gridData.rows`, never your raw array.
40
+ * - Columns must be stable (define outside the component or wrap in `useMemo`).
41
+ * - Initialize state with `createDefaultDataGridState(columns)`.
42
+ * - `renderCell` must be a pure function no React hooks inside.
263
43
  */
264
44
  declare function DataGrid<TRow>(props: DataGridProps<TRow>): react_jsx_runtime0.JSX.Element;
265
45
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"data-grid.d.ts","names":[],"sources":["../../../src/components/data-grid/data-grid.tsx"],"mappings":";;;;iBAsKgB,mCAAA,CAAoC,MAAA,EAAQ,WAAA;;;AAA5D;;;;;AA+sBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,QAAA,MAAA,CAAe,KAAA,EAAO,aAAA,CAAc,IAAA,IAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"data-grid.d.ts","names":[],"sources":["../../../src/components/data-grid/data-grid.tsx"],"mappings":";;;;iBAmEgB,mCAAA,CAAoC,MAAA,EAAQ,WAAA;;;AAA5D;;;;;AAohBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,QAAA,MAAA,CAAe,KAAA,EAAO,aAAA,CAAc,IAAA,IAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}