@gridkitjs/core 0.11.0 → 0.12.1
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/README.md +5 -3
- package/dist/index.d.ts +1104 -344
- package/dist/index.js +836 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -90,7 +90,9 @@ function buildKeyShortcuts(capabilities) {
|
|
|
90
90
|
capabilities.sortable ? "Alt+ArrowUp" : "",
|
|
91
91
|
// Down rather than reusing Up: it reads as "drill into groups", and Up is
|
|
92
92
|
// already sort's own mnemonic on the same header.
|
|
93
|
-
capabilities.groupable ? "Alt+ArrowDown" : ""
|
|
93
|
+
capabilities.groupable ? "Alt+ArrowDown" : "",
|
|
94
|
+
// The ContextMenu key needs no mention: it says what it does on its face.
|
|
95
|
+
capabilities.contextMenu === true ? "Shift+F10" : ""
|
|
94
96
|
].filter(Boolean).join(" ");
|
|
95
97
|
}
|
|
96
98
|
function accessDotted(obj, path) {
|
|
@@ -1902,6 +1904,9 @@ function createGridController(initial) {
|
|
|
1902
1904
|
});
|
|
1903
1905
|
}
|
|
1904
1906
|
function commitPagination(next) {
|
|
1907
|
+
if (samePagination(state.pagination, next)) {
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1905
1910
|
commit("pagination", next, () => {
|
|
1906
1911
|
options.onPaginationChange?.({
|
|
1907
1912
|
pagination: next,
|
|
@@ -2046,6 +2051,17 @@ function createGridController(initial) {
|
|
|
2046
2051
|
options.onColumnSortChange?.({ columnId, sort: next });
|
|
2047
2052
|
});
|
|
2048
2053
|
},
|
|
2054
|
+
clearColumnSort(columnId) {
|
|
2055
|
+
const next = state.columnSort.filter(
|
|
2056
|
+
(entry) => entry.columnId !== columnId
|
|
2057
|
+
);
|
|
2058
|
+
if (next.length === state.columnSort.length) {
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
commit("columnSort", next, () => {
|
|
2062
|
+
options.onColumnSortChange?.({ columnId, sort: next });
|
|
2063
|
+
});
|
|
2064
|
+
},
|
|
2049
2065
|
setGroupBy(groupBy) {
|
|
2050
2066
|
const columnId = changedEntryColumnId(state.groupBy, groupBy);
|
|
2051
2067
|
if (columnId !== void 0) {
|
|
@@ -2084,11 +2100,7 @@ function createGridController(initial) {
|
|
|
2084
2100
|
collapseAllGroups() {
|
|
2085
2101
|
commitGroupExpansion(collapseAllGroups(getView().displayRows), null);
|
|
2086
2102
|
},
|
|
2087
|
-
setPagination
|
|
2088
|
-
if (!samePagination(state.pagination, pagination)) {
|
|
2089
|
-
commitPagination(pagination);
|
|
2090
|
-
}
|
|
2091
|
-
},
|
|
2103
|
+
setPagination: commitPagination,
|
|
2092
2104
|
goToPage,
|
|
2093
2105
|
nextPage() {
|
|
2094
2106
|
goToPage(shownPageIndex() + 1);
|
|
@@ -2142,14 +2154,653 @@ function createGridController(initial) {
|
|
|
2142
2154
|
return controller;
|
|
2143
2155
|
}
|
|
2144
2156
|
|
|
2157
|
+
// src/commands/context.ts
|
|
2158
|
+
function selectedRowsOf(rows, selection) {
|
|
2159
|
+
if (selection.length === 0) {
|
|
2160
|
+
return [];
|
|
2161
|
+
}
|
|
2162
|
+
const selected = new Set(selection);
|
|
2163
|
+
return rows.filter((entry) => selected.has(entry.rowId));
|
|
2164
|
+
}
|
|
2165
|
+
function createCommandContext({
|
|
2166
|
+
controller,
|
|
2167
|
+
target,
|
|
2168
|
+
messages,
|
|
2169
|
+
host
|
|
2170
|
+
}) {
|
|
2171
|
+
const state = controller.getState();
|
|
2172
|
+
const view = controller.getView();
|
|
2173
|
+
let selectedRows;
|
|
2174
|
+
return {
|
|
2175
|
+
target,
|
|
2176
|
+
state,
|
|
2177
|
+
view,
|
|
2178
|
+
options: controller.getOptions(),
|
|
2179
|
+
messages,
|
|
2180
|
+
actions: controller,
|
|
2181
|
+
host,
|
|
2182
|
+
row: target.area === "cell" ? view.rows.find((entry) => entry.rowId === target.rowId) ?? null : null,
|
|
2183
|
+
column: "columnId" in target ? view.dataColumns.find((entry) => entry.id === target.columnId) ?? null : null,
|
|
2184
|
+
selectedRows: () => selectedRows ??= selectedRowsOf(view.rows, state.rowSelection)
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
// src/commands/builtInCommands.ts
|
|
2189
|
+
function isOn(context, areas) {
|
|
2190
|
+
return areas.includes(context.target.area);
|
|
2191
|
+
}
|
|
2192
|
+
function columnOn(context, areas) {
|
|
2193
|
+
return isOn(context, areas) ? context.column : null;
|
|
2194
|
+
}
|
|
2195
|
+
function isGroupedBy(context, columnId) {
|
|
2196
|
+
return context.state.groupBy.some((entry) => entry.columnId === columnId);
|
|
2197
|
+
}
|
|
2198
|
+
function sortableColumn(context) {
|
|
2199
|
+
const column = columnOn(context, ["header"]);
|
|
2200
|
+
return column !== null && (column.column.sortable ?? context.options.sortableColumns ?? false) ? column : null;
|
|
2201
|
+
}
|
|
2202
|
+
function groupableColumn(context) {
|
|
2203
|
+
const column = columnOn(context, ["header"]);
|
|
2204
|
+
return column !== null && (column.column.groupable ?? context.options.groupableColumns ?? false) && !isGroupedBy(context, column.id) ? column : null;
|
|
2205
|
+
}
|
|
2206
|
+
function groupedColumn(context) {
|
|
2207
|
+
const column = columnOn(context, ["header", "group"]);
|
|
2208
|
+
return column !== null && isGroupedBy(context, column.id) ? column : null;
|
|
2209
|
+
}
|
|
2210
|
+
function hideableColumn(context) {
|
|
2211
|
+
const column = columnOn(context, ["header"]);
|
|
2212
|
+
return column !== null && column.column.hideable !== false ? column : null;
|
|
2213
|
+
}
|
|
2214
|
+
function resizableColumn(context) {
|
|
2215
|
+
const column = columnOn(context, ["header"]);
|
|
2216
|
+
if (column === null) {
|
|
2217
|
+
return null;
|
|
2218
|
+
}
|
|
2219
|
+
return context.view.columns.find(
|
|
2220
|
+
(entry) => entry.id === column.id && entry.resizable
|
|
2221
|
+
) ?? null;
|
|
2222
|
+
}
|
|
2223
|
+
function resizableColumnIds(context) {
|
|
2224
|
+
return context.view.columns.filter((entry) => entry.resizable).map((entry) => entry.id);
|
|
2225
|
+
}
|
|
2226
|
+
function isAnythingSelectable(selectable) {
|
|
2227
|
+
return [selectable?.rows, selectable?.columns, selectable?.cells].some(
|
|
2228
|
+
(mode) => mode !== void 0 && mode !== false
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
function columnName(context) {
|
|
2232
|
+
return context.column === null ? "" : resolveColumnHeaderText(context.column.column);
|
|
2233
|
+
}
|
|
2234
|
+
function columnCommand({
|
|
2235
|
+
id,
|
|
2236
|
+
label,
|
|
2237
|
+
icon,
|
|
2238
|
+
find,
|
|
2239
|
+
isEnabled,
|
|
2240
|
+
isChecked,
|
|
2241
|
+
execute
|
|
2242
|
+
}) {
|
|
2243
|
+
function test(predicate) {
|
|
2244
|
+
return (context) => {
|
|
2245
|
+
const column = find(context);
|
|
2246
|
+
return column !== null && predicate(column, context);
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
return {
|
|
2250
|
+
id,
|
|
2251
|
+
label,
|
|
2252
|
+
icon,
|
|
2253
|
+
isVisible: (context) => find(context) !== null,
|
|
2254
|
+
isEnabled: isEnabled === void 0 ? void 0 : test(isEnabled),
|
|
2255
|
+
isChecked: isChecked === void 0 ? void 0 : test(isChecked),
|
|
2256
|
+
execute: (context) => {
|
|
2257
|
+
const column = find(context);
|
|
2258
|
+
if (column !== null) {
|
|
2259
|
+
execute(column, context);
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
function sortCommand(direction) {
|
|
2265
|
+
return columnCommand({
|
|
2266
|
+
id: direction === "asc" ? "sort.ascending" : "sort.descending",
|
|
2267
|
+
label: ({ messages }) => direction === "asc" ? messages.sortAscending : messages.sortDescending,
|
|
2268
|
+
icon: direction === "asc" ? "sortAscending" : "sortDescending",
|
|
2269
|
+
find: sortableColumn,
|
|
2270
|
+
isChecked: (column, { state }) => sortDirectionFor(state.columnSort, column.id) === direction,
|
|
2271
|
+
execute: (column, { actions }) => {
|
|
2272
|
+
actions.setColumnSort([{ columnId: column.id, direction }]);
|
|
2273
|
+
}
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
function builtInCommands() {
|
|
2277
|
+
return [
|
|
2278
|
+
sortCommand("asc"),
|
|
2279
|
+
sortCommand("desc"),
|
|
2280
|
+
// Cleared rather than set, so the change reports this column — the one
|
|
2281
|
+
// the announcement names — rather than a key that moved up past it.
|
|
2282
|
+
columnCommand({
|
|
2283
|
+
id: "sort.clear",
|
|
2284
|
+
label: ({ messages }) => messages.clearSort,
|
|
2285
|
+
find: sortableColumn,
|
|
2286
|
+
isEnabled: (column, { state }) => sortDirectionFor(state.columnSort, column.id) !== null,
|
|
2287
|
+
execute: (column, { actions }) => {
|
|
2288
|
+
actions.clearColumnSort(column.id);
|
|
2289
|
+
}
|
|
2290
|
+
}),
|
|
2291
|
+
{
|
|
2292
|
+
id: "sort.clearAll",
|
|
2293
|
+
label: ({ messages }) => messages.clearAllSorting,
|
|
2294
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "header"]),
|
|
2295
|
+
isEnabled: ({ state }) => state.columnSort.length > 0,
|
|
2296
|
+
execute: ({ actions }) => {
|
|
2297
|
+
actions.setColumnSort([]);
|
|
2298
|
+
}
|
|
2299
|
+
},
|
|
2300
|
+
columnCommand({
|
|
2301
|
+
id: "group.add",
|
|
2302
|
+
label: (context) => context.messages.groupByColumn(columnName(context)),
|
|
2303
|
+
icon: "group",
|
|
2304
|
+
find: groupableColumn,
|
|
2305
|
+
execute: (column, { actions }) => {
|
|
2306
|
+
actions.toggleGroupBy(column.id);
|
|
2307
|
+
}
|
|
2308
|
+
}),
|
|
2309
|
+
// Toggled rather than set, so the change reports this column — the one
|
|
2310
|
+
// the announcement names — rather than the level that moved up.
|
|
2311
|
+
columnCommand({
|
|
2312
|
+
id: "group.remove",
|
|
2313
|
+
label: (context) => context.messages.removeGroupBy(columnName(context)),
|
|
2314
|
+
icon: "group",
|
|
2315
|
+
find: groupedColumn,
|
|
2316
|
+
execute: (column, { actions }) => {
|
|
2317
|
+
actions.toggleGroupBy(column.id);
|
|
2318
|
+
}
|
|
2319
|
+
}),
|
|
2320
|
+
{
|
|
2321
|
+
id: "group.clearAll",
|
|
2322
|
+
label: ({ messages }) => messages.ungroupAll,
|
|
2323
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar"]) && context.state.groupBy.length > 0,
|
|
2324
|
+
execute: ({ actions }) => {
|
|
2325
|
+
actions.setGroupBy([]);
|
|
2326
|
+
}
|
|
2327
|
+
},
|
|
2328
|
+
{
|
|
2329
|
+
id: "group.expandAll",
|
|
2330
|
+
label: ({ messages }) => messages.expandAllGroups,
|
|
2331
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "group", "cell"]) && context.state.groupBy.length > 0,
|
|
2332
|
+
execute: ({ actions }) => {
|
|
2333
|
+
actions.expandAllGroups();
|
|
2334
|
+
}
|
|
2335
|
+
},
|
|
2336
|
+
{
|
|
2337
|
+
id: "group.collapseAll",
|
|
2338
|
+
label: ({ messages }) => messages.collapseAllGroups,
|
|
2339
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "group", "cell"]) && context.state.groupBy.length > 0,
|
|
2340
|
+
execute: ({ actions }) => {
|
|
2341
|
+
actions.collapseAllGroups();
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
columnCommand({
|
|
2345
|
+
id: "column.hide",
|
|
2346
|
+
label: ({ messages }) => messages.hideColumn,
|
|
2347
|
+
icon: "hide",
|
|
2348
|
+
find: hideableColumn,
|
|
2349
|
+
// The last column shown stays: a grid with none has no header left to
|
|
2350
|
+
// bring one back from.
|
|
2351
|
+
isEnabled: (column, { view }) => view.columns.some((entry) => entry.id !== column.id),
|
|
2352
|
+
execute: (column, { actions }) => {
|
|
2353
|
+
actions.hideColumns([column.id]);
|
|
2354
|
+
}
|
|
2355
|
+
}),
|
|
2356
|
+
columnCommand({
|
|
2357
|
+
id: "column.autoFit",
|
|
2358
|
+
label: ({ messages }) => messages.autoFitColumn,
|
|
2359
|
+
icon: "autoFit",
|
|
2360
|
+
find: resizableColumn,
|
|
2361
|
+
execute: (column, { host }) => {
|
|
2362
|
+
host.autoFitColumns([column.id]);
|
|
2363
|
+
}
|
|
2364
|
+
}),
|
|
2365
|
+
{
|
|
2366
|
+
id: "column.autoFitAll",
|
|
2367
|
+
label: ({ messages }) => messages.autoFitAllColumns,
|
|
2368
|
+
icon: "autoFit",
|
|
2369
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "header"]) && resizableColumnIds(context).length > 0,
|
|
2370
|
+
execute: (context) => {
|
|
2371
|
+
context.host.autoFitColumns(resizableColumnIds(context));
|
|
2372
|
+
}
|
|
2373
|
+
},
|
|
2374
|
+
// The target goes along, so the renderer opens the chooser where it was
|
|
2375
|
+
// asked for: beside the toolbar button, below the header, or at the
|
|
2376
|
+
// grid's corner for a call from nowhere in particular.
|
|
2377
|
+
{
|
|
2378
|
+
id: "column.choose",
|
|
2379
|
+
label: ({ messages }) => messages.chooseColumns,
|
|
2380
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "header"]),
|
|
2381
|
+
execute: ({ host, target }) => {
|
|
2382
|
+
host.openPanel("columnChooser", target);
|
|
2383
|
+
}
|
|
2384
|
+
},
|
|
2385
|
+
{
|
|
2386
|
+
id: "selection.selectAllRows",
|
|
2387
|
+
label: ({ messages }) => messages.selectAllRows,
|
|
2388
|
+
isVisible: (context) => isOn(context, ["grid", "cell"]) && context.options.selectable?.rows === "multiple",
|
|
2389
|
+
isEnabled: ({ view }) => view.displayDataRows.length > 0,
|
|
2390
|
+
execute: ({ actions }) => {
|
|
2391
|
+
actions.selectAllRows();
|
|
2392
|
+
}
|
|
2393
|
+
},
|
|
2394
|
+
{
|
|
2395
|
+
id: "selection.clear",
|
|
2396
|
+
label: ({ messages }) => messages.clearSelection,
|
|
2397
|
+
isVisible: (context) => isOn(context, ["grid", "cell", "header"]) && isAnythingSelectable(context.options.selectable),
|
|
2398
|
+
isEnabled: ({ state }) => state.rowSelection.length > 0 || state.columnSelection.length > 0 || state.cellSelection !== null,
|
|
2399
|
+
execute: ({ actions }) => {
|
|
2400
|
+
actions.clearSelection();
|
|
2401
|
+
}
|
|
2402
|
+
},
|
|
2403
|
+
{
|
|
2404
|
+
id: "filter.clearAll",
|
|
2405
|
+
label: ({ messages }) => messages.clearFilters,
|
|
2406
|
+
isVisible: (context) => isOn(context, ["grid", "toolbar", "header"]),
|
|
2407
|
+
isEnabled: ({ state }) => state.filter.length > 0,
|
|
2408
|
+
execute: ({ actions }) => {
|
|
2409
|
+
actions.setFilter([]);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
];
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/commands/registry.ts
|
|
2416
|
+
function isCommandVisible(command, context) {
|
|
2417
|
+
return command.isVisible?.(context) ?? true;
|
|
2418
|
+
}
|
|
2419
|
+
function isCommandEnabled(command, context) {
|
|
2420
|
+
return command.isEnabled?.(context) ?? true;
|
|
2421
|
+
}
|
|
2422
|
+
function resolveCommands(commands) {
|
|
2423
|
+
const registry = new Map(
|
|
2424
|
+
builtInCommands().map((command) => [command.id, command])
|
|
2425
|
+
);
|
|
2426
|
+
for (const command of commands ?? []) {
|
|
2427
|
+
if (command.id === "separator") {
|
|
2428
|
+
reportError(
|
|
2429
|
+
"a command cannot have the id `separator`, which a menu reads as a separator, so it is left out."
|
|
2430
|
+
);
|
|
2431
|
+
continue;
|
|
2432
|
+
}
|
|
2433
|
+
registry.set(command.id, command);
|
|
2434
|
+
}
|
|
2435
|
+
return registry;
|
|
2436
|
+
}
|
|
2437
|
+
function runCommand(command, context) {
|
|
2438
|
+
if (!isCommandVisible(command, context) || !isCommandEnabled(command, context)) {
|
|
2439
|
+
return false;
|
|
2440
|
+
}
|
|
2441
|
+
command.execute(context);
|
|
2442
|
+
return true;
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
// src/menu/resolveMenu.ts
|
|
2446
|
+
var reportedUnknownIds = /* @__PURE__ */ new WeakMap();
|
|
2447
|
+
function reportUnknownId(commands, id) {
|
|
2448
|
+
let reported = reportedUnknownIds.get(commands);
|
|
2449
|
+
if (reported === void 0) {
|
|
2450
|
+
reported = /* @__PURE__ */ new Set();
|
|
2451
|
+
reportedUnknownIds.set(commands, reported);
|
|
2452
|
+
}
|
|
2453
|
+
if (reported.has(id)) {
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
reported.add(id);
|
|
2457
|
+
reportError(
|
|
2458
|
+
`the menu or toolbar entry \`${id}\` names no command, so it is left out.`
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
function evaluate(value, context) {
|
|
2462
|
+
return typeof value === "function" ? value(context) : value;
|
|
2463
|
+
}
|
|
2464
|
+
function commandItem(command, context) {
|
|
2465
|
+
if (!isCommandVisible(command, context)) {
|
|
2466
|
+
return null;
|
|
2467
|
+
}
|
|
2468
|
+
return {
|
|
2469
|
+
type: "item",
|
|
2470
|
+
id: command.id,
|
|
2471
|
+
label: evaluate(command.label, context),
|
|
2472
|
+
icon: command.icon,
|
|
2473
|
+
shortcut: command.shortcut,
|
|
2474
|
+
disabled: !isCommandEnabled(command, context),
|
|
2475
|
+
checked: command.isChecked?.(context),
|
|
2476
|
+
run: () => runCommand(command, context)
|
|
2477
|
+
};
|
|
2478
|
+
}
|
|
2479
|
+
function inlineItem(entry, context) {
|
|
2480
|
+
if (evaluate(entry.hidden ?? false, context)) {
|
|
2481
|
+
return null;
|
|
2482
|
+
}
|
|
2483
|
+
const disabled = evaluate(entry.disabled ?? false, context);
|
|
2484
|
+
return {
|
|
2485
|
+
type: "item",
|
|
2486
|
+
id: entry.id,
|
|
2487
|
+
label: evaluate(entry.label, context),
|
|
2488
|
+
icon: entry.icon,
|
|
2489
|
+
shortcut: entry.shortcut,
|
|
2490
|
+
disabled,
|
|
2491
|
+
checked: entry.checked === void 0 ? void 0 : evaluate(entry.checked, context),
|
|
2492
|
+
run: () => {
|
|
2493
|
+
if (disabled) {
|
|
2494
|
+
return false;
|
|
2495
|
+
}
|
|
2496
|
+
entry.onSelect(context);
|
|
2497
|
+
return true;
|
|
2498
|
+
}
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
function collapseSeparators(entries, isEdge = () => false) {
|
|
2502
|
+
const collapsed = [];
|
|
2503
|
+
for (const entry of entries) {
|
|
2504
|
+
const previous = collapsed.at(-1);
|
|
2505
|
+
if (entry.type !== "separator") {
|
|
2506
|
+
if (isEdge(entry) && previous?.type === "separator") {
|
|
2507
|
+
collapsed.pop();
|
|
2508
|
+
}
|
|
2509
|
+
collapsed.push(entry);
|
|
2510
|
+
} else if (previous !== void 0 && previous.type !== "separator" && !isEdge(previous)) {
|
|
2511
|
+
collapsed.push(entry);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
if (collapsed.at(-1)?.type === "separator") {
|
|
2515
|
+
collapsed.pop();
|
|
2516
|
+
}
|
|
2517
|
+
return collapsed;
|
|
2518
|
+
}
|
|
2519
|
+
function resolveMenuEntry(entry, index, options) {
|
|
2520
|
+
const { commands, context } = options;
|
|
2521
|
+
if (entry === "separator") {
|
|
2522
|
+
return { type: "separator", key: `separator-${String(index)}` };
|
|
2523
|
+
}
|
|
2524
|
+
if (typeof entry === "string") {
|
|
2525
|
+
const command = commands.get(entry);
|
|
2526
|
+
if (command === void 0) {
|
|
2527
|
+
reportUnknownId(commands, entry);
|
|
2528
|
+
return null;
|
|
2529
|
+
}
|
|
2530
|
+
return commandItem(command, context);
|
|
2531
|
+
}
|
|
2532
|
+
return entry.type === "item" ? inlineItem(entry, context) : resolveSubmenu(entry, options);
|
|
2533
|
+
}
|
|
2534
|
+
function resolveSubmenu(entry, options) {
|
|
2535
|
+
const items = resolveMenu(entry.items, options);
|
|
2536
|
+
return items.length === 0 ? null : {
|
|
2537
|
+
type: "submenu",
|
|
2538
|
+
id: entry.id,
|
|
2539
|
+
label: evaluate(entry.label, options.context),
|
|
2540
|
+
icon: entry.icon,
|
|
2541
|
+
items
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
function resolveMenu(entries, options) {
|
|
2545
|
+
return collapseSeparators(
|
|
2546
|
+
entries.map((entry, index) => resolveMenuEntry(entry, index, options)).filter((entry) => entry !== null)
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// src/menu/contextMenu.ts
|
|
2551
|
+
var defaultContextMenu = {
|
|
2552
|
+
header: [
|
|
2553
|
+
"sort.ascending",
|
|
2554
|
+
"sort.descending",
|
|
2555
|
+
"sort.clear",
|
|
2556
|
+
"separator",
|
|
2557
|
+
"group.add",
|
|
2558
|
+
"group.remove",
|
|
2559
|
+
"separator",
|
|
2560
|
+
"column.autoFit",
|
|
2561
|
+
"column.autoFitAll",
|
|
2562
|
+
"separator",
|
|
2563
|
+
"column.hide",
|
|
2564
|
+
"column.choose"
|
|
2565
|
+
],
|
|
2566
|
+
cell: [
|
|
2567
|
+
"selection.selectAllRows",
|
|
2568
|
+
"selection.clear",
|
|
2569
|
+
"separator",
|
|
2570
|
+
"group.expandAll",
|
|
2571
|
+
"group.collapseAll"
|
|
2572
|
+
],
|
|
2573
|
+
group: ["group.expandAll", "group.collapseAll", "separator", "group.remove"],
|
|
2574
|
+
body: []
|
|
2575
|
+
};
|
|
2576
|
+
function hasContextMenu(contextMenu, area) {
|
|
2577
|
+
if (contextMenu === void 0 || contextMenu === false) {
|
|
2578
|
+
return false;
|
|
2579
|
+
}
|
|
2580
|
+
const entries = (contextMenu === true ? void 0 : contextMenu[area]) ?? defaultContextMenu[area];
|
|
2581
|
+
return typeof entries === "function" || entries.length > 0;
|
|
2582
|
+
}
|
|
2583
|
+
function entriesFor(given, request) {
|
|
2584
|
+
if (given === void 0) {
|
|
2585
|
+
return request.defaults;
|
|
2586
|
+
}
|
|
2587
|
+
return typeof given === "function" ? given(request) ?? [] : given;
|
|
2588
|
+
}
|
|
2589
|
+
function contextMenuEntries(contextMenu, context) {
|
|
2590
|
+
if (contextMenu === void 0 || contextMenu === false) {
|
|
2591
|
+
return [];
|
|
2592
|
+
}
|
|
2593
|
+
const options = contextMenu === true ? {} : contextMenu;
|
|
2594
|
+
const { target } = context;
|
|
2595
|
+
switch (target.area) {
|
|
2596
|
+
case "header":
|
|
2597
|
+
return entriesFor(options.header, {
|
|
2598
|
+
target,
|
|
2599
|
+
defaults: defaultContextMenu.header,
|
|
2600
|
+
context
|
|
2601
|
+
});
|
|
2602
|
+
case "cell":
|
|
2603
|
+
return entriesFor(options.cell, {
|
|
2604
|
+
target,
|
|
2605
|
+
defaults: defaultContextMenu.cell,
|
|
2606
|
+
context
|
|
2607
|
+
});
|
|
2608
|
+
case "group":
|
|
2609
|
+
return entriesFor(options.group, {
|
|
2610
|
+
target,
|
|
2611
|
+
defaults: defaultContextMenu.group,
|
|
2612
|
+
context
|
|
2613
|
+
});
|
|
2614
|
+
case "body":
|
|
2615
|
+
return entriesFor(options.body, {
|
|
2616
|
+
target,
|
|
2617
|
+
defaults: defaultContextMenu.body,
|
|
2618
|
+
context
|
|
2619
|
+
});
|
|
2620
|
+
default:
|
|
2621
|
+
return [];
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
// src/menu/navigation.ts
|
|
2626
|
+
function startIndex(count, from, move) {
|
|
2627
|
+
const focused = from >= 0 && from < count;
|
|
2628
|
+
switch (move) {
|
|
2629
|
+
case "first":
|
|
2630
|
+
return 0;
|
|
2631
|
+
case "last":
|
|
2632
|
+
return count - 1;
|
|
2633
|
+
case "next":
|
|
2634
|
+
return focused ? from + 1 : 0;
|
|
2635
|
+
case "previous":
|
|
2636
|
+
return focused ? from - 1 : count - 1;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
function nextMenuIndex(entries, from, move) {
|
|
2640
|
+
const count = entries.length;
|
|
2641
|
+
const step = move === "next" || move === "first" ? 1 : -1;
|
|
2642
|
+
const start = startIndex(count, from, move);
|
|
2643
|
+
for (let offset = 0; offset < count; offset++) {
|
|
2644
|
+
const index = ((start + step * offset) % count + count) % count;
|
|
2645
|
+
if (entries[index]?.type !== "separator") {
|
|
2646
|
+
return index;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
return -1;
|
|
2650
|
+
}
|
|
2651
|
+
function typeaheadIndex(labels, from, query) {
|
|
2652
|
+
const typed = query.toLowerCase();
|
|
2653
|
+
const firstCodePoint = typed.codePointAt(0);
|
|
2654
|
+
if (firstCodePoint === void 0) {
|
|
2655
|
+
return -1;
|
|
2656
|
+
}
|
|
2657
|
+
const first = String.fromCodePoint(firstCodePoint);
|
|
2658
|
+
const repeated = typed.replaceAll(first, "") === "";
|
|
2659
|
+
const prefix = repeated ? first : typed;
|
|
2660
|
+
const start = repeated ? from + 1 : Math.max(from, 0);
|
|
2661
|
+
for (let offset = 0; offset < labels.length; offset++) {
|
|
2662
|
+
const index = (start + offset) % labels.length;
|
|
2663
|
+
if (labels[index]?.toLowerCase().startsWith(prefix) === true) {
|
|
2664
|
+
return index;
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
return -1;
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
// src/toolbar/options.ts
|
|
2671
|
+
var defaultToolbar = ["search", "spacer", "filter.clearAll", "column.choose"];
|
|
2672
|
+
function toolbarEntries(toolbar) {
|
|
2673
|
+
if (toolbar === void 0 || toolbar === false) {
|
|
2674
|
+
return [];
|
|
2675
|
+
}
|
|
2676
|
+
return (toolbar === true ? void 0 : toolbar.items) ?? defaultToolbar;
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
// src/toolbar/resolveToolbar.ts
|
|
2680
|
+
function isSpacer(entry) {
|
|
2681
|
+
return entry.type === "spacer";
|
|
2682
|
+
}
|
|
2683
|
+
function resolveToolbar(entries, options) {
|
|
2684
|
+
const { commands, contextFor } = options;
|
|
2685
|
+
function resolveEntry(entry, index) {
|
|
2686
|
+
if (entry === "search") {
|
|
2687
|
+
return { type: "search", key: "search" };
|
|
2688
|
+
}
|
|
2689
|
+
if (entry === "spacer") {
|
|
2690
|
+
return { type: "spacer", key: `spacer-${String(index)}` };
|
|
2691
|
+
}
|
|
2692
|
+
if (typeof entry === "object" && entry.type === "custom") {
|
|
2693
|
+
return { type: "custom", id: entry.id, key: entry.id };
|
|
2694
|
+
}
|
|
2695
|
+
if (entry === "separator") {
|
|
2696
|
+
return { type: "separator", key: `separator-${String(index)}` };
|
|
2697
|
+
}
|
|
2698
|
+
const resolved = resolveMenuEntry(entry, index, {
|
|
2699
|
+
commands,
|
|
2700
|
+
context: contextFor({
|
|
2701
|
+
area: "toolbar",
|
|
2702
|
+
itemId: typeof entry === "string" ? entry : entry.id
|
|
2703
|
+
})
|
|
2704
|
+
});
|
|
2705
|
+
if (resolved === null || resolved.type === "separator") {
|
|
2706
|
+
return resolved;
|
|
2707
|
+
}
|
|
2708
|
+
if (resolved.type === "submenu") {
|
|
2709
|
+
return { ...resolved, type: "menu", key: resolved.id };
|
|
2710
|
+
}
|
|
2711
|
+
const { checked, ...item } = resolved;
|
|
2712
|
+
return { ...item, type: "button", key: item.id, pressed: checked };
|
|
2713
|
+
}
|
|
2714
|
+
return collapseSeparators(
|
|
2715
|
+
entries.map(resolveEntry).filter((entry) => entry !== null),
|
|
2716
|
+
isSpacer
|
|
2717
|
+
);
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
// src/toolbar/overflow.ts
|
|
2721
|
+
function fitToolbarItems({
|
|
2722
|
+
widths,
|
|
2723
|
+
available,
|
|
2724
|
+
moreWidth,
|
|
2725
|
+
pinned
|
|
2726
|
+
}) {
|
|
2727
|
+
const total = widths.reduce((sum, width) => sum + width, 0);
|
|
2728
|
+
if (total <= available) {
|
|
2729
|
+
return widths.length;
|
|
2730
|
+
}
|
|
2731
|
+
let used = moreWidth + widths.reduce((sum, width, index) => sum + (pinned[index] ? width : 0), 0);
|
|
2732
|
+
for (const [index, width] of widths.entries()) {
|
|
2733
|
+
if (!pinned[index]) {
|
|
2734
|
+
used += width;
|
|
2735
|
+
if (used > available) {
|
|
2736
|
+
return index;
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
return widths.length;
|
|
2741
|
+
}
|
|
2742
|
+
function isPinnedToolbarItem(item) {
|
|
2743
|
+
return item.type === "search" || item.type === "custom";
|
|
2744
|
+
}
|
|
2745
|
+
function asMenuEntry(item) {
|
|
2746
|
+
switch (item.type) {
|
|
2747
|
+
case "button":
|
|
2748
|
+
return {
|
|
2749
|
+
type: "item",
|
|
2750
|
+
id: item.id,
|
|
2751
|
+
label: item.label,
|
|
2752
|
+
icon: item.icon,
|
|
2753
|
+
shortcut: item.shortcut,
|
|
2754
|
+
disabled: item.disabled,
|
|
2755
|
+
checked: item.pressed,
|
|
2756
|
+
run: item.run
|
|
2757
|
+
};
|
|
2758
|
+
case "menu":
|
|
2759
|
+
return {
|
|
2760
|
+
type: "submenu",
|
|
2761
|
+
id: item.id,
|
|
2762
|
+
label: item.label,
|
|
2763
|
+
icon: item.icon,
|
|
2764
|
+
items: item.items
|
|
2765
|
+
};
|
|
2766
|
+
case "separator":
|
|
2767
|
+
return item;
|
|
2768
|
+
default:
|
|
2769
|
+
return null;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
function splitToolbarItems(items, fit) {
|
|
2773
|
+
const fits = (item, index) => index < fit || isPinnedToolbarItem(item);
|
|
2774
|
+
return {
|
|
2775
|
+
shown: collapseSeparators(
|
|
2776
|
+
items.filter(fits),
|
|
2777
|
+
(item) => item.type === "spacer"
|
|
2778
|
+
),
|
|
2779
|
+
overflow: collapseSeparators(
|
|
2780
|
+
items.filter((item, index) => !fits(item, index)).map(asMenuEntry).filter((entry) => entry !== null)
|
|
2781
|
+
)
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
// src/toolbar/search.ts
|
|
2786
|
+
function searchTextOf(filter) {
|
|
2787
|
+
const query = filterQueryFor(filter) ?? "";
|
|
2788
|
+
const start = query.startsWith("%") ? 1 : 0;
|
|
2789
|
+
const end = query.endsWith("%") ? -1 : void 0;
|
|
2790
|
+
return query.slice(start, end);
|
|
2791
|
+
}
|
|
2792
|
+
function setSearchText(filter, text) {
|
|
2793
|
+
return setColumnFilter(filter, void 0, text === "" ? "" : `%${text}%`);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2145
2796
|
// src/util/navigation.ts
|
|
2146
2797
|
var HEADER_ROW = -1;
|
|
2147
|
-
function clampFocus(focus, rowCount,
|
|
2798
|
+
function clampFocus(focus, rowCount, columnCount2) {
|
|
2148
2799
|
return {
|
|
2149
2800
|
rowIndex: Math.min(Math.max(focus.rowIndex, HEADER_ROW), rowCount - 1),
|
|
2150
2801
|
columnIndex: Math.min(
|
|
2151
2802
|
Math.max(focus.columnIndex, 0),
|
|
2152
|
-
Math.max(
|
|
2803
|
+
Math.max(columnCount2 - 1, 0)
|
|
2153
2804
|
)
|
|
2154
2805
|
};
|
|
2155
2806
|
}
|
|
@@ -2167,7 +2818,7 @@ function skipSkippableRows(rowIndex, direction, rowCount, isSkippableRow, fallba
|
|
|
2167
2818
|
}
|
|
2168
2819
|
return next;
|
|
2169
2820
|
}
|
|
2170
|
-
function nextFocusForKey(key, modifiers, focus, rowCount,
|
|
2821
|
+
function nextFocusForKey(key, modifiers, focus, rowCount, columnCount2, pageSize, isSkippableRow = noRowsSkippable) {
|
|
2171
2822
|
if (modifiers.altKey) {
|
|
2172
2823
|
return null;
|
|
2173
2824
|
}
|
|
@@ -2214,8 +2865,8 @@ function nextFocusForKey(key, modifiers, focus, rowCount, columnCount, pageSize,
|
|
|
2214
2865
|
isSkippableRow,
|
|
2215
2866
|
rowIndex
|
|
2216
2867
|
),
|
|
2217
|
-
columnIndex:
|
|
2218
|
-
} : { rowIndex, columnIndex:
|
|
2868
|
+
columnIndex: columnCount2 - 1
|
|
2869
|
+
} : { rowIndex, columnIndex: columnCount2 - 1 };
|
|
2219
2870
|
case "PageUp":
|
|
2220
2871
|
return {
|
|
2221
2872
|
rowIndex: skipSkippableRows(
|
|
@@ -2278,6 +2929,139 @@ function paginationWindow(currentPage, pageCount, options) {
|
|
|
2278
2929
|
return entries;
|
|
2279
2930
|
}
|
|
2280
2931
|
|
|
2932
|
+
// src/util/columnChooser.ts
|
|
2933
|
+
function isHideable(column) {
|
|
2934
|
+
return column.column.hideable !== false;
|
|
2935
|
+
}
|
|
2936
|
+
function matchesSearch(label, search) {
|
|
2937
|
+
return label.toLowerCase().includes(search.toLowerCase());
|
|
2938
|
+
}
|
|
2939
|
+
function selectAllStateOf(states) {
|
|
2940
|
+
if (states.length > 0 && states.every(Boolean)) {
|
|
2941
|
+
return "checked";
|
|
2942
|
+
}
|
|
2943
|
+
return states.some(Boolean) ? "mixed" : "unchecked";
|
|
2944
|
+
}
|
|
2945
|
+
function resolveColumnChooser({
|
|
2946
|
+
columns,
|
|
2947
|
+
visibility,
|
|
2948
|
+
search = ""
|
|
2949
|
+
}) {
|
|
2950
|
+
const all = columns.map((column) => ({
|
|
2951
|
+
column,
|
|
2952
|
+
label: resolveColumnHeaderText(column.column),
|
|
2953
|
+
visible: isColumnVisible(column.column, visibility)
|
|
2954
|
+
}));
|
|
2955
|
+
const shownCount = all.filter(({ visible }) => visible).length;
|
|
2956
|
+
const matched = all.filter(({ label }) => matchesSearch(label, search));
|
|
2957
|
+
const entries = matched.map(
|
|
2958
|
+
({ column, label, visible }) => ({
|
|
2959
|
+
columnId: column.id,
|
|
2960
|
+
label,
|
|
2961
|
+
visible,
|
|
2962
|
+
disabled: visible && (!isHideable(column) || shownCount === 1)
|
|
2963
|
+
})
|
|
2964
|
+
);
|
|
2965
|
+
const covered = matched.filter(({ column }) => isHideable(column));
|
|
2966
|
+
const selectAll2 = selectAllStateOf(covered.map(({ visible }) => visible));
|
|
2967
|
+
return {
|
|
2968
|
+
entries,
|
|
2969
|
+
selectAll: selectAll2,
|
|
2970
|
+
toggleAll: toggleAllOf(covered, selectAll2, shownCount)
|
|
2971
|
+
};
|
|
2972
|
+
}
|
|
2973
|
+
function toggleAllOf(covered, selectAll2, shownCount) {
|
|
2974
|
+
const show = selectAll2 !== "checked";
|
|
2975
|
+
const changing = covered.filter(({ visible }) => visible !== show).map(({ column }) => column.id);
|
|
2976
|
+
const columnIds = !show && changing.length === shownCount ? changing.slice(1) : changing;
|
|
2977
|
+
return columnIds.length === 0 ? null : { visible: show, columnIds };
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
// src/messages.ts
|
|
2981
|
+
function columnCount(count, change) {
|
|
2982
|
+
return count === 1 ? `1 column ${change}` : `${String(count)} columns ${change}`;
|
|
2983
|
+
}
|
|
2984
|
+
function searchResults(count) {
|
|
2985
|
+
if (count === 0) {
|
|
2986
|
+
return "No rows found";
|
|
2987
|
+
}
|
|
2988
|
+
return count === 1 ? "1 row found" : `${String(count)} rows found`;
|
|
2989
|
+
}
|
|
2990
|
+
function selectedCount(count, target) {
|
|
2991
|
+
const noun = target === "rows" ? "row" : "column";
|
|
2992
|
+
if (count === 0) {
|
|
2993
|
+
return `No ${noun}s selected`;
|
|
2994
|
+
}
|
|
2995
|
+
return count === 1 ? `1 ${noun} selected` : `${String(count)} ${noun}s selected`;
|
|
2996
|
+
}
|
|
2997
|
+
var defaultMessages = {
|
|
2998
|
+
pagerLabel: "Pagination",
|
|
2999
|
+
previousPage: "Previous",
|
|
3000
|
+
nextPage: "Next",
|
|
3001
|
+
pageSizeLabel: "Rows per page",
|
|
3002
|
+
pageButtonLabel: (page) => `Page ${String(page)}`,
|
|
3003
|
+
pageStatus: (page, pageCount) => `Page ${String(page)} of ${String(pageCount)}`,
|
|
3004
|
+
loadingMore: "Loading more\u2026",
|
|
3005
|
+
booleanTrue: "true",
|
|
3006
|
+
booleanFalse: "false",
|
|
3007
|
+
blankGroupValue: "(blank)",
|
|
3008
|
+
groupByBarLabel: "Grouped by",
|
|
3009
|
+
groupByBarPlaceholder: "Drag a column here to group by it",
|
|
3010
|
+
groupByChipLabel: (columnName2, level, levelCount) => levelCount > 1 ? `${columnName2}, level ${String(level)} of ${String(levelCount)}` : columnName2,
|
|
3011
|
+
removeGroupBy: (columnName2) => `Stop grouping by ${columnName2}`,
|
|
3012
|
+
columnResized: (columnName2, width) => `${columnName2}, ${String(width)} pixels wide`,
|
|
3013
|
+
columnMoved: (columnName2, position, columnCount2) => `${columnName2}, column ${String(position)} of ${String(columnCount2)}`,
|
|
3014
|
+
columnSorted: (columnName2, direction, key, keyCount) => {
|
|
3015
|
+
const sorted = `${columnName2} sorted ${direction === "asc" ? "ascending" : "descending"}`;
|
|
3016
|
+
return keyCount > 1 ? `${sorted}, key ${String(key)} of ${String(keyCount)}` : sorted;
|
|
3017
|
+
},
|
|
3018
|
+
sortCleared: (columnName2) => `${columnName2}, sort cleared`,
|
|
3019
|
+
groupedBy: (columnName2, level, levelCount) => levelCount > 1 ? `Grouped by ${columnName2}, level ${String(level)} of ${String(levelCount)}` : `Grouped by ${columnName2}`,
|
|
3020
|
+
groupingRemoved: (columnName2) => `${columnName2}, grouping removed`,
|
|
3021
|
+
groupExpanded: "Group expanded",
|
|
3022
|
+
groupCollapsed: "Group collapsed",
|
|
3023
|
+
allGroupsExpanded: "All groups expanded",
|
|
3024
|
+
allGroupsCollapsed: "All groups collapsed",
|
|
3025
|
+
selectedCount,
|
|
3026
|
+
cellSelected: (columnName2, rowNumber) => `${columnName2}, row ${String(rowNumber)}, selected`,
|
|
3027
|
+
columnHidden: (columnName2) => `${columnName2}, column hidden`,
|
|
3028
|
+
columnShown: (columnName2) => `${columnName2}, column shown`,
|
|
3029
|
+
columnsHidden: (count) => columnCount(count, "hidden"),
|
|
3030
|
+
columnsShown: (count) => columnCount(count, "shown"),
|
|
3031
|
+
columnsAutoFitted: (count) => columnCount(count, "autofitted"),
|
|
3032
|
+
headerMenuLabel: (columnName2) => `${columnName2} column menu`,
|
|
3033
|
+
cellMenuLabel: "Row menu",
|
|
3034
|
+
groupMenuLabel: "Group menu",
|
|
3035
|
+
bodyMenuLabel: "Grid menu",
|
|
3036
|
+
sortAscending: "Sort ascending",
|
|
3037
|
+
sortDescending: "Sort descending",
|
|
3038
|
+
clearSort: "Clear sort",
|
|
3039
|
+
clearAllSorting: "Clear all sorting",
|
|
3040
|
+
groupByColumn: (columnName2) => `Group by ${columnName2}`,
|
|
3041
|
+
ungroupAll: "Ungroup all",
|
|
3042
|
+
expandAllGroups: "Expand all groups",
|
|
3043
|
+
collapseAllGroups: "Collapse all groups",
|
|
3044
|
+
hideColumn: "Hide column",
|
|
3045
|
+
autoFitColumn: "Autofit column",
|
|
3046
|
+
autoFitAllColumns: "Autofit all columns",
|
|
3047
|
+
selectAllRows: "Select all rows",
|
|
3048
|
+
clearSelection: "Clear selection",
|
|
3049
|
+
clearFilters: "Clear filters",
|
|
3050
|
+
chooseColumns: "Choose columns",
|
|
3051
|
+
toolbarLabel: "Grid toolbar",
|
|
3052
|
+
searchLabel: "Search",
|
|
3053
|
+
searchPlaceholder: "Search\u2026",
|
|
3054
|
+
moreToolbarItems: "More",
|
|
3055
|
+
searchResults,
|
|
3056
|
+
columnChooserLabel: "Columns",
|
|
3057
|
+
columnChooserSearchLabel: "Search columns",
|
|
3058
|
+
showAllColumns: "Show all",
|
|
3059
|
+
noMatchingColumns: "No matching columns"
|
|
3060
|
+
};
|
|
3061
|
+
function resolveMessages(messages) {
|
|
3062
|
+
return messages === void 0 ? defaultMessages : { ...defaultMessages, ...messages };
|
|
3063
|
+
}
|
|
3064
|
+
|
|
2281
3065
|
// src/util/format.ts
|
|
2282
3066
|
var DATE_FIELDS = {
|
|
2283
3067
|
year: "numeric",
|
|
@@ -2464,7 +3248,7 @@ function describeColumnFilter(filter, columnId) {
|
|
|
2464
3248
|
function isOfferable(value) {
|
|
2465
3249
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value instanceof Date;
|
|
2466
3250
|
}
|
|
2467
|
-
function
|
|
3251
|
+
function matchesSearch2(label, search) {
|
|
2468
3252
|
return label.toLowerCase().includes(search.toLowerCase());
|
|
2469
3253
|
}
|
|
2470
3254
|
function columnValueOptions(rows, dataColumns, filter, columnId, query = {}) {
|
|
@@ -2486,7 +3270,7 @@ function columnValueOptions(rows, dataColumns, filter, columnId, query = {}) {
|
|
|
2486
3270
|
if (isEmptyCell(value)) {
|
|
2487
3271
|
blanks++;
|
|
2488
3272
|
} else if (isOfferable(value)) {
|
|
2489
|
-
const key =
|
|
3273
|
+
const key = filterValueKey(value, column.type);
|
|
2490
3274
|
const bucket = buckets.get(key);
|
|
2491
3275
|
if (bucket === void 0) {
|
|
2492
3276
|
buckets.set(key, { value, row, count: 1 });
|
|
@@ -2496,22 +3280,27 @@ function columnValueOptions(rows, dataColumns, filter, columnId, query = {}) {
|
|
|
2496
3280
|
}
|
|
2497
3281
|
}
|
|
2498
3282
|
const { search = "", limit, locale } = query;
|
|
3283
|
+
const messages = resolveMessages(query.messages);
|
|
2499
3284
|
const options = [...buckets.values()].sort((a, b) => compareValues(a.value, b.value, column.type)).map(({ value, row, count }) => ({
|
|
2500
3285
|
value,
|
|
2501
|
-
label: formatCellValue(value, column, locale, row),
|
|
3286
|
+
label: formatCellValue(value, column, locale, row, messages),
|
|
2502
3287
|
count
|
|
2503
|
-
})).filter((option) =>
|
|
3288
|
+
})).filter((option) => matchesSearch2(option.label, search));
|
|
2504
3289
|
const shown = limit === void 0 ? options : options.slice(0, limit);
|
|
2505
3290
|
return {
|
|
2506
3291
|
options: shown,
|
|
2507
3292
|
total: options.length,
|
|
2508
3293
|
truncated: shown.length < options.length,
|
|
2509
|
-
blanks
|
|
3294
|
+
blanks,
|
|
3295
|
+
columnType: column.type
|
|
2510
3296
|
};
|
|
2511
3297
|
}
|
|
2512
|
-
function
|
|
3298
|
+
function keyOf2(draft, value) {
|
|
3299
|
+
return filterValueKey(value, draft.columnType);
|
|
3300
|
+
}
|
|
3301
|
+
function everyOption(draft) {
|
|
2513
3302
|
return new Map(
|
|
2514
|
-
options.map((option) => [
|
|
3303
|
+
draft.options.map((option) => [keyOf2(draft, option.value), option.value])
|
|
2515
3304
|
);
|
|
2516
3305
|
}
|
|
2517
3306
|
function initialFilterEditorDraft(shape, values) {
|
|
@@ -2520,17 +3309,18 @@ function initialFilterEditorDraft(shape, values) {
|
|
|
2520
3309
|
options: values.options,
|
|
2521
3310
|
blanks: values.blanks,
|
|
2522
3311
|
search: "",
|
|
2523
|
-
checked: everyOption(values
|
|
3312
|
+
checked: everyOption(values),
|
|
2524
3313
|
includeBlanks: values.blanks > 0,
|
|
2525
3314
|
conditions: [],
|
|
2526
|
-
combinator: "and"
|
|
3315
|
+
combinator: "and",
|
|
3316
|
+
columnType: values.columnType
|
|
2527
3317
|
};
|
|
2528
3318
|
switch (shape.kind) {
|
|
2529
3319
|
case "values":
|
|
2530
3320
|
return {
|
|
2531
3321
|
...draft,
|
|
2532
3322
|
checked: new Map(
|
|
2533
|
-
shape.values.filter((value) => !isEmptyCell(value)).map((value) => [
|
|
3323
|
+
shape.values.filter((value) => !isEmptyCell(value)).map((value) => [keyOf2(draft, value), value])
|
|
2534
3324
|
),
|
|
2535
3325
|
includeBlanks: shape.includeBlanks
|
|
2536
3326
|
};
|
|
@@ -2548,7 +3338,7 @@ function initialFilterEditorDraft(shape, values) {
|
|
|
2548
3338
|
}
|
|
2549
3339
|
function visibleFilterOptions(draft) {
|
|
2550
3340
|
return draft.search === "" ? draft.options : draft.options.filter(
|
|
2551
|
-
(option) =>
|
|
3341
|
+
(option) => matchesSearch2(option.label, draft.search)
|
|
2552
3342
|
);
|
|
2553
3343
|
}
|
|
2554
3344
|
function selectAllCoversBlanks(draft) {
|
|
@@ -2556,7 +3346,7 @@ function selectAllCoversBlanks(draft) {
|
|
|
2556
3346
|
}
|
|
2557
3347
|
function selectAllState(draft) {
|
|
2558
3348
|
const states = visibleFilterOptions(draft).map(
|
|
2559
|
-
(option) => draft.checked.has(
|
|
3349
|
+
(option) => draft.checked.has(keyOf2(draft, option.value))
|
|
2560
3350
|
);
|
|
2561
3351
|
if (selectAllCoversBlanks(draft)) {
|
|
2562
3352
|
states.push(draft.includeBlanks);
|
|
@@ -2570,7 +3360,7 @@ function toggleAll(draft) {
|
|
|
2570
3360
|
const check = selectAllState(draft) !== "checked";
|
|
2571
3361
|
const checked = new Map(draft.checked);
|
|
2572
3362
|
for (const option of visibleFilterOptions(draft)) {
|
|
2573
|
-
const key =
|
|
3363
|
+
const key = keyOf2(draft, option.value);
|
|
2574
3364
|
if (check) {
|
|
2575
3365
|
checked.set(key, option.value);
|
|
2576
3366
|
} else {
|
|
@@ -2589,7 +3379,7 @@ function filterEditorReducer(draft, action) {
|
|
|
2589
3379
|
case "search":
|
|
2590
3380
|
return { ...draft, search: action.search };
|
|
2591
3381
|
case "toggleValue": {
|
|
2592
|
-
const key =
|
|
3382
|
+
const key = keyOf2(draft, action.value);
|
|
2593
3383
|
const checked = new Map(draft.checked);
|
|
2594
3384
|
if (checked.has(key)) {
|
|
2595
3385
|
checked.delete(key);
|
|
@@ -2613,7 +3403,7 @@ function filterEditorReducer(draft, action) {
|
|
|
2613
3403
|
return {
|
|
2614
3404
|
...draft,
|
|
2615
3405
|
search: "",
|
|
2616
|
-
checked: everyOption(draft
|
|
3406
|
+
checked: everyOption(draft),
|
|
2617
3407
|
includeBlanks: draft.blanks > 0,
|
|
2618
3408
|
conditions: []
|
|
2619
3409
|
};
|
|
@@ -2621,7 +3411,7 @@ function filterEditorReducer(draft, action) {
|
|
|
2621
3411
|
}
|
|
2622
3412
|
function checksEverything(draft) {
|
|
2623
3413
|
return draft.options.every(
|
|
2624
|
-
(option) => draft.checked.has(
|
|
3414
|
+
(option) => draft.checked.has(keyOf2(draft, option.value))
|
|
2625
3415
|
) && (draft.includeBlanks || draft.blanks === 0);
|
|
2626
3416
|
}
|
|
2627
3417
|
function draftEntries(draft, columnId) {
|
|
@@ -2657,49 +3447,6 @@ function draftToFilter(draft, columnId, current) {
|
|
|
2657
3447
|
return [...kept.slice(0, first), ...replacement, ...kept.slice(first)];
|
|
2658
3448
|
}
|
|
2659
3449
|
|
|
2660
|
-
// src/messages.ts
|
|
2661
|
-
function selectedCount(count, target) {
|
|
2662
|
-
const noun = target === "rows" ? "row" : "column";
|
|
2663
|
-
if (count === 0) {
|
|
2664
|
-
return `No ${noun}s selected`;
|
|
2665
|
-
}
|
|
2666
|
-
return count === 1 ? `1 ${noun} selected` : `${String(count)} ${noun}s selected`;
|
|
2667
|
-
}
|
|
2668
|
-
var defaultMessages = {
|
|
2669
|
-
pagerLabel: "Pagination",
|
|
2670
|
-
previousPage: "Previous",
|
|
2671
|
-
nextPage: "Next",
|
|
2672
|
-
pageSizeLabel: "Rows per page",
|
|
2673
|
-
pageButtonLabel: (page) => `Page ${String(page)}`,
|
|
2674
|
-
pageStatus: (page, pageCount) => `Page ${String(page)} of ${String(pageCount)}`,
|
|
2675
|
-
loadingMore: "Loading more\u2026",
|
|
2676
|
-
booleanTrue: "true",
|
|
2677
|
-
booleanFalse: "false",
|
|
2678
|
-
blankGroupValue: "(blank)",
|
|
2679
|
-
groupByBarLabel: "Grouped by",
|
|
2680
|
-
groupByBarPlaceholder: "Drag a column here to group by it",
|
|
2681
|
-
groupByChipLabel: (columnName, level, levelCount) => levelCount > 1 ? `${columnName}, level ${String(level)} of ${String(levelCount)}` : columnName,
|
|
2682
|
-
removeGroupBy: (columnName) => `Stop grouping by ${columnName}`,
|
|
2683
|
-
columnResized: (columnName, width) => `${columnName}, ${String(width)} pixels wide`,
|
|
2684
|
-
columnMoved: (columnName, position, columnCount) => `${columnName}, column ${String(position)} of ${String(columnCount)}`,
|
|
2685
|
-
columnSorted: (columnName, direction, key, keyCount) => {
|
|
2686
|
-
const sorted = `${columnName} sorted ${direction === "asc" ? "ascending" : "descending"}`;
|
|
2687
|
-
return keyCount > 1 ? `${sorted}, key ${String(key)} of ${String(keyCount)}` : sorted;
|
|
2688
|
-
},
|
|
2689
|
-
sortCleared: (columnName) => `${columnName}, sort cleared`,
|
|
2690
|
-
groupedBy: (columnName, level, levelCount) => levelCount > 1 ? `Grouped by ${columnName}, level ${String(level)} of ${String(levelCount)}` : `Grouped by ${columnName}`,
|
|
2691
|
-
groupingRemoved: (columnName) => `${columnName}, grouping removed`,
|
|
2692
|
-
groupExpanded: "Group expanded",
|
|
2693
|
-
groupCollapsed: "Group collapsed",
|
|
2694
|
-
allGroupsExpanded: "All groups expanded",
|
|
2695
|
-
allGroupsCollapsed: "All groups collapsed",
|
|
2696
|
-
selectedCount,
|
|
2697
|
-
cellSelected: (columnName, rowNumber) => `${columnName}, row ${String(rowNumber)}, selected`
|
|
2698
|
-
};
|
|
2699
|
-
function resolveMessages(messages) {
|
|
2700
|
-
return messages === void 0 ? defaultMessages : { ...defaultMessages, ...messages };
|
|
2701
|
-
}
|
|
2702
|
-
|
|
2703
3450
|
// src/util/virtualization.ts
|
|
2704
3451
|
function visibleRange(heights, estimatedHeight, scrollTop, viewportHeight, overscan) {
|
|
2705
3452
|
const rowCount = heights.length;
|
|
@@ -2752,6 +3499,7 @@ export {
|
|
|
2752
3499
|
applySelectionIntent,
|
|
2753
3500
|
beginColumnResize,
|
|
2754
3501
|
buildKeyShortcuts,
|
|
3502
|
+
builtInCommands,
|
|
2755
3503
|
clampColumnWidth,
|
|
2756
3504
|
clampFocus,
|
|
2757
3505
|
clearAllFilters,
|
|
@@ -2760,9 +3508,13 @@ export {
|
|
|
2760
3508
|
columnValueOptions,
|
|
2761
3509
|
compareValues,
|
|
2762
3510
|
computeAggregates,
|
|
3511
|
+
contextMenuEntries,
|
|
3512
|
+
createCommandContext,
|
|
2763
3513
|
createGridController,
|
|
2764
3514
|
createGridViewResolver,
|
|
3515
|
+
defaultContextMenu,
|
|
2765
3516
|
defaultMessages,
|
|
3517
|
+
defaultToolbar,
|
|
2766
3518
|
defineColumnsFromRows,
|
|
2767
3519
|
describeColumnFilter,
|
|
2768
3520
|
diffSelection,
|
|
@@ -2772,14 +3524,17 @@ export {
|
|
|
2772
3524
|
filterQueryFor,
|
|
2773
3525
|
filterRows,
|
|
2774
3526
|
fitColumnsToWidth,
|
|
3527
|
+
fitToolbarItems,
|
|
2775
3528
|
formatAggregateValue,
|
|
2776
3529
|
formatCellValue,
|
|
2777
3530
|
getColumnId,
|
|
2778
3531
|
groupRowId,
|
|
2779
3532
|
groupRows,
|
|
3533
|
+
hasContextMenu,
|
|
2780
3534
|
initialFilterEditorDraft,
|
|
2781
3535
|
intentOf,
|
|
2782
3536
|
isColumnVisible,
|
|
3537
|
+
isPinnedToolbarItem,
|
|
2783
3538
|
isSameCell,
|
|
2784
3539
|
matchesQuery,
|
|
2785
3540
|
moveColumnBefore,
|
|
@@ -2787,23 +3542,30 @@ export {
|
|
|
2787
3542
|
movesColumn,
|
|
2788
3543
|
movesGroupBy,
|
|
2789
3544
|
nextFocusForKey,
|
|
3545
|
+
nextMenuIndex,
|
|
2790
3546
|
paginateRows,
|
|
2791
3547
|
paginationWindow,
|
|
2792
3548
|
resolveCell,
|
|
3549
|
+
resolveColumnChooser,
|
|
2793
3550
|
resolveColumnConstraints,
|
|
2794
3551
|
resolveColumnHeaderText,
|
|
2795
3552
|
resolveColumnLabel,
|
|
2796
3553
|
resolveColumnWidths,
|
|
2797
3554
|
resolveColumns,
|
|
3555
|
+
resolveCommands,
|
|
2798
3556
|
resolveDataColumns,
|
|
2799
3557
|
resolveDropBefore,
|
|
2800
3558
|
resolveGridView,
|
|
2801
3559
|
resolveKeyboardDropTarget,
|
|
3560
|
+
resolveMenu,
|
|
2802
3561
|
resolveMessages,
|
|
2803
3562
|
resolveRowId,
|
|
2804
3563
|
resolveRows,
|
|
2805
3564
|
resolveShownRows,
|
|
3565
|
+
resolveToolbar,
|
|
2806
3566
|
revertColumnSize,
|
|
3567
|
+
runCommand,
|
|
3568
|
+
searchTextOf,
|
|
2807
3569
|
selectAll,
|
|
2808
3570
|
selectAllState,
|
|
2809
3571
|
selectCell,
|
|
@@ -2812,15 +3574,19 @@ export {
|
|
|
2812
3574
|
serializeGridState,
|
|
2813
3575
|
setColumnFilter,
|
|
2814
3576
|
setColumnVisibility,
|
|
3577
|
+
setSearchText,
|
|
2815
3578
|
sizeColumnToContent,
|
|
2816
3579
|
sortDirectionFor,
|
|
2817
3580
|
sortPriorityFor,
|
|
2818
3581
|
sortRows,
|
|
3582
|
+
splitToolbarItems,
|
|
2819
3583
|
toggleCellSelection,
|
|
2820
3584
|
toggleColumnSort,
|
|
2821
3585
|
toggleGroupExpansion,
|
|
2822
3586
|
toggleSelection,
|
|
3587
|
+
toolbarEntries,
|
|
2823
3588
|
totalColumnWidth,
|
|
3589
|
+
typeaheadIndex,
|
|
2824
3590
|
visibleFilterOptions,
|
|
2825
3591
|
visibleRange,
|
|
2826
3592
|
withGroupAggregates
|