@stackframe/dashboard-ui-components 2.8.89 → 2.8.92
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.
- package/dist/components/chart-legend.d.ts +1 -1
- package/dist/components/data-grid/data-grid-sizing.d.ts +6 -5
- package/dist/components/data-grid/data-grid-sizing.d.ts.map +1 -1
- package/dist/components/data-grid/data-grid-sizing.js +9 -28
- package/dist/components/data-grid/data-grid-sizing.js.map +1 -1
- package/dist/components/data-grid/data-grid.d.ts +17 -237
- package/dist/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/components/data-grid/data-grid.js +377 -523
- package/dist/components/data-grid/data-grid.js.map +1 -1
- package/dist/components/data-grid/data-grid.test.js +82 -0
- package/dist/components/data-grid/data-grid.test.js.map +1 -1
- package/dist/components/data-grid/index.d.ts +4 -3
- package/dist/components/data-grid/index.js +17 -58
- package/dist/components/data-grid/state.d.ts +4 -61
- package/dist/components/data-grid/state.d.ts.map +1 -1
- package/dist/components/data-grid/state.js +13 -160
- package/dist/components/data-grid/state.js.map +1 -1
- package/dist/components/data-grid/types.d.ts +9 -4
- package/dist/components/data-grid/types.d.ts.map +1 -1
- package/dist/components/data-grid/use-url-state.d.ts +38 -0
- package/dist/components/data-grid/use-url-state.d.ts.map +1 -0
- package/dist/components/data-grid/use-url-state.js +214 -0
- package/dist/components/data-grid/use-url-state.js.map +1 -0
- package/dist/components/data-grid/use-url-state.test.d.ts +1 -0
- package/dist/components/data-grid/use-url-state.test.js +91 -0
- package/dist/components/data-grid/use-url-state.test.js.map +1 -0
- package/dist/components/dialog.d.ts +67 -0
- package/dist/components/dialog.d.ts.map +1 -0
- package/dist/components/dialog.js +100 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/dashboard-ui-components.global.js +10651 -6388
- package/dist/dashboard-ui-components.global.js.map +4 -4
- package/dist/esm/components/chart-legend.d.ts +1 -1
- package/dist/esm/components/data-grid/data-grid-sizing.d.ts +6 -5
- package/dist/esm/components/data-grid/data-grid-sizing.d.ts.map +1 -1
- package/dist/esm/components/data-grid/data-grid-sizing.js +7 -26
- package/dist/esm/components/data-grid/data-grid-sizing.js.map +1 -1
- package/dist/esm/components/data-grid/data-grid.d.ts +17 -237
- package/dist/esm/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/esm/components/data-grid/data-grid.js +380 -526
- package/dist/esm/components/data-grid/data-grid.js.map +1 -1
- package/dist/esm/components/data-grid/data-grid.test.js +82 -0
- package/dist/esm/components/data-grid/data-grid.test.js.map +1 -1
- package/dist/esm/components/data-grid/index.d.ts +4 -3
- package/dist/esm/components/data-grid/index.js +4 -3
- package/dist/esm/components/data-grid/state.d.ts +4 -61
- package/dist/esm/components/data-grid/state.d.ts.map +1 -1
- package/dist/esm/components/data-grid/state.js +15 -150
- package/dist/esm/components/data-grid/state.js.map +1 -1
- package/dist/esm/components/data-grid/types.d.ts +9 -4
- package/dist/esm/components/data-grid/types.d.ts.map +1 -1
- package/dist/esm/components/data-grid/use-url-state.d.ts +38 -0
- package/dist/esm/components/data-grid/use-url-state.d.ts.map +1 -0
- package/dist/esm/components/data-grid/use-url-state.js +212 -0
- package/dist/esm/components/data-grid/use-url-state.js.map +1 -0
- package/dist/esm/components/data-grid/use-url-state.test.d.ts +1 -0
- package/dist/esm/components/data-grid/use-url-state.test.js +91 -0
- package/dist/esm/components/data-grid/use-url-state.test.js.map +1 -0
- package/dist/esm/components/dialog.d.ts +67 -0
- package/dist/esm/components/dialog.d.ts.map +1 -0
- package/dist/esm/components/dialog.js +92 -0
- package/dist/esm/components/dialog.js.map +1 -0
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +37 -0
- package/package.json +4 -3
|
@@ -6,6 +6,7 @@ let __data_grid_sizing_js = require("./data-grid-sizing.js");
|
|
|
6
6
|
let __data_grid_toolbar_js = require("./data-grid-toolbar.js");
|
|
7
7
|
let __data_grid_js = require("./data-grid.js");
|
|
8
8
|
let __use_data_source_js = require("./use-data-source.js");
|
|
9
|
+
let __use_url_state_js = require("./use-url-state.js");
|
|
9
10
|
|
|
10
11
|
Object.defineProperty(exports, 'DATA_GRID_DEFAULT_STRINGS', {
|
|
11
12
|
enumerable: true,
|
|
@@ -13,34 +14,28 @@ Object.defineProperty(exports, 'DATA_GRID_DEFAULT_STRINGS', {
|
|
|
13
14
|
return __strings_js.DATA_GRID_DEFAULT_STRINGS;
|
|
14
15
|
}
|
|
15
16
|
});
|
|
16
|
-
Object.defineProperty(exports, '
|
|
17
|
+
Object.defineProperty(exports, 'DEFAULT_COL_WIDTH', {
|
|
17
18
|
enumerable: true,
|
|
18
19
|
get: function () {
|
|
19
|
-
return
|
|
20
|
+
return __data_grid_sizing_js.DEFAULT_COL_WIDTH;
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
|
-
Object.defineProperty(exports, '
|
|
23
|
-
enumerable: true,
|
|
24
|
-
get: function () {
|
|
25
|
-
return __data_grid_js.DataGrid;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
Object.defineProperty(exports, 'DataGridToolbar', {
|
|
23
|
+
Object.defineProperty(exports, 'DEFAULT_MAX_COL_WIDTH', {
|
|
29
24
|
enumerable: true,
|
|
30
25
|
get: function () {
|
|
31
|
-
return
|
|
26
|
+
return __data_grid_sizing_js.DEFAULT_MAX_COL_WIDTH;
|
|
32
27
|
}
|
|
33
28
|
});
|
|
34
|
-
Object.defineProperty(exports, '
|
|
29
|
+
Object.defineProperty(exports, 'DataGrid', {
|
|
35
30
|
enumerable: true,
|
|
36
31
|
get: function () {
|
|
37
|
-
return
|
|
32
|
+
return __data_grid_js.DataGrid;
|
|
38
33
|
}
|
|
39
34
|
});
|
|
40
|
-
Object.defineProperty(exports, '
|
|
35
|
+
Object.defineProperty(exports, 'DataGridToolbar', {
|
|
41
36
|
enumerable: true,
|
|
42
37
|
get: function () {
|
|
43
|
-
return
|
|
38
|
+
return __data_grid_toolbar_js.DataGridToolbar;
|
|
44
39
|
}
|
|
45
40
|
});
|
|
46
41
|
Object.defineProperty(exports, 'applyQuickSearch', {
|
|
@@ -55,10 +50,10 @@ Object.defineProperty(exports, 'buildRowComparator', {
|
|
|
55
50
|
return __state_js.buildRowComparator;
|
|
56
51
|
}
|
|
57
52
|
});
|
|
58
|
-
Object.defineProperty(exports, '
|
|
53
|
+
Object.defineProperty(exports, 'clampColumnWidth', {
|
|
59
54
|
enumerable: true,
|
|
60
55
|
get: function () {
|
|
61
|
-
return
|
|
56
|
+
return __data_grid_sizing_js.clampColumnWidth;
|
|
62
57
|
}
|
|
63
58
|
});
|
|
64
59
|
Object.defineProperty(exports, 'createDefaultDataGridState', {
|
|
@@ -103,34 +98,16 @@ Object.defineProperty(exports, 'formatGridDate', {
|
|
|
103
98
|
return __state_js.formatGridDate;
|
|
104
99
|
}
|
|
105
100
|
});
|
|
106
|
-
Object.defineProperty(exports, '
|
|
107
|
-
enumerable: true,
|
|
108
|
-
get: function () {
|
|
109
|
-
return __data_grid_sizing_js.getEffectiveMinWidth;
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
Object.defineProperty(exports, 'getSortDirection', {
|
|
113
|
-
enumerable: true,
|
|
114
|
-
get: function () {
|
|
115
|
-
return __state_js.getSortDirection;
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
Object.defineProperty(exports, 'getSortIndex', {
|
|
119
|
-
enumerable: true,
|
|
120
|
-
get: function () {
|
|
121
|
-
return __state_js.getSortIndex;
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
Object.defineProperty(exports, 'getTotalPages', {
|
|
101
|
+
Object.defineProperty(exports, 'getEffectiveMaxWidth', {
|
|
125
102
|
enumerable: true,
|
|
126
103
|
get: function () {
|
|
127
|
-
return
|
|
104
|
+
return __data_grid_sizing_js.getEffectiveMaxWidth;
|
|
128
105
|
}
|
|
129
106
|
});
|
|
130
|
-
Object.defineProperty(exports, '
|
|
107
|
+
Object.defineProperty(exports, 'getEffectiveMinWidth', {
|
|
131
108
|
enumerable: true,
|
|
132
109
|
get: function () {
|
|
133
|
-
return
|
|
110
|
+
return __data_grid_sizing_js.getEffectiveMinWidth;
|
|
134
111
|
}
|
|
135
112
|
});
|
|
136
113
|
Object.defineProperty(exports, 'isDataGridInteractiveRowClickTarget', {
|
|
@@ -151,34 +128,16 @@ Object.defineProperty(exports, 'resolveColumnValue', {
|
|
|
151
128
|
return __state_js.resolveColumnValue;
|
|
152
129
|
}
|
|
153
130
|
});
|
|
154
|
-
Object.defineProperty(exports, 'resolveColumnWidth', {
|
|
155
|
-
enumerable: true,
|
|
156
|
-
get: function () {
|
|
157
|
-
return __state_js.resolveColumnWidth;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
131
|
Object.defineProperty(exports, 'resolveDataGridStrings', {
|
|
161
132
|
enumerable: true,
|
|
162
133
|
get: function () {
|
|
163
134
|
return __strings_js.resolveDataGridStrings;
|
|
164
135
|
}
|
|
165
136
|
});
|
|
166
|
-
Object.defineProperty(exports, '
|
|
167
|
-
enumerable: true,
|
|
168
|
-
get: function () {
|
|
169
|
-
return __state_js.selectAll;
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
Object.defineProperty(exports, 'toggleRowSelection', {
|
|
173
|
-
enumerable: true,
|
|
174
|
-
get: function () {
|
|
175
|
-
return __state_js.toggleRowSelection;
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
Object.defineProperty(exports, 'toggleSort', {
|
|
137
|
+
Object.defineProperty(exports, 'useDataGridUrlState', {
|
|
179
138
|
enumerable: true,
|
|
180
139
|
get: function () {
|
|
181
|
-
return
|
|
140
|
+
return __use_url_state_js.useDataGridUrlState;
|
|
182
141
|
}
|
|
183
142
|
});
|
|
184
143
|
Object.defineProperty(exports, 'useDataSource', {
|
|
@@ -1,83 +1,26 @@
|
|
|
1
|
-
import { DataGridColumnDef, DataGridDateDisplay, DataGridDateFormat, DataGridPaginationModel,
|
|
1
|
+
import { DataGridColumnDef, DataGridDateDisplay, DataGridDateFormat, DataGridPaginationModel, DataGridSortModel, DataGridState } from "./types.js";
|
|
2
2
|
|
|
3
3
|
//#region src/components/data-grid/state.d.ts
|
|
4
|
-
declare const EMPTY_SORT_MODEL: DataGridSortModel;
|
|
5
|
-
declare const EMPTY_SELECTION: DataGridSelectionModel;
|
|
6
|
-
declare const DEFAULT_PAGINATION: DataGridPaginationModel;
|
|
7
4
|
/**
|
|
8
5
|
* Build the initial `DataGridState` for a set of columns. Pass this as the
|
|
9
|
-
* lazy initializer to `useState` —
|
|
6
|
+
* lazy initializer to `useState` — never hand-assemble the state object.
|
|
10
7
|
*
|
|
11
8
|
* ```tsx
|
|
12
9
|
* const [gridState, setGridState] = React.useState(() =>
|
|
13
10
|
* createDefaultDataGridState(columns)
|
|
14
11
|
* );
|
|
15
12
|
* ```
|
|
16
|
-
*
|
|
17
|
-
* `columns` must be defined BEFORE this call (obvious, but a common TDZ
|
|
18
|
-
* mistake: if you declare columns after the `useState`, you'll crash on
|
|
19
|
-
* the first render). Keep the columns reference stable across renders
|
|
20
|
-
* (define them outside the component or wrap in `React.useMemo`).
|
|
21
13
|
*/
|
|
22
14
|
declare function createDefaultDataGridState(columns: readonly DataGridColumnDef<any>[]): DataGridState;
|
|
23
15
|
declare function resolveColumnValue<TRow>(col: DataGridColumnDef<TRow>, row: TRow): unknown;
|
|
24
|
-
declare function resolveColumnWidth(col: DataGridColumnDef<any>, storedWidth: number | undefined): number;
|
|
25
|
-
declare function isColumnVisible(columnId: string, visibility: Record<string, boolean>): boolean;
|
|
26
|
-
declare function toggleSort(model: DataGridSortModel, columnId: string, multiSort: boolean): DataGridSortModel;
|
|
27
|
-
declare function getSortDirection(model: DataGridSortModel, columnId: string): false | "asc" | "desc";
|
|
28
|
-
declare function getSortIndex(model: DataGridSortModel, columnId: string): number | null;
|
|
29
16
|
declare function buildRowComparator<TRow>(sortModel: DataGridSortModel, columns: readonly DataGridColumnDef<TRow>[]): ((a: TRow, b: TRow) => number) | null;
|
|
30
17
|
declare function paginateRows<TRow>(rows: readonly TRow[], pagination: DataGridPaginationModel): TRow[];
|
|
31
|
-
|
|
32
|
-
declare function toggleRowSelection(selection: DataGridSelectionModel, rowId: string, mode: "single" | "multiple", shiftKey: boolean, ctrlKey: boolean, allRowIds: readonly string[]): DataGridSelectionModel;
|
|
33
|
-
declare function selectAll(allRowIds: readonly string[]): DataGridSelectionModel;
|
|
34
|
-
declare function clearSelection(): DataGridSelectionModel;
|
|
35
|
-
/** Default row matcher used by `applyQuickSearch`. Case-insensitive
|
|
36
|
-
* substring match across every column's resolved cell value. Columns
|
|
37
|
-
* with `null` / `undefined` values are skipped. The query is expected
|
|
38
|
-
* to be pre-trimmed and lowercased by `applyQuickSearch` — this helper
|
|
39
|
-
* does NOT trim or lowercase it again, so if you wire it up yourself,
|
|
40
|
-
* do that first. */
|
|
18
|
+
/** Default row matcher: case-insensitive substring across every column. */
|
|
41
19
|
declare function defaultMatchRow<TRow>(row: TRow, query: string, columns: readonly DataGridColumnDef<TRow>[]): boolean;
|
|
42
|
-
/** Client-side quick-search filter. Returns the original array
|
|
43
|
-
* reference when `query` is empty, so calling this in a hot `useMemo`
|
|
44
|
-
* is cheap in the common "no search" case.
|
|
45
|
-
*
|
|
46
|
-
* Used by `useDataSource` in client mode. Exported so consumers driving
|
|
47
|
-
* the grid manually (or doing their own pre-filtering before feeding
|
|
48
|
-
* rows to an async data source) can stay consistent with the built-in
|
|
49
|
-
* search behaviour.
|
|
50
|
-
*
|
|
51
|
-
* Override `matchRow` for custom matching logic — e.g. fuzzy matching,
|
|
52
|
-
* field-specific weighting, or skipping some columns. */
|
|
53
20
|
declare function applyQuickSearch<TRow>(rows: readonly TRow[], query: string, columns: readonly DataGridColumnDef<TRow>[], matchRow?: (row: TRow, query: string, columns: readonly DataGridColumnDef<TRow>[]) => boolean): readonly TRow[];
|
|
54
|
-
/** Parse a raw cell value into a `Date`. Returns `null` for nullish,
|
|
55
|
-
* unparseable, or invalid dates. Accepts strings (including ISO and
|
|
56
|
-
* "YYYY-MM-DD HH:MM:SS"-style ClickHouse output), numbers (ms since
|
|
57
|
-
* epoch), and `Date` instances. For truly weird formats, override via
|
|
58
|
-
* `col.parseValue`. */
|
|
59
21
|
declare function defaultParseDate(value: unknown): Date | null;
|
|
60
|
-
/** Default relative formatter — "1 day ago" / "in 2 hours" via
|
|
61
|
-
* `Intl.RelativeTimeFormat`. Pure function of the date; does NOT
|
|
62
|
-
* re-render as real time passes. */
|
|
63
22
|
declare function defaultFormatRelative(date: Date): string;
|
|
64
|
-
/** Default absolute formatter — full locale date + time. */
|
|
65
23
|
declare function defaultFormatAbsolute(date: Date): string;
|
|
66
|
-
/** Format a raw cell value for display in a `date` / `dateTime` column.
|
|
67
|
-
* Returns both the inline display string and the tooltip string (which
|
|
68
|
-
* is always the absolute form so users can read the exact datetime).
|
|
69
|
-
*
|
|
70
|
-
* Used internally by the grid's default date cell renderer, and exported
|
|
71
|
-
* so consumers writing a custom `renderCell` for a date column can stay
|
|
72
|
-
* visually consistent with the built-in behaviour.
|
|
73
|
-
*
|
|
74
|
-
* ```tsx
|
|
75
|
-
* renderCell: ({ value, dateDisplay }) => {
|
|
76
|
-
* const { display, tooltip } = formatGridDate(value, dateDisplay);
|
|
77
|
-
* if (!display) return <span className="text-muted-foreground/40">—</span>;
|
|
78
|
-
* return <span title={tooltip ?? undefined}>{display}</span>;
|
|
79
|
-
* }
|
|
80
|
-
* ``` */
|
|
81
24
|
declare function formatGridDate(value: unknown, mode: DataGridDateDisplay, opts?: {
|
|
82
25
|
parseValue?: (value: unknown) => Date | null;
|
|
83
26
|
dateFormat?: DataGridDateFormat;
|
|
@@ -87,5 +30,5 @@ declare function formatGridDate(value: unknown, mode: DataGridDateDisplay, opts?
|
|
|
87
30
|
};
|
|
88
31
|
declare function exportToCsv<TRow>(rows: readonly TRow[], columns: readonly DataGridColumnDef<TRow>[], filename: string): void;
|
|
89
32
|
//#endregion
|
|
90
|
-
export {
|
|
33
|
+
export { applyQuickSearch, buildRowComparator, createDefaultDataGridState, defaultFormatAbsolute, defaultFormatRelative, defaultMatchRow, defaultParseDate, exportToCsv, formatGridDate, paginateRows, resolveColumnValue };
|
|
91
34
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","names":[],"sources":["../../../src/components/data-grid/state.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.d.ts","names":[],"sources":["../../../src/components/data-grid/state.ts"],"mappings":";;;;;AAqBA;;;;;;;;iBAAgB,0BAAA,CACd,OAAA,WAAkB,iBAAA,UACjB,aAAA;AAAA,iBAwBa,kBAAA,MAAA,CACd,GAAA,EAAK,iBAAA,CAAkB,IAAA,GACvB,GAAA,EAAK,IAAA;AAAA,iBAkBS,kBAAA,MAAA,CACd,SAAA,EAAW,iBAAA,EACX,OAAA,WAAkB,iBAAA,CAAkB,IAAA,QACjC,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA;AAAA,iBAkBD,YAAA,MAAA,CACd,IAAA,WAAe,IAAA,IACf,UAAA,EAAY,uBAAA,GACX,IAAA;;iBAQa,eAAA,MAAA,CACd,GAAA,EAAK,IAAA,EACL,KAAA,UACA,OAAA,WAAkB,iBAAA,CAAkB,IAAA;AAAA,iBAUtB,gBAAA,MAAA,CACd,IAAA,WAAe,IAAA,IACf,KAAA,UACA,OAAA,WAAkB,iBAAA,CAAkB,IAAA,KACpC,QAAA,IACE,GAAA,EAAK,IAAA,EACL,KAAA,UACA,OAAA,WAAkB,iBAAA,CAAkB,IAAA,2BAE5B,IAAA;AAAA,iBAQI,gBAAA,CAAiB,KAAA,YAAiB,IAAA;AAAA,iBA+BlC,qBAAA,CAAsB,IAAA,EAAM,IAAA;AAAA,iBAY5B,qBAAA,CAAsB,IAAA,EAAM,IAAA;AAAA,iBAI5B,cAAA,CACd,KAAA,WACA,IAAA,EAAM,mBAAA,EACN,IAAA;EACE,UAAA,IAAc,KAAA,cAAmB,IAAA;EACjC,UAAA,GAAa,kBAAA;AAAA;EAEZ,OAAA;EAAwB,OAAA;AAAA;AAAA,iBAab,WAAA,MAAA,CACd,IAAA,WAAe,IAAA,IACf,OAAA,WAAkB,iBAAA,CAAkB,IAAA,KACpC,QAAA"}
|
|
@@ -4,40 +4,25 @@ let __data_grid_sizing_js = require("./data-grid-sizing.js");
|
|
|
4
4
|
let _stackframe_stack_shared_dist_utils_strings = require("@stackframe/stack-shared/dist/utils/strings");
|
|
5
5
|
|
|
6
6
|
//#region src/components/data-grid/state.ts
|
|
7
|
-
const EMPTY_SORT_MODEL = [];
|
|
8
|
-
const EMPTY_SELECTION = {
|
|
9
|
-
selectedIds: /* @__PURE__ */ new Set(),
|
|
10
|
-
anchorId: null
|
|
11
|
-
};
|
|
12
|
-
const DEFAULT_PAGINATION = {
|
|
13
|
-
pageIndex: 0,
|
|
14
|
-
pageSize: 50
|
|
15
|
-
};
|
|
16
7
|
/**
|
|
17
8
|
* Build the initial `DataGridState` for a set of columns. Pass this as the
|
|
18
|
-
* lazy initializer to `useState` —
|
|
9
|
+
* lazy initializer to `useState` — never hand-assemble the state object.
|
|
19
10
|
*
|
|
20
11
|
* ```tsx
|
|
21
12
|
* const [gridState, setGridState] = React.useState(() =>
|
|
22
13
|
* createDefaultDataGridState(columns)
|
|
23
14
|
* );
|
|
24
15
|
* ```
|
|
25
|
-
*
|
|
26
|
-
* `columns` must be defined BEFORE this call (obvious, but a common TDZ
|
|
27
|
-
* mistake: if you declare columns after the `useState`, you'll crash on
|
|
28
|
-
* the first render). Keep the columns reference stable across renders
|
|
29
|
-
* (define them outside the component or wrap in `React.useMemo`).
|
|
30
16
|
*/
|
|
31
17
|
function createDefaultDataGridState(columns) {
|
|
32
18
|
const columnWidths = {};
|
|
33
19
|
const columnOrder = [];
|
|
34
20
|
for (const col of columns) {
|
|
35
|
-
|
|
36
|
-
columnWidths[col.id] = (0, __data_grid_sizing_js.clampColumnWidth)(col, raw);
|
|
21
|
+
columnWidths[col.id] = (0, __data_grid_sizing_js.clampColumnWidth)(col, col.width ?? __data_grid_sizing_js.DEFAULT_COL_WIDTH);
|
|
37
22
|
columnOrder.push(col.id);
|
|
38
23
|
}
|
|
39
24
|
return {
|
|
40
|
-
sorting:
|
|
25
|
+
sorting: [],
|
|
41
26
|
columnVisibility: {},
|
|
42
27
|
columnWidths,
|
|
43
28
|
columnPinning: {
|
|
@@ -45,8 +30,14 @@ function createDefaultDataGridState(columns) {
|
|
|
45
30
|
right: []
|
|
46
31
|
},
|
|
47
32
|
columnOrder,
|
|
48
|
-
pagination:
|
|
49
|
-
|
|
33
|
+
pagination: {
|
|
34
|
+
pageIndex: 0,
|
|
35
|
+
pageSize: 50
|
|
36
|
+
},
|
|
37
|
+
selection: {
|
|
38
|
+
selectedIds: /* @__PURE__ */ new Set(),
|
|
39
|
+
anchorId: null
|
|
40
|
+
},
|
|
50
41
|
dateDisplay: "relative",
|
|
51
42
|
quickSearch: ""
|
|
52
43
|
};
|
|
@@ -55,39 +46,6 @@ function resolveColumnValue(col, row) {
|
|
|
55
46
|
if (typeof col.accessor === "function") return col.accessor(row);
|
|
56
47
|
return row[col.accessor ?? col.id];
|
|
57
48
|
}
|
|
58
|
-
function resolveColumnWidth(col, storedWidth) {
|
|
59
|
-
return (0, __data_grid_sizing_js.clampColumnWidth)(col, storedWidth ?? col.width ?? 150);
|
|
60
|
-
}
|
|
61
|
-
function isColumnVisible(columnId, visibility) {
|
|
62
|
-
return visibility[columnId] !== false;
|
|
63
|
-
}
|
|
64
|
-
function toggleSort(model, columnId, multiSort) {
|
|
65
|
-
const existing = model.find((s) => s.columnId === columnId);
|
|
66
|
-
if (!existing) {
|
|
67
|
-
const item = {
|
|
68
|
-
columnId,
|
|
69
|
-
direction: "asc"
|
|
70
|
-
};
|
|
71
|
-
return multiSort ? [...model, item] : [item];
|
|
72
|
-
}
|
|
73
|
-
if (existing.direction === "asc") {
|
|
74
|
-
const updated = {
|
|
75
|
-
columnId,
|
|
76
|
-
direction: "desc"
|
|
77
|
-
};
|
|
78
|
-
return model.map((s) => s.columnId === columnId ? updated : s);
|
|
79
|
-
}
|
|
80
|
-
return model.filter((s) => s.columnId !== columnId);
|
|
81
|
-
}
|
|
82
|
-
function getSortDirection(model, columnId) {
|
|
83
|
-
const item = model.find((s) => s.columnId === columnId);
|
|
84
|
-
return item ? item.direction : false;
|
|
85
|
-
}
|
|
86
|
-
function getSortIndex(model, columnId) {
|
|
87
|
-
if (model.length <= 1) return null;
|
|
88
|
-
const idx = model.findIndex((s) => s.columnId === columnId);
|
|
89
|
-
return idx >= 0 ? idx + 1 : null;
|
|
90
|
-
}
|
|
91
49
|
function defaultComparator(a, b) {
|
|
92
50
|
if (a == null && b == null) return 0;
|
|
93
51
|
if (a == null) return -1;
|
|
@@ -115,61 +73,7 @@ function paginateRows(rows, pagination) {
|
|
|
115
73
|
const start = pagination.pageIndex * pagination.pageSize;
|
|
116
74
|
return rows.slice(start, start + pagination.pageSize);
|
|
117
75
|
}
|
|
118
|
-
|
|
119
|
-
return Math.max(1, Math.ceil(totalRows / pageSize));
|
|
120
|
-
}
|
|
121
|
-
function toggleRowSelection(selection, rowId, mode, shiftKey, ctrlKey, allRowIds) {
|
|
122
|
-
if (mode === "single") {
|
|
123
|
-
const isSelected = selection.selectedIds.has(rowId);
|
|
124
|
-
return {
|
|
125
|
-
selectedIds: isSelected ? /* @__PURE__ */ new Set() : new Set([rowId]),
|
|
126
|
-
anchorId: isSelected ? null : rowId
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
if (shiftKey && selection.anchorId != null) {
|
|
130
|
-
const anchorIdx = allRowIds.indexOf(selection.anchorId);
|
|
131
|
-
const currentIdx = allRowIds.indexOf(rowId);
|
|
132
|
-
if (anchorIdx >= 0 && currentIdx >= 0) {
|
|
133
|
-
const start = Math.min(anchorIdx, currentIdx);
|
|
134
|
-
const end = Math.max(anchorIdx, currentIdx);
|
|
135
|
-
const rangeIds = allRowIds.slice(start, end + 1);
|
|
136
|
-
const next = ctrlKey ? new Set(selection.selectedIds) : /* @__PURE__ */ new Set();
|
|
137
|
-
for (const id of rangeIds) next.add(id);
|
|
138
|
-
return {
|
|
139
|
-
selectedIds: next,
|
|
140
|
-
anchorId: selection.anchorId
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (ctrlKey) {
|
|
145
|
-
const next = new Set(selection.selectedIds);
|
|
146
|
-
if (next.has(rowId)) next.delete(rowId);
|
|
147
|
-
else next.add(rowId);
|
|
148
|
-
return {
|
|
149
|
-
selectedIds: next,
|
|
150
|
-
anchorId: rowId
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
selectedIds: new Set([rowId]),
|
|
155
|
-
anchorId: rowId
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function selectAll(allRowIds) {
|
|
159
|
-
return {
|
|
160
|
-
selectedIds: new Set(allRowIds),
|
|
161
|
-
anchorId: null
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function clearSelection() {
|
|
165
|
-
return EMPTY_SELECTION;
|
|
166
|
-
}
|
|
167
|
-
/** Default row matcher used by `applyQuickSearch`. Case-insensitive
|
|
168
|
-
* substring match across every column's resolved cell value. Columns
|
|
169
|
-
* with `null` / `undefined` values are skipped. The query is expected
|
|
170
|
-
* to be pre-trimmed and lowercased by `applyQuickSearch` — this helper
|
|
171
|
-
* does NOT trim or lowercase it again, so if you wire it up yourself,
|
|
172
|
-
* do that first. */
|
|
76
|
+
/** Default row matcher: case-insensitive substring across every column. */
|
|
173
77
|
function defaultMatchRow(row, query, columns) {
|
|
174
78
|
for (const col of columns) {
|
|
175
79
|
const v = resolveColumnValue(col, row);
|
|
@@ -178,35 +82,15 @@ function defaultMatchRow(row, query, columns) {
|
|
|
178
82
|
}
|
|
179
83
|
return false;
|
|
180
84
|
}
|
|
181
|
-
/** Client-side quick-search filter. Returns the original array
|
|
182
|
-
* reference when `query` is empty, so calling this in a hot `useMemo`
|
|
183
|
-
* is cheap in the common "no search" case.
|
|
184
|
-
*
|
|
185
|
-
* Used by `useDataSource` in client mode. Exported so consumers driving
|
|
186
|
-
* the grid manually (or doing their own pre-filtering before feeding
|
|
187
|
-
* rows to an async data source) can stay consistent with the built-in
|
|
188
|
-
* search behaviour.
|
|
189
|
-
*
|
|
190
|
-
* Override `matchRow` for custom matching logic — e.g. fuzzy matching,
|
|
191
|
-
* field-specific weighting, or skipping some columns. */
|
|
192
85
|
function applyQuickSearch(rows, query, columns, matchRow = defaultMatchRow) {
|
|
193
86
|
const trimmed = query.trim().toLowerCase();
|
|
194
87
|
if (!trimmed) return rows;
|
|
195
88
|
return rows.filter((r) => matchRow(r, trimmed, columns));
|
|
196
89
|
}
|
|
197
|
-
/** Parse a raw cell value into a `Date`. Returns `null` for nullish,
|
|
198
|
-
* unparseable, or invalid dates. Accepts strings (including ISO and
|
|
199
|
-
* "YYYY-MM-DD HH:MM:SS"-style ClickHouse output), numbers (ms since
|
|
200
|
-
* epoch), and `Date` instances. For truly weird formats, override via
|
|
201
|
-
* `col.parseValue`. */
|
|
202
90
|
function defaultParseDate(value) {
|
|
203
91
|
if (value == null) return null;
|
|
204
92
|
if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
|
|
205
|
-
if (typeof value === "number") {
|
|
206
|
-
const d = new Date(value);
|
|
207
|
-
return isNaN(d.getTime()) ? null : d;
|
|
208
|
-
}
|
|
209
|
-
if (typeof value === "string") {
|
|
93
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
210
94
|
const d = new Date(value);
|
|
211
95
|
return isNaN(d.getTime()) ? null : d;
|
|
212
96
|
}
|
|
@@ -252,9 +136,6 @@ function getRelativeTimeFormatter(locale) {
|
|
|
252
136
|
}
|
|
253
137
|
return cached;
|
|
254
138
|
}
|
|
255
|
-
/** Default relative formatter — "1 day ago" / "in 2 hours" via
|
|
256
|
-
* `Intl.RelativeTimeFormat`. Pure function of the date; does NOT
|
|
257
|
-
* re-render as real time passes. */
|
|
258
139
|
function defaultFormatRelative(date) {
|
|
259
140
|
const rtf = getRelativeTimeFormatter();
|
|
260
141
|
let duration = (date.getTime() - Date.now()) / 1e3;
|
|
@@ -264,25 +145,9 @@ function defaultFormatRelative(date) {
|
|
|
264
145
|
}
|
|
265
146
|
return rtf.format(Math.round(duration), "year");
|
|
266
147
|
}
|
|
267
|
-
/** Default absolute formatter — full locale date + time. */
|
|
268
148
|
function defaultFormatAbsolute(date) {
|
|
269
149
|
return date.toLocaleString();
|
|
270
150
|
}
|
|
271
|
-
/** Format a raw cell value for display in a `date` / `dateTime` column.
|
|
272
|
-
* Returns both the inline display string and the tooltip string (which
|
|
273
|
-
* is always the absolute form so users can read the exact datetime).
|
|
274
|
-
*
|
|
275
|
-
* Used internally by the grid's default date cell renderer, and exported
|
|
276
|
-
* so consumers writing a custom `renderCell` for a date column can stay
|
|
277
|
-
* visually consistent with the built-in behaviour.
|
|
278
|
-
*
|
|
279
|
-
* ```tsx
|
|
280
|
-
* renderCell: ({ value, dateDisplay }) => {
|
|
281
|
-
* const { display, tooltip } = formatGridDate(value, dateDisplay);
|
|
282
|
-
* if (!display) return <span className="text-muted-foreground/40">—</span>;
|
|
283
|
-
* return <span title={tooltip ?? undefined}>{display}</span>;
|
|
284
|
-
* }
|
|
285
|
-
* ``` */
|
|
286
151
|
function formatGridDate(value, mode, opts) {
|
|
287
152
|
const date = (opts?.parseValue ?? defaultParseDate)(value);
|
|
288
153
|
if (!date) return {
|
|
@@ -320,12 +185,8 @@ function exportToCsv(rows, columns, filename) {
|
|
|
320
185
|
}
|
|
321
186
|
|
|
322
187
|
//#endregion
|
|
323
|
-
exports.DEFAULT_PAGINATION = DEFAULT_PAGINATION;
|
|
324
|
-
exports.EMPTY_SELECTION = EMPTY_SELECTION;
|
|
325
|
-
exports.EMPTY_SORT_MODEL = EMPTY_SORT_MODEL;
|
|
326
188
|
exports.applyQuickSearch = applyQuickSearch;
|
|
327
189
|
exports.buildRowComparator = buildRowComparator;
|
|
328
|
-
exports.clearSelection = clearSelection;
|
|
329
190
|
exports.createDefaultDataGridState = createDefaultDataGridState;
|
|
330
191
|
exports.defaultFormatAbsolute = defaultFormatAbsolute;
|
|
331
192
|
exports.defaultFormatRelative = defaultFormatRelative;
|
|
@@ -333,14 +194,6 @@ exports.defaultMatchRow = defaultMatchRow;
|
|
|
333
194
|
exports.defaultParseDate = defaultParseDate;
|
|
334
195
|
exports.exportToCsv = exportToCsv;
|
|
335
196
|
exports.formatGridDate = formatGridDate;
|
|
336
|
-
exports.getSortDirection = getSortDirection;
|
|
337
|
-
exports.getSortIndex = getSortIndex;
|
|
338
|
-
exports.getTotalPages = getTotalPages;
|
|
339
|
-
exports.isColumnVisible = isColumnVisible;
|
|
340
197
|
exports.paginateRows = paginateRows;
|
|
341
198
|
exports.resolveColumnValue = resolveColumnValue;
|
|
342
|
-
exports.resolveColumnWidth = resolveColumnWidth;
|
|
343
|
-
exports.selectAll = selectAll;
|
|
344
|
-
exports.toggleRowSelection = toggleRowSelection;
|
|
345
|
-
exports.toggleSort = toggleSort;
|
|
346
199
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","names":[],"sources":["../../../src/components/data-grid/state.ts"],"sourcesContent":["import { stringCompare } from \"@stackframe/stack-shared/dist/utils/strings\";\nimport { clampColumnWidth } from \"./data-grid-sizing\";\nimport type {\n DataGridColumnDef,\n DataGridDateDisplay,\n DataGridDateFormat,\n DataGridPaginationModel,\n DataGridSelectionModel,\n DataGridSortModel,\n DataGridState,\n} from \"./types\";\n\n// ─── Default state ───────────────────────────────────────────────────\n\nexport const EMPTY_SORT_MODEL: DataGridSortModel = [];\nexport const EMPTY_SELECTION: DataGridSelectionModel = {\n selectedIds: new Set(),\n anchorId: null,\n};\nexport const DEFAULT_PAGINATION: DataGridPaginationModel = {\n pageIndex: 0,\n pageSize: 50,\n};\n\n/**\n * Build the initial `DataGridState` for a set of columns. Pass this as the\n * lazy initializer to `useState` — NEVER hand-assemble the state object.\n *\n * ```tsx\n * const [gridState, setGridState] = React.useState(() =>\n * createDefaultDataGridState(columns)\n * );\n * ```\n *\n * `columns` must be defined BEFORE this call (obvious, but a common TDZ\n * mistake: if you declare columns after the `useState`, you'll crash on\n * the first render). Keep the columns reference stable across renders\n * (define them outside the component or wrap in `React.useMemo`).\n */\nexport function createDefaultDataGridState(\n columns: readonly DataGridColumnDef<any>[],\n): DataGridState {\n const columnWidths: Record<string, number> = {};\n const columnOrder: string[] = [];\n\n for (const col of columns) {\n const raw = col.width ?? 150;\n columnWidths[col.id] = clampColumnWidth(col, raw);\n columnOrder.push(col.id);\n }\n\n return {\n sorting: EMPTY_SORT_MODEL,\n columnVisibility: {},\n columnWidths,\n columnPinning: { left: [], right: [] },\n columnOrder,\n pagination: DEFAULT_PAGINATION,\n selection: EMPTY_SELECTION,\n dateDisplay: \"relative\",\n quickSearch: \"\",\n };\n}\n\n// ─── Column helpers ──────────────────────────────────────────────────\n\nexport function resolveColumnValue<TRow>(\n col: DataGridColumnDef<TRow>,\n row: TRow,\n): unknown {\n if (typeof col.accessor === \"function\") return col.accessor(row);\n const key = (col.accessor ?? col.id) as keyof TRow;\n return row[key];\n}\n\nexport function resolveColumnWidth(\n col: DataGridColumnDef<any>,\n storedWidth: number | undefined,\n): number {\n const raw = storedWidth ?? col.width ?? 150;\n return clampColumnWidth(col, raw);\n}\n\nexport function isColumnVisible(\n columnId: string,\n visibility: Record<string, boolean>,\n): boolean {\n return visibility[columnId] !== false;\n}\n\n// ─── Sort helpers ────────────────────────────────────────────────────\n\nexport function toggleSort(\n model: DataGridSortModel,\n columnId: string,\n multiSort: boolean,\n): DataGridSortModel {\n const existing = model.find((s) => s.columnId === columnId);\n\n if (!existing) {\n const item = { columnId, direction: \"asc\" as const };\n return multiSort ? [...model, item] : [item];\n }\n\n if (existing.direction === \"asc\") {\n const updated = { columnId, direction: \"desc\" as const };\n return model.map((s) => (s.columnId === columnId ? updated : s));\n }\n\n // desc → remove\n return model.filter((s) => s.columnId !== columnId);\n}\n\nexport function getSortDirection(\n model: DataGridSortModel,\n columnId: string,\n): false | \"asc\" | \"desc\" {\n const item = model.find((s) => s.columnId === columnId);\n return item ? item.direction : false;\n}\n\nexport function getSortIndex(\n model: DataGridSortModel,\n columnId: string,\n): number | null {\n if (model.length <= 1) return null;\n const idx = model.findIndex((s) => s.columnId === columnId);\n return idx >= 0 ? idx + 1 : null;\n}\n\n// ─── Default sort comparator ─────────────────────────────────────────\n\nfunction defaultComparator(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n return stringCompare(String(a), String(b));\n}\n\nexport function buildRowComparator<TRow>(\n sortModel: DataGridSortModel,\n columns: readonly DataGridColumnDef<TRow>[],\n): ((a: TRow, b: TRow) => number) | null {\n if (sortModel.length === 0) return null;\n\n const colMap = new Map(columns.map((c) => [c.id, c]));\n\n return (a, b) => {\n for (const { columnId, direction } of sortModel) {\n const col = colMap.get(columnId);\n if (!col) continue;\n\n const va = resolveColumnValue(col, a);\n const vb = resolveColumnValue(col, b);\n const cmp = col.sortComparator\n ? col.sortComparator(va, vb)\n : defaultComparator(va, vb);\n if (cmp !== 0) return direction === \"asc\" ? cmp : -cmp;\n }\n return 0;\n };\n}\n\n// ─── Pagination helpers ──────────────────────────────────────────────\n\nexport function paginateRows<TRow>(\n rows: readonly TRow[],\n pagination: DataGridPaginationModel,\n): TRow[] {\n const start = pagination.pageIndex * pagination.pageSize;\n return rows.slice(start, start + pagination.pageSize) as TRow[];\n}\n\nexport function getTotalPages(\n totalRows: number,\n pageSize: number,\n): number {\n return Math.max(1, Math.ceil(totalRows / pageSize));\n}\n\n// ─── Selection helpers ───────────────────────────────────────────────\n\nexport function toggleRowSelection(\n selection: DataGridSelectionModel,\n rowId: string,\n mode: \"single\" | \"multiple\",\n shiftKey: boolean,\n ctrlKey: boolean,\n allRowIds: readonly string[],\n): DataGridSelectionModel {\n if (mode === \"single\") {\n const isSelected = selection.selectedIds.has(rowId);\n return {\n selectedIds: isSelected ? new Set() : new Set([rowId]),\n anchorId: isSelected ? null : rowId,\n };\n }\n\n // Multiple mode\n if (shiftKey && selection.anchorId != null) {\n const anchorIdx = allRowIds.indexOf(selection.anchorId);\n const currentIdx = allRowIds.indexOf(rowId);\n if (anchorIdx >= 0 && currentIdx >= 0) {\n const start = Math.min(anchorIdx, currentIdx);\n const end = Math.max(anchorIdx, currentIdx);\n const rangeIds = allRowIds.slice(start, end + 1);\n\n const next = ctrlKey ? new Set(selection.selectedIds) : new Set<string>();\n for (const id of rangeIds) next.add(id);\n\n return { selectedIds: next, anchorId: selection.anchorId };\n }\n }\n\n if (ctrlKey) {\n // Toggle single in multi mode\n const next = new Set(selection.selectedIds);\n if (next.has(rowId)) {\n next.delete(rowId);\n } else {\n next.add(rowId);\n }\n return { selectedIds: next, anchorId: rowId };\n }\n\n // Plain click in multi mode — select only this row\n return {\n selectedIds: new Set([rowId]),\n anchorId: rowId,\n };\n}\n\nexport function selectAll(\n allRowIds: readonly string[],\n): DataGridSelectionModel {\n return {\n selectedIds: new Set(allRowIds),\n anchorId: null,\n };\n}\n\nexport function clearSelection(): DataGridSelectionModel {\n return EMPTY_SELECTION;\n}\n\n// ─── Quick search ────────────────────────────────────────────────────\n\n/** Default row matcher used by `applyQuickSearch`. Case-insensitive\n * substring match across every column's resolved cell value. Columns\n * with `null` / `undefined` values are skipped. The query is expected\n * to be pre-trimmed and lowercased by `applyQuickSearch` — this helper\n * does NOT trim or lowercase it again, so if you wire it up yourself,\n * do that first. */\nexport function defaultMatchRow<TRow>(\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n): boolean {\n for (const col of columns) {\n const v = resolveColumnValue(col, row);\n if (v == null) continue;\n if (String(v).toLowerCase().includes(query)) return true;\n }\n return false;\n}\n\n/** Client-side quick-search filter. Returns the original array\n * reference when `query` is empty, so calling this in a hot `useMemo`\n * is cheap in the common \"no search\" case.\n *\n * Used by `useDataSource` in client mode. Exported so consumers driving\n * the grid manually (or doing their own pre-filtering before feeding\n * rows to an async data source) can stay consistent with the built-in\n * search behaviour.\n *\n * Override `matchRow` for custom matching logic — e.g. fuzzy matching,\n * field-specific weighting, or skipping some columns. */\nexport function applyQuickSearch<TRow>(\n rows: readonly TRow[],\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n matchRow: (\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n ) => boolean = defaultMatchRow,\n): readonly TRow[] {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) return rows;\n return rows.filter((r) => matchRow(r, trimmed, columns));\n}\n\n// ─── Date helpers ────────────────────────────────────────────────────\n\n/** Parse a raw cell value into a `Date`. Returns `null` for nullish,\n * unparseable, or invalid dates. Accepts strings (including ISO and\n * \"YYYY-MM-DD HH:MM:SS\"-style ClickHouse output), numbers (ms since\n * epoch), and `Date` instances. For truly weird formats, override via\n * `col.parseValue`. */\nexport function defaultParseDate(value: unknown): Date | null {\n if (value == null) return null;\n if (value instanceof Date) return isNaN(value.getTime()) ? null : value;\n if (typeof value === \"number\") {\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === \"string\") {\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d;\n }\n return null;\n}\n\nconst DIVISIONS: Array<{ amount: number; unit: Intl.RelativeTimeFormatUnit }> = [\n { amount: 60, unit: \"second\" },\n { amount: 60, unit: \"minute\" },\n { amount: 24, unit: \"hour\" },\n { amount: 7, unit: \"day\" },\n { amount: 4.34524, unit: \"week\" },\n { amount: 12, unit: \"month\" },\n { amount: Number.POSITIVE_INFINITY, unit: \"year\" },\n];\n\n// Memoized per-locale formatter. `Intl.RelativeTimeFormat` construction\n// shows up as a real cost in flamegraphs for grids with many date cells,\n// so cache one instance per locale (\"undefined\" = default).\nconst relativeTimeFormatterCache = new Map<string, Intl.RelativeTimeFormat>();\nfunction getRelativeTimeFormatter(locale?: string): Intl.RelativeTimeFormat {\n const key = locale ?? \"__default__\";\n let cached = relativeTimeFormatterCache.get(key);\n if (cached == null) {\n cached = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n relativeTimeFormatterCache.set(key, cached);\n }\n return cached;\n}\n\n/** Default relative formatter — \"1 day ago\" / \"in 2 hours\" via\n * `Intl.RelativeTimeFormat`. Pure function of the date; does NOT\n * re-render as real time passes. */\nexport function defaultFormatRelative(date: Date): string {\n const rtf = getRelativeTimeFormatter();\n let duration = (date.getTime() - Date.now()) / 1000;\n for (const div of DIVISIONS) {\n if (Math.abs(duration) < div.amount) {\n return rtf.format(Math.round(duration), div.unit);\n }\n duration /= div.amount;\n }\n return rtf.format(Math.round(duration), \"year\");\n}\n\n/** Default absolute formatter — full locale date + time. */\nexport function defaultFormatAbsolute(date: Date): string {\n return date.toLocaleString();\n}\n\n/** Format a raw cell value for display in a `date` / `dateTime` column.\n * Returns both the inline display string and the tooltip string (which\n * is always the absolute form so users can read the exact datetime).\n *\n * Used internally by the grid's default date cell renderer, and exported\n * so consumers writing a custom `renderCell` for a date column can stay\n * visually consistent with the built-in behaviour.\n *\n * ```tsx\n * renderCell: ({ value, dateDisplay }) => {\n * const { display, tooltip } = formatGridDate(value, dateDisplay);\n * if (!display) return <span className=\"text-muted-foreground/40\">—</span>;\n * return <span title={tooltip ?? undefined}>{display}</span>;\n * }\n * ``` */\nexport function formatGridDate(\n value: unknown,\n mode: DataGridDateDisplay,\n opts?: {\n parseValue?: (value: unknown) => Date | null;\n dateFormat?: DataGridDateFormat;\n },\n): { display: string | null; tooltip: string | null } {\n const parse = opts?.parseValue ?? defaultParseDate;\n const date = parse(value);\n if (!date) return { display: null, tooltip: null };\n\n const relative = opts?.dateFormat?.relative ?? defaultFormatRelative;\n const absolute = opts?.dateFormat?.absolute ?? defaultFormatAbsolute;\n\n const tooltip = absolute(date);\n const display = mode === \"relative\" ? relative(date) : tooltip;\n return { display, tooltip };\n}\n\n// ─── CSV Export ──────────────────────────────────────────────────────\n\nexport function exportToCsv<TRow>(\n rows: readonly TRow[],\n columns: readonly DataGridColumnDef<TRow>[],\n filename: string,\n): void {\n const header = columns.map((col) =>\n typeof col.header === \"string\" ? col.header : col.id,\n );\n\n const csvRows = rows.map((row) =>\n columns.map((col) => {\n const val = resolveColumnValue(col, row);\n // Coerce through `?? \"\"` so a `formatValue` that returns undefined/null\n // (easy to do from a ternary) doesn't crash `.includes` below.\n // The type says `formatValue` returns string, but a consumer can\n // easily return undefined/null from a ternary. Guard at runtime.\n const formatted = col.formatValue\n ? String((col.formatValue(val, row) as string | null | undefined) ?? \"\")\n : String(val ?? \"\");\n // Escape CSV special characters\n if (formatted.includes(\",\") || formatted.includes('\"') || formatted.includes(\"\\n\")) {\n return `\"${formatted.replace(/\"/g, '\"\"')}\"`;\n }\n return formatted;\n }),\n );\n\n // Prepend a UTF-8 BOM so Excel (Windows) opens the CSV as UTF-8 instead of\n // falling back to latin-1 and mangling every display name with a non-ascii\n // character.\n const csvContent = \"\\ufeff\" + [\n header.join(\",\"),\n ...csvRows.map((row) => row.join(\",\")),\n ].join(\"\\n\");\n\n const blob = new Blob([csvContent], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n // Safari / older Firefox need the link in the DOM to honour `.click()`.\n document.body.appendChild(link);\n try {\n link.click();\n } finally {\n link.remove();\n URL.revokeObjectURL(url);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"state.js","names":["DEFAULT_COL_WIDTH"],"sources":["../../../src/components/data-grid/state.ts"],"sourcesContent":["import { stringCompare } from \"@stackframe/stack-shared/dist/utils/strings\";\nimport { clampColumnWidth, DEFAULT_COL_WIDTH } from \"./data-grid-sizing\";\nimport type {\n DataGridColumnDef,\n DataGridDateDisplay,\n DataGridDateFormat,\n DataGridPaginationModel,\n DataGridSortModel,\n DataGridState,\n} from \"./types\";\n\n/**\n * Build the initial `DataGridState` for a set of columns. Pass this as the\n * lazy initializer to `useState` — never hand-assemble the state object.\n *\n * ```tsx\n * const [gridState, setGridState] = React.useState(() =>\n * createDefaultDataGridState(columns)\n * );\n * ```\n */\nexport function createDefaultDataGridState(\n columns: readonly DataGridColumnDef<any>[],\n): DataGridState {\n const columnWidths: Record<string, number> = {};\n const columnOrder: string[] = [];\n\n for (const col of columns) {\n columnWidths[col.id] = clampColumnWidth(col, col.width ?? DEFAULT_COL_WIDTH);\n columnOrder.push(col.id);\n }\n\n return {\n sorting: [],\n columnVisibility: {},\n columnWidths,\n columnPinning: { left: [], right: [] },\n columnOrder,\n pagination: { pageIndex: 0, pageSize: 50 },\n selection: { selectedIds: new Set(), anchorId: null },\n dateDisplay: \"relative\",\n quickSearch: \"\",\n };\n}\n\n// ─── Column value resolution ─────────────────────────────────────────\n\nexport function resolveColumnValue<TRow>(\n col: DataGridColumnDef<TRow>,\n row: TRow,\n): unknown {\n if (typeof col.accessor === \"function\") return col.accessor(row);\n const key = (col.accessor ?? col.id) as keyof TRow;\n return row[key];\n}\n\n// ─── Default sort comparator (used by client-mode useDataSource) ────\n\nfunction defaultComparator(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();\n return stringCompare(String(a), String(b));\n}\n\nexport function buildRowComparator<TRow>(\n sortModel: DataGridSortModel,\n columns: readonly DataGridColumnDef<TRow>[],\n): ((a: TRow, b: TRow) => number) | null {\n if (sortModel.length === 0) return null;\n const colMap = new Map(columns.map((c) => [c.id, c]));\n return (a, b) => {\n for (const { columnId, direction } of sortModel) {\n const col = colMap.get(columnId);\n if (!col) continue;\n const va = resolveColumnValue(col, a);\n const vb = resolveColumnValue(col, b);\n const cmp = col.sortComparator ? col.sortComparator(va, vb) : defaultComparator(va, vb);\n if (cmp !== 0) return direction === \"asc\" ? cmp : -cmp;\n }\n return 0;\n };\n}\n\n// ─── Pagination ──────────────────────────────────────────────────────\n\nexport function paginateRows<TRow>(\n rows: readonly TRow[],\n pagination: DataGridPaginationModel,\n): TRow[] {\n const start = pagination.pageIndex * pagination.pageSize;\n return rows.slice(start, start + pagination.pageSize) as TRow[];\n}\n\n// ─── Quick search ────────────────────────────────────────────────────\n\n/** Default row matcher: case-insensitive substring across every column. */\nexport function defaultMatchRow<TRow>(\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n): boolean {\n for (const col of columns) {\n const v = resolveColumnValue(col, row);\n if (v == null) continue;\n if (String(v).toLowerCase().includes(query)) return true;\n }\n return false;\n}\n\nexport function applyQuickSearch<TRow>(\n rows: readonly TRow[],\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n matchRow: (\n row: TRow,\n query: string,\n columns: readonly DataGridColumnDef<TRow>[],\n ) => boolean = defaultMatchRow,\n): readonly TRow[] {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) return rows;\n return rows.filter((r) => matchRow(r, trimmed, columns));\n}\n\n// ─── Date helpers ────────────────────────────────────────────────────\n\nexport function defaultParseDate(value: unknown): Date | null {\n if (value == null) return null;\n if (value instanceof Date) return isNaN(value.getTime()) ? null : value;\n if (typeof value === \"number\" || typeof value === \"string\") {\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d;\n }\n return null;\n}\n\nconst DIVISIONS: Array<{ amount: number; unit: Intl.RelativeTimeFormatUnit }> = [\n { amount: 60, unit: \"second\" },\n { amount: 60, unit: \"minute\" },\n { amount: 24, unit: \"hour\" },\n { amount: 7, unit: \"day\" },\n { amount: 4.34524, unit: \"week\" },\n { amount: 12, unit: \"month\" },\n { amount: Number.POSITIVE_INFINITY, unit: \"year\" },\n];\n\nconst relativeTimeFormatterCache = new Map<string, Intl.RelativeTimeFormat>();\nfunction getRelativeTimeFormatter(locale?: string): Intl.RelativeTimeFormat {\n const key = locale ?? \"__default__\";\n let cached = relativeTimeFormatterCache.get(key);\n if (cached == null) {\n cached = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n relativeTimeFormatterCache.set(key, cached);\n }\n return cached;\n}\n\nexport function defaultFormatRelative(date: Date): string {\n const rtf = getRelativeTimeFormatter();\n // Wall-clock comparison to \"now\" (e.g. \"5 minutes ago\"). performance.now()\n // would be wrong here — it's a monotonic timer, not a wall-clock instant.\n let duration = (date.getTime() - Date.now()) / 1000;\n for (const div of DIVISIONS) {\n if (Math.abs(duration) < div.amount) return rtf.format(Math.round(duration), div.unit);\n duration /= div.amount;\n }\n return rtf.format(Math.round(duration), \"year\");\n}\n\nexport function defaultFormatAbsolute(date: Date): string {\n return date.toLocaleString();\n}\n\nexport function formatGridDate(\n value: unknown,\n mode: DataGridDateDisplay,\n opts?: {\n parseValue?: (value: unknown) => Date | null;\n dateFormat?: DataGridDateFormat;\n },\n): { display: string | null; tooltip: string | null } {\n const parse = opts?.parseValue ?? defaultParseDate;\n const date = parse(value);\n if (!date) return { display: null, tooltip: null };\n const relative = opts?.dateFormat?.relative ?? defaultFormatRelative;\n const absolute = opts?.dateFormat?.absolute ?? defaultFormatAbsolute;\n const tooltip = absolute(date);\n const display = mode === \"relative\" ? relative(date) : tooltip;\n return { display, tooltip };\n}\n\n// ─── CSV Export ──────────────────────────────────────────────────────\n\nexport function exportToCsv<TRow>(\n rows: readonly TRow[],\n columns: readonly DataGridColumnDef<TRow>[],\n filename: string,\n): void {\n const header = columns.map((col) =>\n typeof col.header === \"string\" ? col.header : col.id,\n );\n const csvRows = rows.map((row) =>\n columns.map((col) => {\n const val = resolveColumnValue(col, row);\n const formatted = col.formatValue\n ? String((col.formatValue(val, row) as string | null | undefined) ?? \"\")\n : String(val ?? \"\");\n if (formatted.includes(\",\") || formatted.includes('\"') || formatted.includes(\"\\n\")) {\n return `\"${formatted.replace(/\"/g, '\"\"')}\"`;\n }\n return formatted;\n }),\n );\n // UTF-8 BOM so Excel opens the CSV as UTF-8.\n const csvContent = \"\\uFEFF\" + [\n header.join(\",\"),\n ...csvRows.map((row) => row.join(\",\")),\n ].join(\"\\n\");\n\n const blob = new Blob([csvContent], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n document.body.appendChild(link);\n try {\n link.click();\n } finally {\n link.remove();\n URL.revokeObjectURL(url);\n }\n}\n"],"mappings":"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"}
|
|
@@ -153,6 +153,14 @@ type DataGridCallbacks<TRow> = {
|
|
|
153
153
|
onRowClick?: (row: TRow, rowId: RowId, event: React.MouseEvent) => void;
|
|
154
154
|
onRowDoubleClick?: (row: TRow, rowId: RowId, event: React.MouseEvent) => void;
|
|
155
155
|
onCellClick?: (row: TRow, columnId: string, value: unknown, event: React.MouseEvent) => void;
|
|
156
|
+
/**
|
|
157
|
+
* Fires when the selection set changes. **Page-scoped:** the header "select
|
|
158
|
+
* all" checkbox and `selectedRows` only cover the rows currently rendered
|
|
159
|
+
* (the visible page in paginated mode, or the loaded prefix in infinite
|
|
160
|
+
* mode). The grid does not load other pages to satisfy the selection — if
|
|
161
|
+
* you need cross-page selection, drive `selectedIds` from your own state
|
|
162
|
+
* and load all rows you care about up-front.
|
|
163
|
+
*/
|
|
156
164
|
onSelectionChange?: (selectedIds: ReadonlySet<RowId>, selectedRows: TRow[]) => void;
|
|
157
165
|
onSortChange?: (model: DataGridSortModel) => void;
|
|
158
166
|
onColumnResize?: (columnId: string, width: number) => void;
|
|
@@ -202,10 +210,7 @@ type DataGridProps<TRow> = {
|
|
|
202
210
|
* When `false`, the grid is only as tall as toolbar + header + rows (`h-auto`), so sibling
|
|
203
211
|
* content (e.g. metadata) sits directly under the table without a large empty gap.
|
|
204
212
|
*/
|
|
205
|
-
fillHeight?: boolean;
|
|
206
|
-
/** Top offset for the sticky toolbar + header (px or CSS string).
|
|
207
|
-
* Set this to the page header height so the grid chrome sticks
|
|
208
|
-
* below it instead of overlapping. Defaults to 0. */
|
|
213
|
+
fillHeight?: boolean; /** Top offset for the sticky toolbar + header (px or CSS string). */
|
|
209
214
|
stickyTop?: number | string;
|
|
210
215
|
} & DataGridCallbacks<TRow> & {
|
|
211
216
|
/** Custom toolbar renderer. When `false`, toolbar is hidden entirely. */toolbar?: false | ((ctx: DataGridToolbarContext<TRow>) => ReactNode);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/components/data-grid/types.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/components/data-grid/types.ts"],"mappings":"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"}
|