@stackframe/dashboard-ui-components 2.8.88 → 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 +10649 -6395
  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
@@ -0,0 +1,212 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { createDefaultDataGridState } from "./state.js";
5
+ import { DEFAULT_COL_WIDTH, clampColumnWidth } from "./data-grid-sizing.js";
6
+
7
+ //#region src/components/data-grid/use-url-state.ts
8
+ function serializeWidths(widths, columns) {
9
+ const parts = [];
10
+ for (const col of columns) {
11
+ const w = widths[col.id];
12
+ if (typeof w !== "number" || !Number.isFinite(w)) continue;
13
+ const defaultW = clampColumnWidth(col, col.width ?? DEFAULT_COL_WIDTH);
14
+ if (Math.round(w) === Math.round(defaultW)) continue;
15
+ parts.push(`${encodeURIComponent(col.id)}:${Math.round(w)}`);
16
+ }
17
+ return parts.join(",");
18
+ }
19
+ function parseWidths(raw, fallback, columns) {
20
+ if (!raw) return fallback;
21
+ const colMap = new Map(columns.map((c) => [c.id, c]));
22
+ const out = { ...fallback };
23
+ for (const part of raw.split(",")) {
24
+ const colonIdx = part.indexOf(":");
25
+ if (colonIdx <= 0) continue;
26
+ const encodedId = part.slice(0, colonIdx);
27
+ const num = part.slice(colonIdx + 1);
28
+ let id;
29
+ try {
30
+ id = decodeURIComponent(encodedId);
31
+ } catch {
32
+ continue;
33
+ }
34
+ if (!id || !num) continue;
35
+ const col = colMap.get(id);
36
+ if (!col) continue;
37
+ const n = Number(num);
38
+ if (!Number.isFinite(n)) continue;
39
+ out[id] = clampColumnWidth(col, n);
40
+ }
41
+ return out;
42
+ }
43
+ function serializeHidden(visibility) {
44
+ return Object.entries(visibility).filter(([, v]) => v === false).map(([id]) => encodeURIComponent(id)).join(",");
45
+ }
46
+ function parseHidden(raw, columns) {
47
+ if (!raw) return {};
48
+ const known = new Set(columns.map((c) => c.id));
49
+ const out = {};
50
+ for (const encodedId of raw.split(",")) {
51
+ let id;
52
+ try {
53
+ id = decodeURIComponent(encodedId);
54
+ } catch {
55
+ continue;
56
+ }
57
+ if (id && known.has(id)) out[id] = false;
58
+ }
59
+ return out;
60
+ }
61
+ function serializeSort(sort) {
62
+ return sort.map((s) => `${encodeURIComponent(s.columnId)}:${s.direction === "desc" ? "desc" : "asc"}`).join(",");
63
+ }
64
+ function sortEqual(a, b) {
65
+ if (a.length !== b.length) return false;
66
+ for (let i = 0; i < a.length; i++) if (a[i].columnId !== b[i].columnId || a[i].direction !== b[i].direction) return false;
67
+ return true;
68
+ }
69
+ function parseSort(raw, fallback, columns) {
70
+ if (raw == null) return fallback;
71
+ if (raw === "") return [];
72
+ const known = new Set(columns.map((c) => c.id));
73
+ const out = [];
74
+ for (const part of raw.split(",")) {
75
+ const colonIdx = part.indexOf(":");
76
+ if (colonIdx <= 0) continue;
77
+ const encodedId = part.slice(0, colonIdx);
78
+ const dir = part.slice(colonIdx + 1);
79
+ if (dir !== "asc" && dir !== "desc") continue;
80
+ let id;
81
+ try {
82
+ id = decodeURIComponent(encodedId);
83
+ } catch {
84
+ continue;
85
+ }
86
+ if (!id || !known.has(id)) continue;
87
+ out.push({
88
+ columnId: id,
89
+ direction: dir
90
+ });
91
+ }
92
+ return out;
93
+ }
94
+ function parseQuickSearch(raw, fallback) {
95
+ if (raw == null) return fallback;
96
+ return raw;
97
+ }
98
+ /**
99
+ * Drop-in replacement for `useState(() => createDefaultDataGridState(columns))`
100
+ * that persists user view preferences to URL search params, so a view
101
+ * can be bookmarked / shared / restored on reload.
102
+ *
103
+ * **Persisted:** column widths, hidden columns, sort model, quick-search.
104
+ * **Not persisted** (deliberately): pagination scroll position, selection,
105
+ * column pinning/order, date display mode — these are session-scoped.
106
+ *
107
+ * ```tsx
108
+ * const [gridState, setGridState] = useDataGridUrlState(columns, {
109
+ * paramPrefix: "users",
110
+ * initial: { sorting: [{ columnId: "signedUpAt", direction: "desc" }] },
111
+ * });
112
+ * ```
113
+ *
114
+ * URL encoding: `?{prefix}_w=...&{prefix}_h=...&{prefix}_s=...&{prefix}_q=...`.
115
+ * Default values are omitted so URLs stay clean. Updates use
116
+ * `history.replaceState` (not pushState) so back/forward isn't polluted,
117
+ * and `popstate` is observed so external URL changes flow back into state.
118
+ */
119
+ function useDataGridUrlState(columns, opts) {
120
+ const prefix = opts?.paramPrefix ?? "grid";
121
+ const widthsKey = `${prefix}_w`;
122
+ const hiddenKey = `${prefix}_h`;
123
+ const sortKey = `${prefix}_s`;
124
+ const searchKey = `${prefix}_q`;
125
+ const columnsRef = useRef(columns);
126
+ columnsRef.current = columns;
127
+ const initialRef = useRef(opts?.initial);
128
+ const [state, setState] = useState(() => {
129
+ const base = createDefaultDataGridState(columns);
130
+ const initial = initialRef.current ?? {};
131
+ const baseWithInitial = {
132
+ ...base,
133
+ sorting: initial.sorting ?? base.sorting,
134
+ quickSearch: initial.quickSearch ?? base.quickSearch,
135
+ columnVisibility: initial.columnVisibility ?? base.columnVisibility
136
+ };
137
+ if (typeof window === "undefined") return baseWithInitial;
138
+ const params = new URLSearchParams(window.location.search);
139
+ return {
140
+ ...baseWithInitial,
141
+ columnWidths: parseWidths(params.get(widthsKey), base.columnWidths, columns),
142
+ columnVisibility: params.get(hiddenKey) != null ? parseHidden(params.get(hiddenKey), columns) : baseWithInitial.columnVisibility,
143
+ sorting: parseSort(params.get(sortKey), baseWithInitial.sorting, columns),
144
+ quickSearch: parseQuickSearch(params.get(searchKey), baseWithInitial.quickSearch)
145
+ };
146
+ });
147
+ useEffect(() => {
148
+ if (typeof window === "undefined") return;
149
+ const timer = setTimeout(() => {
150
+ const params = new URLSearchParams(window.location.search);
151
+ const before = params.toString();
152
+ const cols = columnsRef.current;
153
+ const initial = initialRef.current ?? {};
154
+ const widthsStr = serializeWidths(state.columnWidths, cols);
155
+ if (widthsStr) params.set(widthsKey, widthsStr);
156
+ else params.delete(widthsKey);
157
+ const hiddenStr = serializeHidden(state.columnVisibility);
158
+ const initialHidden = initial.columnVisibility ? serializeHidden(initial.columnVisibility) : "";
159
+ if (hiddenStr) params.set(hiddenKey, hiddenStr);
160
+ else if (initialHidden) params.set(hiddenKey, "");
161
+ else params.delete(hiddenKey);
162
+ const initialSort = initial.sorting ?? [];
163
+ if (sortEqual(state.sorting, initialSort)) params.delete(sortKey);
164
+ else params.set(sortKey, serializeSort(state.sorting));
165
+ const initialSearch = initial.quickSearch ?? "";
166
+ if (state.quickSearch === initialSearch) params.delete(searchKey);
167
+ else params.set(searchKey, state.quickSearch);
168
+ const after = params.toString();
169
+ if (before === after) return;
170
+ const url = `${window.location.pathname}${after ? `?${after}` : ""}${window.location.hash}`;
171
+ window.history.replaceState(window.history.state, "", url);
172
+ }, 100);
173
+ return () => clearTimeout(timer);
174
+ }, [
175
+ state.columnWidths,
176
+ state.columnVisibility,
177
+ state.sorting,
178
+ state.quickSearch,
179
+ widthsKey,
180
+ hiddenKey,
181
+ sortKey,
182
+ searchKey
183
+ ]);
184
+ useEffect(() => {
185
+ if (typeof window === "undefined") return;
186
+ const onPop = () => {
187
+ const params = new URLSearchParams(window.location.search);
188
+ const cols = columnsRef.current;
189
+ const initial = initialRef.current ?? {};
190
+ const defaults = createDefaultDataGridState(cols);
191
+ setState((prev) => ({
192
+ ...prev,
193
+ columnWidths: parseWidths(params.get(widthsKey), defaults.columnWidths, cols),
194
+ columnVisibility: params.get(hiddenKey) != null ? parseHidden(params.get(hiddenKey), cols) : initial.columnVisibility ?? defaults.columnVisibility,
195
+ sorting: parseSort(params.get(sortKey), initial.sorting ?? defaults.sorting, cols),
196
+ quickSearch: parseQuickSearch(params.get(searchKey), initial.quickSearch ?? defaults.quickSearch)
197
+ }));
198
+ };
199
+ window.addEventListener("popstate", onPop);
200
+ return () => window.removeEventListener("popstate", onPop);
201
+ }, [
202
+ widthsKey,
203
+ hiddenKey,
204
+ sortKey,
205
+ searchKey
206
+ ]);
207
+ return [state, setState];
208
+ }
209
+
210
+ //#endregion
211
+ export { useDataGridUrlState };
212
+ //# sourceMappingURL=use-url-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-url-state.js","names":[],"sources":["../../../../src/components/data-grid/use-url-state.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { DEFAULT_COL_WIDTH, clampColumnWidth } from \"./data-grid-sizing\";\nimport { createDefaultDataGridState } from \"./state\";\nimport type {\n DataGridColumnDef,\n DataGridSortItem,\n DataGridSortModel,\n DataGridState,\n} from \"./types\";\n\n// ─── URL <-> state encoding ──────────────────────────────────────────\n// Compact, human-readable formats so URLs stay short. Each piece of\n// state gets its own param so unrelated changes don't churn shared keys:\n//\n// ?{prefix}_w=name:200,email:300 column widths (only non-defaults)\n// ?{prefix}_h=createdAt,role hidden column ids\n// ?{prefix}_s=signedUpAt:desc,name:asc multi-column sort\n// ?{prefix}_q=alice quick-search text\n//\n// Column ids are URL-encoded so ids containing `,` `:` or other reserved\n// characters round-trip safely. Without encoding, an id like \"user:name\"\n// would silently break the parser.\n\n// ── widths ─────────────────────────────────────────────────────────\nfunction serializeWidths(\n widths: Record<string, number>,\n columns: readonly DataGridColumnDef<any>[],\n): string {\n const parts: string[] = [];\n for (const col of columns) {\n const w = widths[col.id];\n if (typeof w !== \"number\" || !Number.isFinite(w)) continue;\n const defaultW = clampColumnWidth(col, col.width ?? DEFAULT_COL_WIDTH);\n if (Math.round(w) === Math.round(defaultW)) continue;\n parts.push(`${encodeURIComponent(col.id)}:${Math.round(w)}`);\n }\n return parts.join(\",\");\n}\n\nfunction parseWidths(\n raw: string | null,\n fallback: Record<string, number>,\n columns: readonly DataGridColumnDef<any>[],\n): Record<string, number> {\n if (!raw) return fallback;\n const colMap = new Map(columns.map((c) => [c.id, c]));\n const out: Record<string, number> = { ...fallback };\n for (const part of raw.split(\",\")) {\n // Only split on the FIRST colon — id-side is always pre-encoded so it\n // can't contain a literal `:`, but width-side is always numeric.\n const colonIdx = part.indexOf(\":\");\n if (colonIdx <= 0) continue;\n const encodedId = part.slice(0, colonIdx);\n const num = part.slice(colonIdx + 1);\n let id: string;\n try {\n id = decodeURIComponent(encodedId);\n } catch {\n continue;\n }\n if (!id || !num) continue;\n const col = colMap.get(id);\n if (!col) continue;\n const n = Number(num);\n if (!Number.isFinite(n)) continue;\n out[id] = clampColumnWidth(col, n);\n }\n return out;\n}\n\n// ── hidden columns ─────────────────────────────────────────────────\nfunction serializeHidden(visibility: Record<string, boolean>): string {\n return Object.entries(visibility)\n .filter(([, v]) => v === false)\n .map(([id]) => encodeURIComponent(id))\n .join(\",\");\n}\n\nfunction parseHidden(\n raw: string | null,\n columns: readonly DataGridColumnDef<any>[],\n): Record<string, boolean> {\n if (!raw) return {};\n const known = new Set(columns.map((c) => c.id));\n const out: Record<string, boolean> = {};\n for (const encodedId of raw.split(\",\")) {\n let id: string;\n try {\n id = decodeURIComponent(encodedId);\n } catch {\n continue;\n }\n if (id && known.has(id)) out[id] = false;\n }\n return out;\n}\n\n// ── sort model ─────────────────────────────────────────────────────\nfunction serializeSort(sort: DataGridSortModel): string {\n return sort\n .map((s) => `${encodeURIComponent(s.columnId)}:${s.direction === \"desc\" ? \"desc\" : \"asc\"}`)\n .join(\",\");\n}\n\nfunction sortEqual(a: DataGridSortModel, b: DataGridSortModel): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i].columnId !== b[i].columnId || a[i].direction !== b[i].direction) return false;\n }\n return true;\n}\n\nfunction parseSort(\n raw: string | null,\n fallback: DataGridSortModel,\n columns: readonly DataGridColumnDef<any>[],\n): DataGridSortModel {\n if (raw == null) return fallback;\n if (raw === \"\") return [];\n const known = new Set(columns.map((c) => c.id));\n const out: DataGridSortItem[] = [];\n for (const part of raw.split(\",\")) {\n const colonIdx = part.indexOf(\":\");\n if (colonIdx <= 0) continue;\n const encodedId = part.slice(0, colonIdx);\n const dir = part.slice(colonIdx + 1);\n if (dir !== \"asc\" && dir !== \"desc\") continue;\n let id: string;\n try {\n id = decodeURIComponent(encodedId);\n } catch {\n continue;\n }\n if (!id || !known.has(id)) continue;\n out.push({ columnId: id, direction: dir });\n }\n return out;\n}\n\n// ── quick search ───────────────────────────────────────────────────\nfunction parseQuickSearch(raw: string | null, fallback: string): string {\n if (raw == null) return fallback;\n return raw;\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\ntype UrlStateOptions = {\n /** Disambiguates URL params when multiple grids share a page. Defaults\n * to `\"grid\"`. Use unique prefixes per-grid (e.g. `\"users\"`, `\"teams\"`). */\n paramPrefix?: string,\n /** Overrides for default state used when the URL has no value for a\n * given key. Useful for things like a sensible initial sort (e.g.\n * \"newest signups first\") that should appear on first load but be\n * overridden when the user navigates to a bookmarked URL. */\n initial?: Partial<Pick<DataGridState, \"sorting\" | \"quickSearch\" | \"columnVisibility\">>,\n};\n\n/**\n * Drop-in replacement for `useState(() => createDefaultDataGridState(columns))`\n * that persists user view preferences to URL search params, so a view\n * can be bookmarked / shared / restored on reload.\n *\n * **Persisted:** column widths, hidden columns, sort model, quick-search.\n * **Not persisted** (deliberately): pagination scroll position, selection,\n * column pinning/order, date display mode — these are session-scoped.\n *\n * ```tsx\n * const [gridState, setGridState] = useDataGridUrlState(columns, {\n * paramPrefix: \"users\",\n * initial: { sorting: [{ columnId: \"signedUpAt\", direction: \"desc\" }] },\n * });\n * ```\n *\n * URL encoding: `?{prefix}_w=...&{prefix}_h=...&{prefix}_s=...&{prefix}_q=...`.\n * Default values are omitted so URLs stay clean. Updates use\n * `history.replaceState` (not pushState) so back/forward isn't polluted,\n * and `popstate` is observed so external URL changes flow back into state.\n */\nexport function useDataGridUrlState<TRow>(\n columns: readonly DataGridColumnDef<TRow>[],\n opts?: UrlStateOptions,\n): [DataGridState, React.Dispatch<React.SetStateAction<DataGridState>>] {\n const prefix = opts?.paramPrefix ?? \"grid\";\n const widthsKey = `${prefix}_w`;\n const hiddenKey = `${prefix}_h`;\n const sortKey = `${prefix}_s`;\n const searchKey = `${prefix}_q`;\n\n const columnsRef = useRef(columns);\n columnsRef.current = columns;\n\n // `initial` snapshots are captured once on first render. Re-running them\n // each render would clobber the user's interactions.\n const initialRef = useRef(opts?.initial);\n\n const [state, setState] = useState<DataGridState>(() => {\n const base = createDefaultDataGridState(columns);\n const initial = initialRef.current ?? {};\n const baseWithInitial: DataGridState = {\n ...base,\n sorting: initial.sorting ?? base.sorting,\n quickSearch: initial.quickSearch ?? base.quickSearch,\n columnVisibility: initial.columnVisibility ?? base.columnVisibility,\n };\n if (typeof window === \"undefined\") return baseWithInitial;\n const params = new URLSearchParams(window.location.search);\n return {\n ...baseWithInitial,\n columnWidths: parseWidths(params.get(widthsKey), base.columnWidths, columns),\n columnVisibility: params.get(hiddenKey) != null\n ? parseHidden(params.get(hiddenKey), columns)\n : baseWithInitial.columnVisibility,\n sorting: parseSort(params.get(sortKey), baseWithInitial.sorting, columns),\n quickSearch: parseQuickSearch(params.get(searchKey), baseWithInitial.quickSearch),\n };\n });\n\n // Sync state -> URL. Debounced so that high-frequency state changes\n // (e.g. dragging a column resize handle, typing in the search box)\n // don't fire a URL write per pixel / per keystroke.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const timer = setTimeout(() => {\n const params = new URLSearchParams(window.location.search);\n const before = params.toString();\n const cols = columnsRef.current;\n const initial = initialRef.current ?? {};\n\n const widthsStr = serializeWidths(state.columnWidths, cols);\n if (widthsStr) params.set(widthsKey, widthsStr);\n else params.delete(widthsKey);\n\n const hiddenStr = serializeHidden(state.columnVisibility);\n // If the consumer supplied initial visibility, \"no hidden cols\" must\n // be encoded explicitly (empty string) so a bookmark with no `_h=`\n // doesn't silently re-hide a column the user just un-hid.\n const initialHidden = initial.columnVisibility\n ? serializeHidden(initial.columnVisibility)\n : \"\";\n if (hiddenStr) params.set(hiddenKey, hiddenStr);\n else if (initialHidden) params.set(hiddenKey, \"\");\n else params.delete(hiddenKey);\n\n const initialSort = initial.sorting ?? [];\n if (sortEqual(state.sorting, initialSort)) params.delete(sortKey);\n else params.set(sortKey, serializeSort(state.sorting));\n\n const initialSearch = initial.quickSearch ?? \"\";\n if (state.quickSearch === initialSearch) params.delete(searchKey);\n else params.set(searchKey, state.quickSearch);\n\n const after = params.toString();\n if (before === after) return;\n const url = `${window.location.pathname}${after ? `?${after}` : \"\"}${window.location.hash}`;\n window.history.replaceState(window.history.state, \"\", url);\n }, 100);\n return () => clearTimeout(timer);\n }, [\n state.columnWidths,\n state.columnVisibility,\n state.sorting,\n state.quickSearch,\n widthsKey,\n hiddenKey,\n sortKey,\n searchKey,\n ]);\n\n // React to back/forward navigation.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPop = () => {\n const params = new URLSearchParams(window.location.search);\n const cols = columnsRef.current;\n const initial = initialRef.current ?? {};\n // When the URL no longer has a value for a key, reset to defaults\n // rather than preserving the previous in-memory state — otherwise\n // navigating back to a clean URL leaves stale state.\n const defaults = createDefaultDataGridState(cols);\n setState((prev) => ({\n ...prev,\n columnWidths: parseWidths(params.get(widthsKey), defaults.columnWidths, cols),\n columnVisibility: params.get(hiddenKey) != null\n ? parseHidden(params.get(hiddenKey), cols)\n : (initial.columnVisibility ?? defaults.columnVisibility),\n sorting: parseSort(params.get(sortKey), initial.sorting ?? defaults.sorting, cols),\n quickSearch: parseQuickSearch(params.get(searchKey), initial.quickSearch ?? defaults.quickSearch),\n }));\n };\n window.addEventListener(\"popstate\", onPop);\n return () => window.removeEventListener(\"popstate\", onPop);\n }, [widthsKey, hiddenKey, sortKey, searchKey]);\n\n return [state, setState];\n}\n"],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { act, renderHook } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
3
+ import { useDataGridUrlState } from "./use-url-state.js";
4
+
5
+ //#region src/components/data-grid/use-url-state.test.tsx
6
+ // @vitest-environment jsdom
7
+ const columns = [{
8
+ id: "name",
9
+ header: "Name",
10
+ accessor: () => "",
11
+ width: 160,
12
+ minWidth: 80,
13
+ type: "string"
14
+ }, {
15
+ id: "email",
16
+ header: "Email",
17
+ accessor: () => "",
18
+ width: 200,
19
+ minWidth: 80,
20
+ type: "string"
21
+ }];
22
+ function setUrl(search) {
23
+ window.history.replaceState(null, "", `/${search ? `?${search}` : ""}`);
24
+ }
25
+ beforeEach(() => {
26
+ setUrl("");
27
+ });
28
+ afterEach(() => {
29
+ setUrl("");
30
+ });
31
+ describe("useDataGridUrlState", () => {
32
+ it("initializes from existing URL params", () => {
33
+ setUrl("grid_w=name:240&grid_h=email");
34
+ const { result } = renderHook(() => useDataGridUrlState(columns));
35
+ const [state] = result.current;
36
+ expect(state.columnWidths.name).toBe(240);
37
+ expect(state.columnVisibility.email).toBe(false);
38
+ });
39
+ it("writes width changes back to the URL (after debounce)", async () => {
40
+ const { result } = renderHook(() => useDataGridUrlState(columns));
41
+ act(() => {
42
+ const [, setState] = result.current;
43
+ setState((prev) => ({
44
+ ...prev,
45
+ columnWidths: {
46
+ ...prev.columnWidths,
47
+ name: 250
48
+ }
49
+ }));
50
+ });
51
+ await new Promise((resolve) => setTimeout(resolve, 150));
52
+ expect(new URLSearchParams(window.location.search).get("grid_w")).toBe("name:250");
53
+ });
54
+ it("resets column widths to defaults when a popstate clears the URL", () => {
55
+ setUrl("grid_w=name:300");
56
+ const { result } = renderHook(() => useDataGridUrlState(columns));
57
+ expect(result.current[0].columnWidths.name).toBe(300);
58
+ act(() => {
59
+ setUrl("");
60
+ window.dispatchEvent(new PopStateEvent("popstate"));
61
+ });
62
+ expect(result.current[0].columnWidths.name).toBe(160);
63
+ });
64
+ it("isolates two grids on the same page via paramPrefix", async () => {
65
+ const { result: a } = renderHook(() => useDataGridUrlState(columns, { paramPrefix: "users" }));
66
+ const { result: b } = renderHook(() => useDataGridUrlState(columns, { paramPrefix: "teams" }));
67
+ act(() => {
68
+ a.current[1]((prev) => ({
69
+ ...prev,
70
+ columnWidths: {
71
+ ...prev.columnWidths,
72
+ name: 222
73
+ }
74
+ }));
75
+ });
76
+ await new Promise((resolve) => setTimeout(resolve, 150));
77
+ const params = new URLSearchParams(window.location.search);
78
+ expect(params.get("users_w")).toBe("name:222");
79
+ expect(params.get("teams_w")).toBeNull();
80
+ expect(b.current[0].columnWidths.name).toBe(160);
81
+ });
82
+ it("ignores malformed entries in the URL param without throwing", () => {
83
+ setUrl("grid_w=:,name:abc,name:240,bogusid:99");
84
+ const { result } = renderHook(() => useDataGridUrlState(columns));
85
+ expect(result.current[0].columnWidths.name).toBe(240);
86
+ });
87
+ });
88
+
89
+ //#endregion
90
+ export { };
91
+ //# sourceMappingURL=use-url-state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-url-state.test.js","names":[],"sources":["../../../../src/components/data-grid/use-url-state.test.tsx"],"sourcesContent":["// @vitest-environment jsdom\n\nimport { act, renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport type { DataGridColumnDef } from \"./types\";\nimport { useDataGridUrlState } from \"./use-url-state\";\n\ntype Row = { id: string };\n\nconst columns: DataGridColumnDef<Row>[] = [\n { id: \"name\", header: \"Name\", accessor: () => \"\", width: 160, minWidth: 80, type: \"string\" },\n { id: \"email\", header: \"Email\", accessor: () => \"\", width: 200, minWidth: 80, type: \"string\" },\n];\n\nfunction setUrl(search: string) {\n window.history.replaceState(null, \"\", `/${search ? `?${search}` : \"\"}`);\n}\n\nbeforeEach(() => {\n setUrl(\"\");\n});\n\nafterEach(() => {\n setUrl(\"\");\n});\n\ndescribe(\"useDataGridUrlState\", () => {\n it(\"initializes from existing URL params\", () => {\n setUrl(\"grid_w=name:240&grid_h=email\");\n const { result } = renderHook(() => useDataGridUrlState(columns));\n const [state] = result.current;\n expect(state.columnWidths.name).toBe(240);\n expect(state.columnVisibility.email).toBe(false);\n });\n\n it(\"writes width changes back to the URL (after debounce)\", async () => {\n const { result } = renderHook(() => useDataGridUrlState(columns));\n\n act(() => {\n const [, setState] = result.current;\n setState((prev) => ({\n ...prev,\n columnWidths: { ...prev.columnWidths, name: 250 },\n }));\n });\n\n // Debounce is 100ms.\n await new Promise((resolve) => setTimeout(resolve, 150));\n const params = new URLSearchParams(window.location.search);\n expect(params.get(\"grid_w\")).toBe(\"name:250\");\n });\n\n it(\"resets column widths to defaults when a popstate clears the URL\", () => {\n setUrl(\"grid_w=name:300\");\n const { result } = renderHook(() => useDataGridUrlState(columns));\n expect(result.current[0].columnWidths.name).toBe(300);\n\n act(() => {\n setUrl(\"\");\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n });\n\n // Default for \"name\" column is its declared width of 160.\n expect(result.current[0].columnWidths.name).toBe(160);\n });\n\n it(\"isolates two grids on the same page via paramPrefix\", async () => {\n const { result: a } = renderHook(() => useDataGridUrlState(columns, { paramPrefix: \"users\" }));\n const { result: b } = renderHook(() => useDataGridUrlState(columns, { paramPrefix: \"teams\" }));\n\n act(() => {\n a.current[1]((prev) => ({ ...prev, columnWidths: { ...prev.columnWidths, name: 222 } }));\n });\n await new Promise((resolve) => setTimeout(resolve, 150));\n\n const params = new URLSearchParams(window.location.search);\n expect(params.get(\"users_w\")).toBe(\"name:222\");\n expect(params.get(\"teams_w\")).toBeNull();\n expect(b.current[0].columnWidths.name).toBe(160); // unaffected\n });\n\n it(\"ignores malformed entries in the URL param without throwing\", () => {\n setUrl(\"grid_w=:,name:abc,name:240,bogusid:99\");\n const { result } = renderHook(() => useDataGridUrlState(columns));\n // Only the well-formed `name:240` should land; junk is dropped silently.\n expect(result.current[0].columnWidths.name).toBe(240);\n });\n});\n"],"mappings":";;;;;;AASA,MAAM,UAAoC,CACxC;CAAE,IAAI;CAAQ,QAAQ;CAAQ,gBAAgB;CAAI,OAAO;CAAK,UAAU;CAAI,MAAM;CAAU,EAC5F;CAAE,IAAI;CAAS,QAAQ;CAAS,gBAAgB;CAAI,OAAO;CAAK,UAAU;CAAI,MAAM;CAAU,CAC/F;AAED,SAAS,OAAO,QAAgB;AAC9B,QAAO,QAAQ,aAAa,MAAM,IAAI,IAAI,SAAS,IAAI,WAAW,KAAK;;AAGzE,iBAAiB;AACf,QAAO,GAAG;EACV;AAEF,gBAAgB;AACd,QAAO,GAAG;EACV;AAEF,SAAS,6BAA6B;AACpC,IAAG,8CAA8C;AAC/C,SAAO,+BAA+B;EACtC,MAAM,EAAE,WAAW,iBAAiB,oBAAoB,QAAQ,CAAC;EACjE,MAAM,CAAC,SAAS,OAAO;AACvB,SAAO,MAAM,aAAa,KAAK,CAAC,KAAK,IAAI;AACzC,SAAO,MAAM,iBAAiB,MAAM,CAAC,KAAK,MAAM;GAChD;AAEF,IAAG,yDAAyD,YAAY;EACtE,MAAM,EAAE,WAAW,iBAAiB,oBAAoB,QAAQ,CAAC;AAEjE,YAAU;GACR,MAAM,GAAG,YAAY,OAAO;AAC5B,aAAU,UAAU;IAClB,GAAG;IACH,cAAc;KAAE,GAAG,KAAK;KAAc,MAAM;KAAK;IAClD,EAAE;IACH;AAGF,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;AAExD,SADe,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAC5C,IAAI,SAAS,CAAC,CAAC,KAAK,WAAW;GAC7C;AAEF,IAAG,yEAAyE;AAC1E,SAAO,kBAAkB;EACzB,MAAM,EAAE,WAAW,iBAAiB,oBAAoB,QAAQ,CAAC;AACjE,SAAO,OAAO,QAAQ,GAAG,aAAa,KAAK,CAAC,KAAK,IAAI;AAErD,YAAU;AACR,UAAO,GAAG;AACV,UAAO,cAAc,IAAI,cAAc,WAAW,CAAC;IACnD;AAGF,SAAO,OAAO,QAAQ,GAAG,aAAa,KAAK,CAAC,KAAK,IAAI;GACrD;AAEF,IAAG,uDAAuD,YAAY;EACpE,MAAM,EAAE,QAAQ,MAAM,iBAAiB,oBAAoB,SAAS,EAAE,aAAa,SAAS,CAAC,CAAC;EAC9F,MAAM,EAAE,QAAQ,MAAM,iBAAiB,oBAAoB,SAAS,EAAE,aAAa,SAAS,CAAC,CAAC;AAE9F,YAAU;AACR,KAAE,QAAQ,IAAI,UAAU;IAAE,GAAG;IAAM,cAAc;KAAE,GAAG,KAAK;KAAc,MAAM;KAAK;IAAE,EAAE;IACxF;AACF,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;EAExD,MAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAC1D,SAAO,OAAO,IAAI,UAAU,CAAC,CAAC,KAAK,WAAW;AAC9C,SAAO,OAAO,IAAI,UAAU,CAAC,CAAC,UAAU;AACxC,SAAO,EAAE,QAAQ,GAAG,aAAa,KAAK,CAAC,KAAK,IAAI;GAChD;AAEF,IAAG,qEAAqE;AACtE,SAAO,wCAAwC;EAC/C,MAAM,EAAE,WAAW,iBAAiB,oBAAoB,QAAQ,CAAC;AAEjE,SAAO,OAAO,QAAQ,GAAG,aAAa,KAAK,CAAC,KAAK,IAAI;GACrD;EACF"}
@@ -0,0 +1,67 @@
1
+ import { Dialog } from "@stackframe/stack-ui";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+ import React from "react";
4
+ import * as _radix_ui_react_dialog0 from "@radix-ui/react-dialog";
5
+
6
+ //#region src/components/dialog.d.ts
7
+ type DesignDialogSize = "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "full";
8
+ type DesignDialogVariant = "glassmorphic" | "plain";
9
+ type DesignDialogIcon = React.ElementType<{
10
+ className?: string;
11
+ }>;
12
+ type DesignDialogRootProps = Omit<React.ComponentProps<typeof Dialog>, "children">;
13
+ type DesignDialogProps = {
14
+ trigger?: React.ReactElement;
15
+ size?: DesignDialogSize;
16
+ variant?: DesignDialogVariant;
17
+ icon?: DesignDialogIcon | null;
18
+ title?: React.ReactNode;
19
+ description?: React.ReactNode;
20
+ headerContent?: React.ReactNode;
21
+ customHeader?: React.ReactNode;
22
+ footer?: React.ReactNode;
23
+ noBodyPadding?: boolean;
24
+ hideTopCloseButton?: boolean;
25
+ className?: string;
26
+ overlayClassName?: string;
27
+ headerClassName?: string;
28
+ bodyClassName?: string;
29
+ footerClassName?: string;
30
+ children?: React.ReactNode;
31
+ } & DesignDialogRootProps;
32
+ /**
33
+ * Canonical dashboard modal surface. This wraps the base dialog primitives with
34
+ * a reusable glassmorphic shell and consistent header/body/footer regions.
35
+ */
36
+ declare function DesignDialog({
37
+ trigger,
38
+ size,
39
+ variant,
40
+ icon: Icon,
41
+ title,
42
+ description,
43
+ headerContent,
44
+ customHeader,
45
+ footer,
46
+ noBodyPadding,
47
+ hideTopCloseButton,
48
+ className,
49
+ overlayClassName,
50
+ headerClassName,
51
+ bodyClassName,
52
+ footerClassName,
53
+ children,
54
+ ...dialogRootProps
55
+ }: DesignDialogProps): react_jsx_runtime0.JSX.Element;
56
+ declare const DesignDialogRoot: React.FC<_radix_ui_react_dialog0.DialogProps>;
57
+ declare const DesignDialogTrigger: React.ForwardRefExoticComponent<_radix_ui_react_dialog0.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
58
+ declare const DesignDialogClose: React.ForwardRefExoticComponent<_radix_ui_react_dialog0.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
59
+ declare const DesignDialogTitle: React.FC<Omit<_radix_ui_react_dialog0.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & {
60
+ ref?: React.Ref<HTMLHeadingElement> | undefined;
61
+ }>;
62
+ declare const DesignDialogDescription: React.FC<Omit<_radix_ui_react_dialog0.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & {
63
+ ref?: React.Ref<HTMLParagraphElement> | undefined;
64
+ }>;
65
+ //#endregion
66
+ export { DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogProps, DesignDialogRoot, DesignDialogSize, DesignDialogTitle, DesignDialogTrigger, DesignDialogVariant };
67
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","names":[],"sources":["../../../src/components/dialog.tsx"],"mappings":";;;;;;KAgBY,gBAAA;AAAA,KAaA,mBAAA;AAAA,KA0BP,gBAAA,GAAmB,KAAA,CAAM,WAAA;EAAc,SAAA;AAAA;AAAA,KAEvC,qBAAA,GAAwB,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,MAAA;AAAA,KAElD,iBAAA;EACV,OAAA,GAAU,KAAA,CAAM,YAAA;EAChB,IAAA,GAAO,gBAAA;EACP,OAAA,GAAU,mBAAA;EACV,IAAA,GAAO,gBAAA;EACP,KAAA,GAAQ,KAAA,CAAM,SAAA;EACd,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,aAAA,GAAgB,KAAA,CAAM,SAAA;EACtB,YAAA,GAAe,KAAA,CAAM,SAAA;EACrB,MAAA,GAAS,KAAA,CAAM,SAAA;EACf,aAAA;EACA,kBAAA;EACA,SAAA;EACA,gBAAA;EACA,eAAA;EACA,aAAA;EACA,eAAA;EACA,QAAA,GAAW,KAAA,CAAM,SAAA;AAAA,IACf,qBAAA;;;;;iBAMY,YAAA,CAAA;EACd,OAAA;EACA,IAAA;EACA,OAAA;EACA,IAAA,EAAM,IAAA;EACN,KAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,MAAA;EACA,aAAA;EACA,kBAAA;EACA,SAAA;EACA,gBAAA;EACA,eAAA;EACA,aAAA;EACA,eAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,iBAAA,GAAiB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAsFP,gBAAA,EAAgB,KAAA,CAAA,EAAA,CAAS,uBAAA,CAAT,WAAA;AAAA,cAChB,mBAAA,EAAmB,KAAA,CAAA,yBAAA,CAAgB,uBAAA,CAAhB,kBAAA,GAAA,KAAA,CAAA,aAAA,CAAA,iBAAA;AAAA,cACnB,iBAAA,EAAiB,KAAA,CAAA,yBAAA,CAAc,uBAAA,CAAd,gBAAA,GAAA,KAAA,CAAA,aAAA,CAAA,iBAAA;AAAA,cACjB,iBAAA,EAAiB,KAAA,CAAA,EAAA,CAAA,IAAA,CAAc,uBAAA,CAAd,gBAAA,GAAA,KAAA,CAAA,aAAA,CAAA,kBAAA;;;cACjB,uBAAA,EAAuB,KAAA,CAAA,EAAA,CAAA,IAAA,CAAoB,uBAAA,CAApB,sBAAA,GAAA,KAAA,CAAA,aAAA,CAAA,oBAAA"}
@@ -0,0 +1,86 @@
1
+ "use client";
2
+
3
+ import { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, cn } from "@stackframe/stack-ui";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import React from "react";
6
+
7
+ //#region src/components/dialog.tsx
8
+ const dialogSizeClasses = new Map([
9
+ ["sm", "max-w-sm"],
10
+ ["md", "max-w-md"],
11
+ ["lg", "max-w-lg"],
12
+ ["xl", "max-w-xl"],
13
+ ["2xl", "max-w-2xl"],
14
+ ["3xl", "max-w-3xl"],
15
+ ["4xl", "max-w-4xl"],
16
+ ["5xl", "max-w-5xl"],
17
+ ["6xl", "max-w-6xl"],
18
+ ["7xl", "max-w-7xl"],
19
+ ["full", "max-w-[calc(100vw-2rem)]"]
20
+ ]);
21
+ const dialogSurfaceClasses = new Map([["glassmorphic", "border-0 sm:rounded-2xl bg-background/85 backdrop-blur-2xl ring-1 ring-foreground/[0.06] shadow-[0_24px_48px_-12px_rgba(0,0,0,0.25),0_4px_24px_-8px_rgba(0,0,0,0.12)] dark:bg-background/80 dark:ring-white/[0.06]"], ["plain", "border bg-background shadow-lg sm:rounded-lg"]]);
22
+ const dialogOverlayClasses = new Map([["glassmorphic", "bg-black/50 backdrop-blur-sm"], ["plain", void 0]]);
23
+ /**
24
+ * Canonical dashboard modal surface. This wraps the base dialog primitives with
25
+ * a reusable glassmorphic shell and consistent header/body/footer regions.
26
+ */
27
+ function DesignDialog({ trigger, size = "lg", variant = "glassmorphic", icon: Icon = null, title, description, headerContent, customHeader, footer, noBodyPadding = false, hideTopCloseButton = false, className, overlayClassName, headerClassName, bodyClassName, footerClassName, children, ...dialogRootProps }) {
28
+ const resolvedSizeClass = dialogSizeClasses.get(size) ?? "max-w-lg";
29
+ const resolvedSurfaceClass = dialogSurfaceClasses.get(variant) ?? dialogSurfaceClasses.get("glassmorphic");
30
+ const resolvedOverlayClass = cn(dialogOverlayClasses.get(variant), overlayClassName);
31
+ const shouldRenderTopHeaderRow = Icon != null || title != null || description != null;
32
+ const shouldRenderHeader = customHeader != null || shouldRenderTopHeaderRow || headerContent != null;
33
+ const shouldRenderBody = React.Children.count(children) > 0;
34
+ return /* @__PURE__ */ jsxs(Dialog, {
35
+ ...dialogRootProps,
36
+ children: [trigger != null && /* @__PURE__ */ jsx(DialogTrigger, {
37
+ asChild: true,
38
+ children: trigger
39
+ }), /* @__PURE__ */ jsxs(DialogContent, {
40
+ className: cn("gap-0 p-0 overflow-hidden", resolvedSizeClass, resolvedSurfaceClass, className),
41
+ overlayProps: resolvedOverlayClass ? { className: resolvedOverlayClass } : void 0,
42
+ noCloseButton: hideTopCloseButton,
43
+ children: [
44
+ shouldRenderHeader && /* @__PURE__ */ jsx(DialogHeader, {
45
+ className: cn("px-6 pt-6 pb-4 border-b border-foreground/[0.06]", headerClassName),
46
+ children: customHeader ?? /* @__PURE__ */ jsxs(Fragment, { children: [shouldRenderTopHeaderRow && /* @__PURE__ */ jsxs("div", {
47
+ className: cn("flex items-start gap-3", Icon == null && "gap-0"),
48
+ children: [Icon != null && /* @__PURE__ */ jsx("div", {
49
+ className: "h-9 w-9 rounded-xl bg-primary/10 ring-1 ring-primary/15 flex items-center justify-center shrink-0",
50
+ children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 text-primary" })
51
+ }), (title != null || description != null) && /* @__PURE__ */ jsxs("div", {
52
+ className: "flex-1 min-w-0 space-y-1",
53
+ children: [title != null ? /* @__PURE__ */ jsx(DialogTitle, {
54
+ className: "text-base",
55
+ children: title
56
+ }) : null, description != null ? /* @__PURE__ */ jsx(DialogDescription, {
57
+ className: "text-xs",
58
+ children: description
59
+ }) : null]
60
+ })]
61
+ }), headerContent != null ? /* @__PURE__ */ jsx("div", {
62
+ className: cn(shouldRenderTopHeaderRow && "mt-4"),
63
+ children: headerContent
64
+ }) : null] })
65
+ }),
66
+ shouldRenderBody && /* @__PURE__ */ jsx(DialogBody, {
67
+ className: cn("mx-0 my-0 w-auto", noBodyPadding ? "px-0 py-0" : "px-6 py-4", bodyClassName),
68
+ children
69
+ }),
70
+ footer != null ? /* @__PURE__ */ jsx(DialogFooter, {
71
+ className: cn("px-6 py-3 border-t border-foreground/[0.06] bg-foreground/[0.02]", footerClassName),
72
+ children: footer
73
+ }) : null
74
+ ]
75
+ })]
76
+ });
77
+ }
78
+ const DesignDialogRoot = Dialog;
79
+ const DesignDialogTrigger = DialogTrigger;
80
+ const DesignDialogClose = DialogClose;
81
+ const DesignDialogTitle = DialogTitle;
82
+ const DesignDialogDescription = DialogDescription;
83
+
84
+ //#endregion
85
+ export { DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogRoot, DesignDialogTitle, DesignDialogTrigger };
86
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","names":[],"sources":["../../../src/components/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Dialog,\n DialogBody,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n cn,\n} from \"@stackframe/stack-ui\";\nimport React from \"react\";\n\nexport type DesignDialogSize =\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"xl\"\n | \"2xl\"\n | \"3xl\"\n | \"4xl\"\n | \"5xl\"\n | \"6xl\"\n | \"7xl\"\n | \"full\";\n\nexport type DesignDialogVariant = \"glassmorphic\" | \"plain\";\n\nconst dialogSizeClasses = new Map<DesignDialogSize, string>([\n [\"sm\", \"max-w-sm\"],\n [\"md\", \"max-w-md\"],\n [\"lg\", \"max-w-lg\"],\n [\"xl\", \"max-w-xl\"],\n [\"2xl\", \"max-w-2xl\"],\n [\"3xl\", \"max-w-3xl\"],\n [\"4xl\", \"max-w-4xl\"],\n [\"5xl\", \"max-w-5xl\"],\n [\"6xl\", \"max-w-6xl\"],\n [\"7xl\", \"max-w-7xl\"],\n [\"full\", \"max-w-[calc(100vw-2rem)]\"],\n]);\n\nconst dialogSurfaceClasses = new Map<DesignDialogVariant, string>([\n [\"glassmorphic\", \"border-0 sm:rounded-2xl bg-background/85 backdrop-blur-2xl ring-1 ring-foreground/[0.06] shadow-[0_24px_48px_-12px_rgba(0,0,0,0.25),0_4px_24px_-8px_rgba(0,0,0,0.12)] dark:bg-background/80 dark:ring-white/[0.06]\"],\n [\"plain\", \"border bg-background shadow-lg sm:rounded-lg\"],\n]);\n\nconst dialogOverlayClasses = new Map<DesignDialogVariant, string | undefined>([\n [\"glassmorphic\", \"bg-black/50 backdrop-blur-sm\"],\n [\"plain\", undefined],\n]);\n\ntype DesignDialogIcon = React.ElementType<{ className?: string }>;\n\ntype DesignDialogRootProps = Omit<React.ComponentProps<typeof Dialog>, \"children\">;\n\nexport type DesignDialogProps = {\n trigger?: React.ReactElement,\n size?: DesignDialogSize,\n variant?: DesignDialogVariant,\n icon?: DesignDialogIcon | null,\n title?: React.ReactNode,\n description?: React.ReactNode,\n headerContent?: React.ReactNode,\n customHeader?: React.ReactNode,\n footer?: React.ReactNode,\n noBodyPadding?: boolean,\n hideTopCloseButton?: boolean,\n className?: string,\n overlayClassName?: string,\n headerClassName?: string,\n bodyClassName?: string,\n footerClassName?: string,\n children?: React.ReactNode,\n} & DesignDialogRootProps;\n\n/**\n * Canonical dashboard modal surface. This wraps the base dialog primitives with\n * a reusable glassmorphic shell and consistent header/body/footer regions.\n */\nexport function DesignDialog({\n trigger,\n size = \"lg\",\n variant = \"glassmorphic\",\n icon: Icon = null,\n title,\n description,\n headerContent,\n customHeader,\n footer,\n noBodyPadding = false,\n hideTopCloseButton = false,\n className,\n overlayClassName,\n headerClassName,\n bodyClassName,\n footerClassName,\n children,\n ...dialogRootProps\n}: DesignDialogProps) {\n const resolvedSizeClass = dialogSizeClasses.get(size) ?? \"max-w-lg\";\n const resolvedSurfaceClass = dialogSurfaceClasses.get(variant) ?? dialogSurfaceClasses.get(\"glassmorphic\");\n const resolvedOverlayClass = cn(dialogOverlayClasses.get(variant), overlayClassName);\n const shouldRenderTopHeaderRow = Icon != null || title != null || description != null;\n const shouldRenderHeader = customHeader != null || shouldRenderTopHeaderRow || headerContent != null;\n const shouldRenderBody = React.Children.count(children) > 0;\n\n return (\n <Dialog {...dialogRootProps}>\n {trigger != null && (\n <DialogTrigger asChild>\n {trigger}\n </DialogTrigger>\n )}\n\n <DialogContent\n className={cn(\n \"gap-0 p-0 overflow-hidden\",\n resolvedSizeClass,\n resolvedSurfaceClass,\n className\n )}\n overlayProps={resolvedOverlayClass ? { className: resolvedOverlayClass } : undefined}\n noCloseButton={hideTopCloseButton}\n >\n {shouldRenderHeader && (\n <DialogHeader className={cn(\"px-6 pt-6 pb-4 border-b border-foreground/[0.06]\", headerClassName)}>\n {customHeader ?? (\n <>\n {shouldRenderTopHeaderRow && (\n <div className={cn(\"flex items-start gap-3\", Icon == null && \"gap-0\")}>\n {Icon != null && (\n <div className=\"h-9 w-9 rounded-xl bg-primary/10 ring-1 ring-primary/15 flex items-center justify-center shrink-0\">\n <Icon className=\"h-4 w-4 text-primary\" />\n </div>\n )}\n {(title != null || description != null) && (\n <div className=\"flex-1 min-w-0 space-y-1\">\n {title != null ? (\n <DialogTitle className=\"text-base\">\n {title}\n </DialogTitle>\n ) : null}\n {description != null ? (\n <DialogDescription className=\"text-xs\">\n {description}\n </DialogDescription>\n ) : null}\n </div>\n )}\n </div>\n )}\n\n {headerContent != null ? (\n <div className={cn(shouldRenderTopHeaderRow && \"mt-4\")}>\n {headerContent}\n </div>\n ) : null}\n </>\n )}\n </DialogHeader>\n )}\n\n {shouldRenderBody && (\n <DialogBody\n className={cn(\n \"mx-0 my-0 w-auto\",\n noBodyPadding ? \"px-0 py-0\" : \"px-6 py-4\",\n bodyClassName\n )}\n >\n {children}\n </DialogBody>\n )}\n\n {footer != null ? (\n <DialogFooter className={cn(\"px-6 py-3 border-t border-foreground/[0.06] bg-foreground/[0.02]\", footerClassName)}>\n {footer}\n </DialogFooter>\n ) : null}\n </DialogContent>\n </Dialog>\n );\n}\n\nexport const DesignDialogRoot = Dialog;\nexport const DesignDialogTrigger = DialogTrigger;\nexport const DesignDialogClose = DialogClose;\nexport const DesignDialogTitle = DialogTitle;\nexport const DesignDialogDescription = DialogDescription;\n"],"mappings":";;;;;;;AA+BA,MAAM,oBAAoB,IAAI,IAA8B;CAC1D,CAAC,MAAM,WAAW;CAClB,CAAC,MAAM,WAAW;CAClB,CAAC,MAAM,WAAW;CAClB,CAAC,MAAM,WAAW;CAClB,CAAC,OAAO,YAAY;CACpB,CAAC,OAAO,YAAY;CACpB,CAAC,OAAO,YAAY;CACpB,CAAC,OAAO,YAAY;CACpB,CAAC,OAAO,YAAY;CACpB,CAAC,OAAO,YAAY;CACpB,CAAC,QAAQ,2BAA2B;CACrC,CAAC;AAEF,MAAM,uBAAuB,IAAI,IAAiC,CAChE,CAAC,gBAAgB,qNAAqN,EACtO,CAAC,SAAS,+CAA+C,CAC1D,CAAC;AAEF,MAAM,uBAAuB,IAAI,IAA6C,CAC5E,CAAC,gBAAgB,+BAA+B,EAChD,CAAC,SAAS,OAAU,CACrB,CAAC;;;;;AA8BF,SAAgB,aAAa,EAC3B,SACA,OAAO,MACP,UAAU,gBACV,MAAM,OAAO,MACb,OACA,aACA,eACA,cACA,QACA,gBAAgB,OAChB,qBAAqB,OACrB,WACA,kBACA,iBACA,eACA,iBACA,UACA,GAAG,mBACiB;CACpB,MAAM,oBAAoB,kBAAkB,IAAI,KAAK,IAAI;CACzD,MAAM,uBAAuB,qBAAqB,IAAI,QAAQ,IAAI,qBAAqB,IAAI,eAAe;CAC1G,MAAM,uBAAuB,GAAG,qBAAqB,IAAI,QAAQ,EAAE,iBAAiB;CACpF,MAAM,2BAA2B,QAAQ,QAAQ,SAAS,QAAQ,eAAe;CACjF,MAAM,qBAAqB,gBAAgB,QAAQ,4BAA4B,iBAAiB;CAChG,MAAM,mBAAmB,MAAM,SAAS,MAAM,SAAS,GAAG;AAE1D,QACE,qBAAC;EAAO,GAAI;aACT,WAAW,QACV,oBAAC;GAAc;aACZ;IACa,EAGlB,qBAAC;GACC,WAAW,GACT,6BACA,mBACA,sBACA,UACD;GACD,cAAc,uBAAuB,EAAE,WAAW,sBAAsB,GAAG;GAC3E,eAAe;;IAEd,sBACC,oBAAC;KAAa,WAAW,GAAG,oDAAoD,gBAAgB;eAC7F,gBACC,4CACG,4BACC,qBAAC;MAAI,WAAW,GAAG,0BAA0B,QAAQ,QAAQ,QAAQ;iBAClE,QAAQ,QACP,oBAAC;OAAI,WAAU;iBACb,oBAAC,QAAK,WAAU,yBAAyB;QACrC,GAEN,SAAS,QAAQ,eAAe,SAChC,qBAAC;OAAI,WAAU;kBACZ,SAAS,OACR,oBAAC;QAAY,WAAU;kBACpB;SACW,GACZ,MACH,eAAe,OACd,oBAAC;QAAkB,WAAU;kBAC1B;SACiB,GAClB;QACA;OAEJ,EAGP,iBAAiB,OAChB,oBAAC;MAAI,WAAW,GAAG,4BAA4B,OAAO;gBACnD;OACG,GACJ,QACH;MAEQ;IAGhB,oBACC,oBAAC;KACC,WAAW,GACT,oBACA,gBAAgB,cAAc,aAC9B,cACD;KAEA;MACU;IAGd,UAAU,OACT,oBAAC;KAAa,WAAW,GAAG,oEAAoE,gBAAgB;eAC7G;MACY,GACb;;IACU;GACT;;AAIb,MAAa,mBAAmB;AAChC,MAAa,sBAAsB;AACnC,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;AACjC,MAAa,0BAA0B"}
@@ -3,6 +3,7 @@ import { DesignBadge, DesignBadgeColor, DesignBadgeContentMode, DesignBadgeProps
3
3
  import { DesignButton, DesignButtonProps, DesignOriginalButtonProps } from "./components/button";
4
4
  import { DesignCard, DesignCardProps, DesignCardTint, DesignCardTintProps, useGlassmorphicDefault, useInsideDesignCard } from "./components/card";
5
5
  import { CursorBlastEffect, CursorBlastEffectProps } from "./components/cursor-blast-effect";
6
+ import { DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogProps, DesignDialogRoot, DesignDialogSize, DesignDialogTitle, DesignDialogTrigger, DesignDialogVariant } from "./components/dialog";
6
7
  import { DesignEditMode, useDesignEditMode } from "./components/edit-mode";
7
8
  import { DesignInput, DesignInputProps } from "./components/input";
8
9
  import { DesignPillToggle, DesignPillToggleOption, DesignPillToggleProps } from "./components/pill-toggle";
@@ -20,4 +21,4 @@ import { DesignProgressBar, DesignProgressBarProps } from "./components/progress
20
21
  import { DesignEmptyState, DesignEmptyStateProps } from "./components/empty-state";
21
22
  export * from "./components/analytics-chart";
22
23
  export * from "./components/data-grid";
23
- export { CursorBlastEffect, type CursorBlastEffectProps, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DesignAlert, type DesignAlertProps, DesignBadge, type DesignBadgeColor, type DesignBadgeContentMode, type DesignBadgeProps, type DesignBadgeSize, DesignButton, type DesignButtonProps, DesignCard, type DesignCardProps, DesignCardTint, type DesignCardTintProps, type DesignCategoryTabItem, DesignCategoryTabs, type DesignCategoryTabsProps, DesignChartCard, type DesignChartCardProps, type DesignChartColorEntry, type DesignChartColorName, type DesignChartConfig, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignEditMode, DesignEmptyState, type DesignEmptyStateProps, DesignInput, type DesignInputProps, DesignMetricCard, type DesignMetricCardProps, type DesignMetricCardTrend, type DesignOriginalButtonProps, DesignPillToggle, type DesignPillToggleOption, type DesignPillToggleProps, DesignProgressBar, type DesignProgressBarProps, DesignSeparator, type DesignSeparatorProps, DesignSkeleton, type DesignSkeletonProps, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, getDesignChartColor, getPayloadConfigFromPayload, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };
24
+ export { CursorBlastEffect, type CursorBlastEffectProps, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DesignAlert, type DesignAlertProps, DesignBadge, type DesignBadgeColor, type DesignBadgeContentMode, type DesignBadgeProps, type DesignBadgeSize, DesignButton, type DesignButtonProps, DesignCard, type DesignCardProps, DesignCardTint, type DesignCardTintProps, type DesignCategoryTabItem, DesignCategoryTabs, type DesignCategoryTabsProps, DesignChartCard, type DesignChartCardProps, type DesignChartColorEntry, type DesignChartColorName, type DesignChartConfig, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignDialog, DesignDialogClose, DesignDialogDescription, type DesignDialogProps, DesignDialogRoot, type DesignDialogSize, DesignDialogTitle, DesignDialogTrigger, type DesignDialogVariant, DesignEditMode, DesignEmptyState, type DesignEmptyStateProps, DesignInput, type DesignInputProps, DesignMetricCard, type DesignMetricCardProps, type DesignMetricCardTrend, type DesignOriginalButtonProps, DesignPillToggle, type DesignPillToggleOption, type DesignPillToggleProps, DesignProgressBar, type DesignProgressBarProps, DesignSeparator, type DesignSeparatorProps, DesignSkeleton, type DesignSkeletonProps, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, getDesignChartColor, getPayloadConfigFromPayload, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };
package/dist/esm/index.js CHANGED
@@ -3,6 +3,7 @@ import { DesignBadge } from "./components/badge.js";
3
3
  import { DesignButton } from "./components/button.js";
4
4
  import { DesignCard, DesignCardTint, useGlassmorphicDefault, useInsideDesignCard } from "./components/card.js";
5
5
  import { CursorBlastEffect } from "./components/cursor-blast-effect.js";
6
+ import { DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogRoot, DesignDialogTitle, DesignDialogTrigger } from "./components/dialog.js";
6
7
  import { DesignEditMode, useDesignEditMode } from "./components/edit-mode.js";
7
8
  import { DesignInput } from "./components/input.js";
8
9
  import { DesignPillToggle } from "./components/pill-toggle.js";
@@ -23,4 +24,4 @@ export * from "./components/analytics-chart/index.js"
23
24
 
24
25
  export * from "./components/data-grid/index.js"
25
26
 
26
- export { CursorBlastEffect, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DesignAlert, DesignBadge, DesignButton, DesignCard, DesignCardTint, DesignCategoryTabs, DesignChartCard, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignEditMode, DesignEmptyState, DesignInput, DesignMetricCard, DesignPillToggle, DesignProgressBar, DesignSeparator, DesignSkeleton, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, getDesignChartColor, getPayloadConfigFromPayload, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };
27
+ export { CursorBlastEffect, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DesignAlert, DesignBadge, DesignButton, DesignCard, DesignCardTint, DesignCategoryTabs, DesignChartCard, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogRoot, DesignDialogTitle, DesignDialogTrigger, DesignEditMode, DesignEmptyState, DesignInput, DesignMetricCard, DesignPillToggle, DesignProgressBar, DesignSeparator, DesignSkeleton, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, getDesignChartColor, getPayloadConfigFromPayload, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };
package/dist/index.d.ts CHANGED
@@ -16,12 +16,14 @@ import { DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_CO
16
16
  import { DesignChartTooltip, DesignChartTooltipContent } from "./components/chart-tooltip.js";
17
17
  import { CursorBlastEffect, CursorBlastEffectProps } from "./components/cursor-blast-effect.js";
18
18
  import { DataGridCallbacks, DataGridCellContext, DataGridColumnAlign, DataGridColumnDef, DataGridColumnPin, DataGridColumnPinning, DataGridColumnType, DataGridColumnVisibility, DataGridDataPaginationMode, DataGridDataSource, DataGridDateDisplay, DataGridDateFormat, DataGridFetchParams, DataGridFetchResult, DataGridFooterContext, DataGridHeaderContext, DataGridPaginationMode, DataGridPaginationModel, DataGridProps, DataGridSelectOption, DataGridSelectionMode, DataGridSelectionModel, DataGridSortItem, DataGridSortModel, DataGridState, DataGridStrings, DataGridToolbarContext, RowId } from "./components/data-grid/types.js";
19
- import { getEffectiveMinWidth } from "./components/data-grid/data-grid-sizing.js";
19
+ import { DEFAULT_COL_WIDTH, DEFAULT_MAX_COL_WIDTH, clampColumnWidth, getEffectiveMaxWidth, getEffectiveMinWidth } from "./components/data-grid/data-grid-sizing.js";
20
20
  import { DataGridToolbar } from "./components/data-grid/data-grid-toolbar.js";
21
21
  import { DataGrid, isDataGridInteractiveRowClickTarget } from "./components/data-grid/data-grid.js";
22
22
  import { UseDataSourceResult, useDataSource } from "./components/data-grid/use-data-source.js";
23
- import { DEFAULT_PAGINATION, EMPTY_SELECTION, EMPTY_SORT_MODEL, applyQuickSearch, buildRowComparator, clearSelection, createDefaultDataGridState, defaultFormatAbsolute, defaultFormatRelative, defaultMatchRow, defaultParseDate, exportToCsv, formatGridDate, getSortDirection, getSortIndex, getTotalPages, isColumnVisible, paginateRows, resolveColumnValue, resolveColumnWidth, selectAll, toggleRowSelection, toggleSort } from "./components/data-grid/state.js";
23
+ import { useDataGridUrlState } from "./components/data-grid/use-url-state.js";
24
+ import { applyQuickSearch, buildRowComparator, createDefaultDataGridState, defaultFormatAbsolute, defaultFormatRelative, defaultMatchRow, defaultParseDate, exportToCsv, formatGridDate, paginateRows, resolveColumnValue } from "./components/data-grid/state.js";
24
25
  import { DATA_GRID_DEFAULT_STRINGS, resolveDataGridStrings } from "./components/data-grid/strings.js";
26
+ import { DesignDialog, DesignDialogClose, DesignDialogDescription, DesignDialogProps, DesignDialogRoot, DesignDialogSize, DesignDialogTitle, DesignDialogTrigger, DesignDialogVariant } from "./components/dialog.js";
25
27
  import { DesignEditMode, useDesignEditMode } from "./components/edit-mode.js";
26
28
  import { DesignEmptyState, DesignEmptyStateProps } from "./components/empty-state.js";
27
29
  import { DesignInput, DesignInputProps } from "./components/input.js";
@@ -32,4 +34,4 @@ import { DesignSeparator, DesignSeparatorProps } from "./components/separator.js
32
34
  import { DesignSkeleton, DesignSkeletonProps } from "./components/skeleton.js";
33
35
  import { DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow } from "./components/table.js";
34
36
  import { DesignCategoryTabItem, DesignCategoryTabs, DesignCategoryTabsProps } from "./components/tabs.js";
35
- export { ANALYTICS_CHART_DEFAULT_LAYERS, ANALYTICS_CHART_DEFAULT_PALETTE, ANALYTICS_CHART_DEFAULT_STATE, ANALYTICS_CHART_DEFAULT_STRINGS, AnalyticsChart, AnalyticsChartAnnotationsLayer, AnalyticsChartAreaLayer, AnalyticsChartBarLayer, AnalyticsChartDataLayer, AnalyticsChartDelta, AnalyticsChartLayer, AnalyticsChartLayerType, AnalyticsChartLayers, AnalyticsChartLineLayer, AnalyticsChartPalette, AnalyticsChartPieProps, AnalyticsChartPieState, AnalyticsChartProps, AnalyticsChartSegmentRamp, AnalyticsChartSeries, AnalyticsChartState, AnalyticsChartStrings, AnalyticsChartStrokeStyle, AnalyticsChartTimeseriesState, AnalyticsChartTooltipContext, AnalyticsChartTooltipLayerView, AnalyticsChartTooltipSegmentRow, AnalyticsChartView, Annotation, CursorBlastEffect, type CursorBlastEffectProps, DATA_GRID_DEFAULT_STRINGS, DEFAULT_FORMAT_KIND, DEFAULT_PAGINATION, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DataGrid, DataGridCallbacks, DataGridCellContext, DataGridColumnAlign, DataGridColumnDef, DataGridColumnPin, DataGridColumnPinning, DataGridColumnType, DataGridColumnVisibility, DataGridDataPaginationMode, DataGridDataSource, DataGridDateDisplay, DataGridDateFormat, DataGridFetchParams, DataGridFetchResult, DataGridFooterContext, DataGridHeaderContext, DataGridPaginationMode, DataGridPaginationModel, DataGridProps, DataGridSelectOption, DataGridSelectionMode, DataGridSelectionModel, DataGridSortItem, DataGridSortModel, DataGridState, DataGridStrings, DataGridToolbar, DataGridToolbarContext, DefaultAnalyticsChartTooltip, DefaultAnalyticsChartTooltipProps, DesignAlert, type DesignAlertProps, DesignBadge, type DesignBadgeColor, type DesignBadgeContentMode, type DesignBadgeProps, type DesignBadgeSize, DesignButton, type DesignButtonProps, DesignCard, type DesignCardProps, DesignCardTint, type DesignCardTintProps, type DesignCategoryTabItem, DesignCategoryTabs, type DesignCategoryTabsProps, DesignChartCard, type DesignChartCardProps, type DesignChartColorEntry, type DesignChartColorName, type DesignChartConfig, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignEditMode, DesignEmptyState, type DesignEmptyStateProps, DesignInput, type DesignInputProps, DesignMetricCard, type DesignMetricCardProps, type DesignMetricCardTrend, type DesignOriginalButtonProps, DesignPillToggle, type DesignPillToggleOption, type DesignPillToggleProps, DesignProgressBar, type DesignProgressBarProps, DesignSeparator, type DesignSeparatorProps, DesignSkeleton, type DesignSkeletonProps, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, EMPTY_MATRIX, EMPTY_SELECTION, EMPTY_SERIES, EMPTY_SORT_MODEL, FORMAT_KIND_TYPES, FormatKind, FormatKindCurrency, FormatKindDatetime, FormatKindDuration, FormatKindNumeric, FormatKindPercent, FormatKindShort, FormatKindType, Margin, Point, ResolvedDataLayerStyle, RowId, STROKE_DASHARRAY, TrendPill, UseDataSourceResult, applyQuickSearch, buildRampColors, buildRowComparator, buildSegmentThemeMap, clearSelection, computeLocalInProgressIdx, createDefaultDataGridState, defaultFormatAbsolute, defaultFormatRelative, defaultMatchRow, defaultParseDate, exportToCsv, findAnnotationsLayer, findCompareLayer, findLayerById, findPrimaryLayer, formatDelta, formatGridDate, formatValue, getDesignChartColor, getEffectiveMinWidth, getPayloadConfigFromPayload, getSortDirection, getSortIndex, getTotalPages, isAnalyticsChartDataLayer, isColumnVisible, isDataGridInteractiveRowClickTarget, isTimeseriesState, paginateRows, patchLayerById, pointValue, resolveAnalyticsChartPalette, resolveAnalyticsChartStrings, resolveColumnValue, resolveColumnWidth, resolveDataGridStrings, resolveDataLayerStyle, selectAll, setLayerById, toggleRowSelection, toggleSort, useDataSource, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };
37
+ export { ANALYTICS_CHART_DEFAULT_LAYERS, ANALYTICS_CHART_DEFAULT_PALETTE, ANALYTICS_CHART_DEFAULT_STATE, ANALYTICS_CHART_DEFAULT_STRINGS, AnalyticsChart, AnalyticsChartAnnotationsLayer, AnalyticsChartAreaLayer, AnalyticsChartBarLayer, AnalyticsChartDataLayer, AnalyticsChartDelta, AnalyticsChartLayer, AnalyticsChartLayerType, AnalyticsChartLayers, AnalyticsChartLineLayer, AnalyticsChartPalette, AnalyticsChartPieProps, AnalyticsChartPieState, AnalyticsChartProps, AnalyticsChartSegmentRamp, AnalyticsChartSeries, AnalyticsChartState, AnalyticsChartStrings, AnalyticsChartStrokeStyle, AnalyticsChartTimeseriesState, AnalyticsChartTooltipContext, AnalyticsChartTooltipLayerView, AnalyticsChartTooltipSegmentRow, AnalyticsChartView, Annotation, CursorBlastEffect, type CursorBlastEffectProps, DATA_GRID_DEFAULT_STRINGS, DEFAULT_COL_WIDTH, DEFAULT_FORMAT_KIND, DEFAULT_MAX_COL_WIDTH, DESIGN_CHART_AXIS_TICK_STYLE, DESIGN_CHART_COLORS, DESIGN_CHART_GRID_COLOR, DataGrid, DataGridCallbacks, DataGridCellContext, DataGridColumnAlign, DataGridColumnDef, DataGridColumnPin, DataGridColumnPinning, DataGridColumnType, DataGridColumnVisibility, DataGridDataPaginationMode, DataGridDataSource, DataGridDateDisplay, DataGridDateFormat, DataGridFetchParams, DataGridFetchResult, DataGridFooterContext, DataGridHeaderContext, DataGridPaginationMode, DataGridPaginationModel, DataGridProps, DataGridSelectOption, DataGridSelectionMode, DataGridSelectionModel, DataGridSortItem, DataGridSortModel, DataGridState, DataGridStrings, DataGridToolbar, DataGridToolbarContext, DefaultAnalyticsChartTooltip, DefaultAnalyticsChartTooltipProps, DesignAlert, type DesignAlertProps, DesignBadge, type DesignBadgeColor, type DesignBadgeContentMode, type DesignBadgeProps, type DesignBadgeSize, DesignButton, type DesignButtonProps, DesignCard, type DesignCardProps, DesignCardTint, type DesignCardTintProps, type DesignCategoryTabItem, DesignCategoryTabs, type DesignCategoryTabsProps, DesignChartCard, type DesignChartCardProps, type DesignChartColorEntry, type DesignChartColorName, type DesignChartConfig, DesignChartContainer, DesignChartLegendContent, DesignChartStyle, DesignChartTooltip, DesignChartTooltipContent, DesignDialog, DesignDialogClose, DesignDialogDescription, type DesignDialogProps, DesignDialogRoot, type DesignDialogSize, DesignDialogTitle, DesignDialogTrigger, type DesignDialogVariant, DesignEditMode, DesignEmptyState, type DesignEmptyStateProps, DesignInput, type DesignInputProps, DesignMetricCard, type DesignMetricCardProps, type DesignMetricCardTrend, type DesignOriginalButtonProps, DesignPillToggle, type DesignPillToggleOption, type DesignPillToggleProps, DesignProgressBar, type DesignProgressBarProps, DesignSeparator, type DesignSeparatorProps, DesignSkeleton, type DesignSkeletonProps, DesignTable, DesignTableBody, DesignTableCell, DesignTableHead, DesignTableHeader, DesignTableRow, EMPTY_MATRIX, EMPTY_SERIES, FORMAT_KIND_TYPES, FormatKind, FormatKindCurrency, FormatKindDatetime, FormatKindDuration, FormatKindNumeric, FormatKindPercent, FormatKindShort, FormatKindType, Margin, Point, ResolvedDataLayerStyle, RowId, STROKE_DASHARRAY, TrendPill, UseDataSourceResult, applyQuickSearch, buildRampColors, buildRowComparator, buildSegmentThemeMap, clampColumnWidth, computeLocalInProgressIdx, createDefaultDataGridState, defaultFormatAbsolute, defaultFormatRelative, defaultMatchRow, defaultParseDate, exportToCsv, findAnnotationsLayer, findCompareLayer, findLayerById, findPrimaryLayer, formatDelta, formatGridDate, formatValue, getDesignChartColor, getEffectiveMaxWidth, getEffectiveMinWidth, getPayloadConfigFromPayload, isAnalyticsChartDataLayer, isDataGridInteractiveRowClickTarget, isTimeseriesState, paginateRows, patchLayerById, pointValue, resolveAnalyticsChartPalette, resolveAnalyticsChartStrings, resolveColumnValue, resolveDataGridStrings, resolveDataLayerStyle, setLayerById, useDataGridUrlState, useDataSource, useDesignChart, useDesignEditMode, useGlassmorphicDefault, useInsideDesignCard };