@svgrid/grid 3.0.5 → 3.0.7
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 +28 -7
- package/dist/GridMenus.svelte +34 -4
- package/dist/SvGrid.controller.svelte.d.ts +23 -3
- package/dist/SvGrid.controller.svelte.js +235 -54
- package/dist/SvGrid.css +143 -7
- package/dist/SvGrid.helpers.js +2 -4
- package/dist/SvGrid.svelte +223 -38
- package/dist/SvGrid.types.d.ts +77 -4
- package/dist/SvGridDropdown.svelte +20 -0
- package/dist/SvGridDropdown.svelte.d.ts +12 -0
- package/dist/SvModal.svelte +22 -0
- package/dist/SvModal.svelte.d.ts +7 -0
- package/dist/a11y/dismissable.d.ts +10 -0
- package/dist/a11y/dismissable.js +24 -2
- package/dist/build-api.js +81 -31
- package/dist/cdn/{GridMenus-CID62rlI.js → GridMenus-BgUS-W3o.js} +151 -142
- package/dist/cdn/GridMenus-CcwU8I4t.js +644 -0
- package/dist/cdn/{SvChartMenu-FBSMINA6.js → SvChartMenu-BFSTpvB-.js} +1 -1
- package/dist/cdn/{SvChartMenu-Bl6PBbkT.js → SvChartMenu-BZ1Iwv0y.js} +1 -1
- package/dist/cdn/{SvDateTimePicker-DQwt4UAs.js → SvDateTimePicker-D9u_cOf8.js} +1 -1
- package/dist/cdn/{SvDateTimePicker-vNU6bZ-q.js → SvDateTimePicker-s_6IUpI7.js} +1 -1
- package/dist/cdn/{SvGridCellEditor-B1p-vCK5.js → SvGridCellEditor-9yz-SbdZ.js} +2 -2
- package/dist/cdn/{SvGridCellEditor-D_0q4xAu.js → SvGridCellEditor-D7-ql1Hd.js} +2 -2
- package/dist/cdn/{SvGridChart-C3EWAZaM.js → SvGridChart-DMUOFxOe.js} +4 -4
- package/dist/cdn/{SvGridChart-DzLkSwCH.js → SvGridChart-N7ik0oWy.js} +4 -4
- package/dist/cdn/{SvGridChartBuilder-CfII62sZ.js → SvGridChartBuilder-CB_Jnm2k.js} +4 -4
- package/dist/cdn/{SvGridChartBuilder-BE2T1ykB.js → SvGridChartBuilder-Ca7gF8ZK.js} +4 -4
- package/dist/cdn/{SvGridChartPanel-xf4sWVTo.js → SvGridChartPanel-9GOJRHP7.js} +5 -5
- package/dist/cdn/{SvGridChartPanel-CCX5_Wgd.js → SvGridChartPanel-Dl-FujN8.js} +5 -5
- package/dist/cdn/{SvGridChartView-CfuXmY5I.js → SvGridChartView-B1LFgoPP.js} +2 -2
- package/dist/cdn/{SvGridChartView-DYwabQWj.js → SvGridChartView-By3n7DGZ.js} +2 -2
- package/dist/cdn/{SvGridDropdown-D0VdjeR8.js → SvGridDropdown-BWeM3lMe.js} +46 -46
- package/dist/cdn/{SvGridDropdown-D13MtJ2j.js → SvGridDropdown-CJ6QqTxu.js} +67 -67
- package/dist/cdn/{SvModal-CIZWCcad.js → SvModal-ClxGmpAc.js} +187 -186
- package/dist/cdn/{SvModal-BAE-pjZX.js → SvModal-DhB_VMFR.js} +148 -147
- package/dist/cdn/{cell-formatting-C2Hf5gqd.js → cell-formatting-Mnv84zoE.js} +28 -6
- package/dist/cdn/{chart-Dz7SqMXH.js → chart-By7h2Guv.js} +1 -1
- package/dist/cdn/{chart-panel-messages-CUbf2R4i.js → chart-panel-messages-BC-tOgFY.js} +1 -1
- package/dist/cdn/{chart-panel-messages-CmNrMdsr.js → chart-panel-messages-DUaXr-sb.js} +1 -1
- package/dist/cdn/{chart-summary-BJW_tg_X.js → chart-summary-BDtrNEiA.js} +1 -1
- package/dist/cdn/{chart-trend-CaN9mDEV.js → chart-trend-C1aOAPBZ.js} +1 -1
- package/dist/cdn/{dismissable-DAHetSNk.js → dismissable-Brc4EZU1.js} +5 -1
- package/dist/cdn/{editor-registry-BhgE3S84.js → editor-registry-BVeHvlZR.js} +49 -50
- package/dist/cdn/{export-format-CUDLy2yn.js → export-format-y1wdyCcv.js} +93 -97
- package/dist/cdn/{row-resize-niQCp040.js → row-resize-DtOS1KG6.js} +41 -32
- package/dist/cdn/{server-block-cache-CGoWz-87.js → server-block-cache-DIqb3VZn.js} +4 -0
- package/dist/cdn/{src-jcFMkBnN.js → src-25JmJ_7g.js} +4768 -4149
- package/dist/cdn/{src-Bklofsad.js → src-kE9B98r6.js} +4796 -4177
- package/dist/cdn/svgrid.js +18 -18
- package/dist/cdn/svgrid.svelte-external.js +18 -18
- package/dist/cdn/{validate-C7Rn_Bns.js → validate-AZoD8BoR.js} +6 -2
- package/dist/cell-formatting.d.ts +9 -0
- package/dist/cell-formatting.js +52 -1
- package/dist/cell-render.js +25 -6
- package/dist/clipboard.d.ts +2 -2
- package/dist/clipboard.js +72 -23
- package/dist/columns.js +7 -2
- package/dist/conditional-formatting.d.ts +2 -0
- package/dist/conditional-formatting.js +2 -0
- package/dist/core.d.ts +22 -6
- package/dist/core.js +478 -40
- package/dist/editing.js +24 -0
- package/dist/export-format.d.ts +8 -0
- package/dist/export-format.js +23 -16
- package/dist/grid-messages.d.ts +4 -0
- package/dist/grid-messages.js +4 -0
- package/dist/headless.d.ts +5 -0
- package/dist/headless.js +12 -0
- package/dist/history.d.ts +21 -0
- package/dist/history.js +34 -4
- package/dist/index.d.ts +1 -1
- package/dist/keyboard-handlers.js +24 -1
- package/dist/keyboard.js +4 -0
- package/dist/row-drag-touch.d.ts +1 -1
- package/dist/row-drag.js +35 -1
- package/dist/row-model.d.ts +6 -0
- package/dist/row-resize.js +22 -1
- package/dist/selection.js +1 -1
- package/dist/server-block-cache.d.ts +5 -0
- package/dist/server-block-cache.js +8 -0
- package/dist/server-data-source.d.ts +35 -3
- package/dist/server-data-source.js +11 -2
- package/dist/server.d.ts +1 -1
- package/dist/sparkline.js +7 -5
- package/dist/svgrid-wrapper.types.d.ts +33 -0
- package/dist/validate.js +9 -1
- package/dist/virtualization/column-virtualizer.d.ts +1 -0
- package/dist/virtualization/svelte-virtualizer.svelte.d.ts +1 -0
- package/dist/virtualization/svelte-virtualizer.svelte.js +1 -0
- package/dist/virtualization/virtualizer.d.ts +3 -0
- package/dist/virtualization/virtualizer.js +14 -1
- package/package.json +6 -1
- package/src/GridMenus.svelte +34 -4
- package/src/SvGrid.controller.svelte.ts +236 -57
- package/src/SvGrid.css +143 -7
- package/src/SvGrid.helpers.ts +2 -4
- package/src/SvGrid.svelte +223 -38
- package/src/SvGrid.types.ts +77 -4
- package/src/SvGridDropdown.svelte +20 -0
- package/src/SvModal.svelte +22 -0
- package/src/SvModal.test.ts +30 -1
- package/src/a11y/dismissable.test.ts +10 -1
- package/src/a11y/dismissable.ts +22 -2
- package/src/build-api.ts +85 -27
- package/src/cell-formatting.test.ts +17 -0
- package/src/cell-formatting.ts +49 -1
- package/src/cell-render.test.ts +24 -2
- package/src/cell-render.ts +24 -8
- package/src/clipboard.test.ts +107 -0
- package/src/clipboard.ts +62 -23
- package/src/columns.test.ts +4 -4
- package/src/columns.ts +7 -2
- package/src/conditional-formatting.test.ts +8 -0
- package/src/conditional-formatting.ts +3 -0
- package/src/core.sort.test.ts +86 -0
- package/src/core.tick-repair.test.ts +287 -0
- package/src/core.ts +478 -40
- package/src/editing.test.ts +52 -0
- package/src/editing.ts +25 -0
- package/src/export-dates.test.ts +114 -0
- package/src/export-format.ts +26 -14
- package/src/grid-messages.test.ts +7 -0
- package/src/grid-messages.ts +10 -0
- package/src/headless.ts +24 -0
- package/src/history.test.ts +49 -1
- package/src/history.ts +48 -2
- package/src/index.ts +2 -0
- package/src/keyboard-handlers.coverage.test.ts +65 -0
- package/src/keyboard-handlers.ts +26 -1
- package/src/keyboard.ts +3 -0
- package/src/row-drag-touch.ts +2 -2
- package/src/row-drag.test.ts +51 -0
- package/src/row-drag.ts +35 -2
- package/src/row-model.ts +6 -0
- package/src/row-resize.ts +24 -1
- package/src/selection.ts +1 -1
- package/src/server-block-cache.test.ts +27 -0
- package/src/server-block-cache.ts +13 -0
- package/src/server-data-source.infinite.test.ts +62 -0
- package/src/server-data-source.test.ts +19 -0
- package/src/server-data-source.ts +48 -4
- package/src/server.ts +2 -0
- package/src/sparkline.test.ts +7 -0
- package/src/sparkline.ts +6 -4
- package/src/svgrid-wrapper.types.ts +32 -0
- package/src/svgrid.api.test.ts +21 -0
- package/src/svgrid.charting.test.ts +12 -4
- package/src/svgrid.context-menu.test.ts +12 -0
- package/src/svgrid.data-push.svelte.test.ts +94 -0
- package/src/svgrid.detail-rows.svelte.test.ts +187 -0
- package/src/svgrid.filter-menu-scroll.test.ts +9 -0
- package/src/svgrid.gantt-seam.test.ts +1 -1
- package/src/svgrid.live-update-paths.svelte.test.ts +186 -0
- package/src/svgrid.menu-scroll-close.test.ts +10 -0
- package/src/svgrid.row-model-seam.svelte.test.ts +16 -0
- package/src/svgrid.row-pinning.test.ts +15 -1
- package/src/svgrid.selection-bar-seam.test.ts +1 -1
- package/src/svgrid.sticky-groups.svelte.test.ts +145 -0
- package/src/svgrid.upsell-license.test.ts +1 -1
- package/src/test-setup.ts +12 -0
- package/src/transaction.test.ts +58 -0
- package/src/validate.ts +7 -1
- package/src/virtualization/svelte-virtualizer.svelte.ts +1 -0
- package/src/virtualization/virtualizer.test.ts +44 -0
- package/src/virtualization/virtualizer.ts +13 -1
- package/dist/cdn/GridMenus-DLL-qZeu.js +0 -635
package/dist/server.d.ts
CHANGED
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* a worker feeding a block cache, or `@svgrid/enterprise`'s own row model,
|
|
9
9
|
* whose unit tests run without the Svelte compiler.
|
|
10
10
|
*/
|
|
11
|
-
export { createServerDataSource, type ServerDataSource, type ServerSelectionRule, type ServerRequest, type ServerResult, type ServerController, type ServerControllerOptions, type ServerState, type ServerSortModel, type ServerFilterModel, type ServerAggregation, type ServerGroupRow, type ServerLeafRow, type ServerMoreRow, type ServerFooterRow, type ServerSkeletonRow, type ServerGrandTotalRow, type ServerPlaceholderRow, type ServerDisplayRow, } from './server-data-source.js';
|
|
11
|
+
export { createServerDataSource, type ServerDataSource, type ServerSelectionRule, type ServerRequest, type ServerResult, type ServerController, type ServerControllerOptions, type ServerState, type ServerSortModel, type ServerFilterModel, type ServerAggFn, type ServerAggregation, type ServerGroupRow, type ServerLeafRow, type ServerMoreRow, type ServerFooterRow, type ServerSkeletonRow, type ServerGrandTotalRow, type ServerPlaceholderRow, type ServerDisplayRow, type ServerDetailRow, } from './server-data-source.js';
|
|
12
12
|
export { createBlockCache, createRowPlaceholder, rowPlaceholderState, type BlockCache, type BlockCacheOptions, type BlockCacheState, type BlockFetchResult, type BlockState, } from './server-block-cache.js';
|
|
13
13
|
export { toServerFilterColumns, type GridRowModel, type GridFilterState, type GridRowModelSort, } from './row-model.js';
|
package/dist/sparkline.js
CHANGED
|
@@ -38,13 +38,15 @@ export function buildSparkline(values, cfg = {}) {
|
|
|
38
38
|
const barW = Math.max(1, slot - gap);
|
|
39
39
|
const mid = height / 2;
|
|
40
40
|
const h = innerH / 2;
|
|
41
|
-
const bars =
|
|
41
|
+
const bars = [];
|
|
42
|
+
values.forEach((v, i) => {
|
|
42
43
|
const x = pad + i * slot + (slot - barW) / 2;
|
|
44
|
+
// A win/loss sparkline marks a win up and a loss down; a zero is a
|
|
45
|
+
// blank gap, no mark at all, the way Excel draws one.
|
|
43
46
|
if (v > 0)
|
|
44
|
-
|
|
45
|
-
if (v < 0)
|
|
46
|
-
|
|
47
|
-
return { x, y: mid - 1, w: barW, h: 2, negative: false };
|
|
47
|
+
bars.push({ x, y: mid - h, w: barW, h, negative: false });
|
|
48
|
+
else if (v < 0)
|
|
49
|
+
bars.push({ x, y: mid, w: barW, h, negative: true });
|
|
48
50
|
});
|
|
49
51
|
return { ...base, linePath: '', areaPath: '', bars, lastPoint: null };
|
|
50
52
|
}
|
|
@@ -151,6 +151,12 @@ export type SvGridTransactionResult = {
|
|
|
151
151
|
* the component.
|
|
152
152
|
*/
|
|
153
153
|
export type SvGridApi<TFeatures extends TableFeatures, TData extends RowData> = {
|
|
154
|
+
/**
|
|
155
|
+
* The grid's root element (`.sv-grid-root`), or null before mount and
|
|
156
|
+
* after unmount. For measuring, focusing, or reading the theme the grid
|
|
157
|
+
* is drawn with - the PDF export takes its colours from here.
|
|
158
|
+
*/
|
|
159
|
+
getElement(): HTMLElement | null;
|
|
154
160
|
/** Read a cell value from the underlying data at `rowIndex`. */
|
|
155
161
|
getCellValue(rowIndex: number, columnId: string): unknown;
|
|
156
162
|
/** Write a cell value through the column's field. */
|
|
@@ -413,6 +419,15 @@ export type SvGridApi<TFeatures extends TableFeatures, TData extends RowData> =
|
|
|
413
419
|
getDisplayedRows(): ReadonlyArray<TData>;
|
|
414
420
|
/** Snapshot of the current data array (pre-pipeline). */
|
|
415
421
|
getData(): ReadonlyArray<TData>;
|
|
422
|
+
/**
|
|
423
|
+
* The stable id the grid keys a row by: what the `getRowId` prop
|
|
424
|
+
* computed, or the row's position when no `getRowId` is set. Pass a
|
|
425
|
+
* display index (the space `getActiveCell`, `scrollToRow` and the cell
|
|
426
|
+
* methods use) or a row object; returns null for an unknown index or a
|
|
427
|
+
* row that is not in the data. Pair with `selectRows`, `toggleRowSelected`
|
|
428
|
+
* or an `applyTransaction` remove, all of which take these ids.
|
|
429
|
+
*/
|
|
430
|
+
getRowId(row: number | TData): string | null;
|
|
416
431
|
/**
|
|
417
432
|
* Snapshot of every column the grid currently knows about, in visual
|
|
418
433
|
* order, with the human-readable header label. Use this when exporting
|
|
@@ -560,6 +575,24 @@ export type SvGridApi<TFeatures extends TableFeatures, TData extends RowData> =
|
|
|
560
575
|
canRedo(): boolean;
|
|
561
576
|
/** Wipe both stacks (e.g. after a server save commits the buffer). */
|
|
562
577
|
clearHistory(): void;
|
|
578
|
+
/**
|
|
579
|
+
* Mark every step recorded from now on with `tag`, until the next call;
|
|
580
|
+
* `undefined` stops the marking. The grid never reads the tag. It is for a
|
|
581
|
+
* consumer that shows one of several data sets through the grid (a
|
|
582
|
+
* workbook's sheets, say) and has to know which one the next Ctrl+Z would
|
|
583
|
+
* change before it lets the grid apply it: it tags the steps with the data
|
|
584
|
+
* set they were made on and asks `peekUndo` first.
|
|
585
|
+
*/
|
|
586
|
+
setHistoryTag(tag: unknown): void;
|
|
587
|
+
/** The step the next `undo()` would apply, or null when there is none. A
|
|
588
|
+
* multi-cell action carries one tag, so it reports as one. */
|
|
589
|
+
peekUndo(): {
|
|
590
|
+
tag: unknown;
|
|
591
|
+
} | null;
|
|
592
|
+
/** The step the next `redo()` would apply, or null when there is none. */
|
|
593
|
+
peekRedo(): {
|
|
594
|
+
tag: unknown;
|
|
595
|
+
} | null;
|
|
563
596
|
/**
|
|
564
597
|
* The same `GridCommandContext` a registered shortcut handler receives.
|
|
565
598
|
*
|
package/dist/validate.js
CHANGED
|
@@ -21,7 +21,15 @@ export function validateGridConfig(input) {
|
|
|
21
21
|
// (a key absent from row 0 but present later) does not trip it. A row
|
|
22
22
|
// model shows placeholder rows before its first block lands; those carry
|
|
23
23
|
// no data keys at all and say nothing about the columns.
|
|
24
|
-
|
|
24
|
+
// Stops at the sample size: this runs on every data change, and a filter
|
|
25
|
+
// over all the rows first was O(n) per tick on a live feed.
|
|
26
|
+
const sample = [];
|
|
27
|
+
for (const row of input.data ?? []) {
|
|
28
|
+
if (sample.length >= FIELD_SAMPLE_ROWS)
|
|
29
|
+
break;
|
|
30
|
+
if (!rowPlaceholderState(row))
|
|
31
|
+
sample.push(row);
|
|
32
|
+
}
|
|
25
33
|
// Under server-side grouping the first rows are group rows, which carry
|
|
26
34
|
// a key and aggregates and none of the leaf fields; nothing to judge by.
|
|
27
35
|
if (sample.length && !input.serverGroup) {
|
|
@@ -10,6 +10,7 @@ export declare function createColumnVirtualizer(input: {
|
|
|
10
10
|
setViewportWidth(viewportWidth: number): void;
|
|
11
11
|
setHorizontalOffset(scrollOffset: number): void;
|
|
12
12
|
setOptions(next: Partial<import("./types.js").VirtualizerOptions>): void;
|
|
13
|
+
measure(): void;
|
|
13
14
|
setScrollOffset(scrollOffset: number): void;
|
|
14
15
|
setViewportHeight(viewportHeight: number): void;
|
|
15
16
|
scrollToIndex(index: number): void;
|
|
@@ -2,6 +2,7 @@ import type { VirtualizerOptions } from './types.js';
|
|
|
2
2
|
export declare function createSvelteVirtualizer(options: VirtualizerOptions): {
|
|
3
3
|
readonly version: number;
|
|
4
4
|
setOptions: (next: Partial<VirtualizerOptions>) => void;
|
|
5
|
+
measure: () => void;
|
|
5
6
|
setScrollOffset: (scrollOffset: number) => void;
|
|
6
7
|
setViewportHeight: (viewportHeight: number) => void;
|
|
7
8
|
scrollToIndex: (index: number) => void;
|
|
@@ -10,6 +10,7 @@ export function createSvelteVirtualizer(options) {
|
|
|
10
10
|
return version;
|
|
11
11
|
},
|
|
12
12
|
setOptions: virtualizer.setOptions,
|
|
13
|
+
measure: virtualizer.measure,
|
|
13
14
|
setScrollOffset: virtualizer.setScrollOffset,
|
|
14
15
|
setViewportHeight: virtualizer.setViewportHeight,
|
|
15
16
|
scrollToIndex: virtualizer.scrollToIndex,
|
|
@@ -16,6 +16,9 @@ type VirtualizerListener = () => void;
|
|
|
16
16
|
export declare function buildPreMeasureItems(count: number, estimateSize: number, viewportHeight: number, overscan: number): Array<VirtualItem>;
|
|
17
17
|
export declare function createVirtualizer(initial: VirtualizerOptions): {
|
|
18
18
|
setOptions(next: Partial<VirtualizerOptions>): void;
|
|
19
|
+
/** Drop the cached offsets and re-read every size from `estimateSize`.
|
|
20
|
+
* Call after the sizes a stable size function reports have changed. */
|
|
21
|
+
measure(): void;
|
|
19
22
|
setScrollOffset(scrollOffset: number): void;
|
|
20
23
|
setViewportHeight(viewportHeight: number): void;
|
|
21
24
|
scrollToIndex(index: number): void;
|
|
@@ -210,9 +210,22 @@ export function createVirtualizer(initial) {
|
|
|
210
210
|
return {
|
|
211
211
|
setOptions(next) {
|
|
212
212
|
const merged = { ...options, ...next };
|
|
213
|
-
|
|
213
|
+
// Passing a size function means "sizes may have changed", even when it is
|
|
214
|
+
// the same reference: the documented variable-height pattern is a stable
|
|
215
|
+
// function reading a mutable map, and keying the cache on identity alone
|
|
216
|
+
// left the offsets and total stale after a row grew (#102).
|
|
217
|
+
const remeasure = typeof next.estimateSize === 'function';
|
|
218
|
+
if (!remeasure && sameOptions(options, merged))
|
|
214
219
|
return;
|
|
215
220
|
options = merged;
|
|
221
|
+
if (remeasure)
|
|
222
|
+
offsetCache = null;
|
|
223
|
+
recalc();
|
|
224
|
+
},
|
|
225
|
+
/** Drop the cached offsets and re-read every size from `estimateSize`.
|
|
226
|
+
* Call after the sizes a stable size function reports have changed. */
|
|
227
|
+
measure() {
|
|
228
|
+
offsetCache = null;
|
|
216
229
|
recalc();
|
|
217
230
|
},
|
|
218
231
|
setScrollOffset(scrollOffset) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgrid/grid",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7",
|
|
4
4
|
"description": "Svelte 5-native data grid and data table. Headless-first engine with virtual scrolling for 100k+ rows, Excel-style filtering, inline editing, grouping, tree data, pivot, and server-side data. Drop-in <SvGrid> component. TypeScript, SSR-ready.",
|
|
5
5
|
"author": "jQWidgets <boikom@jqwidgets.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -94,6 +94,11 @@
|
|
|
94
94
|
"svelte": "./dist/filtering/excel-filters.js",
|
|
95
95
|
"import": "./dist/filtering/excel-filters.js"
|
|
96
96
|
},
|
|
97
|
+
"./sparkline": {
|
|
98
|
+
"types": "./dist/sparkline.d.ts",
|
|
99
|
+
"svelte": "./dist/sparkline.js",
|
|
100
|
+
"import": "./dist/sparkline.js"
|
|
101
|
+
},
|
|
97
102
|
"./shortcuts": {
|
|
98
103
|
"types": "./dist/shortcut-registry.d.ts",
|
|
99
104
|
"svelte": "./dist/shortcut-registry.js",
|
package/src/GridMenus.svelte
CHANGED
|
@@ -214,6 +214,19 @@
|
|
|
214
214
|
});
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Whether a column's active filter operator is one of the set operators,
|
|
219
|
+
* read at event time from component state: the condition input's focus
|
|
220
|
+
* and blur handlers cannot depend on a template `@const`, because blur
|
|
221
|
+
* also fires while the popover is being torn down, after that const's
|
|
222
|
+
* effect is gone.
|
|
223
|
+
*/
|
|
224
|
+
function isSetOperatorFor(colId: string): boolean {
|
|
225
|
+
const column = allColumns.find((c) => c.id === colId);
|
|
226
|
+
const op = filterMenuValues[colId]?.operator ?? defaultOperatorFor(column);
|
|
227
|
+
return op === "in" || op === "notIn";
|
|
228
|
+
}
|
|
229
|
+
|
|
217
230
|
/** Enter anywhere in the panel means "done" - filtering is already live. */
|
|
218
231
|
function onFilterPanelKeydown(event: KeyboardEvent) {
|
|
219
232
|
if (event.key !== "Enter" || event.shiftKey) return;
|
|
@@ -286,8 +299,23 @@
|
|
|
286
299
|
const saveComment = $derived(ctrl.saveComment);
|
|
287
300
|
const removeComment = $derived(ctrl.removeComment);
|
|
288
301
|
const closeCommentEditor = $derived(ctrl.closeCommentEditor);
|
|
302
|
+
|
|
303
|
+
function onContextMenuKeydown(event: KeyboardEvent) {
|
|
304
|
+
// Escape closes the context menu, the way every spreadsheet and desktop
|
|
305
|
+
// app does. The backdrop closes it on a click, but a keyboard user who
|
|
306
|
+
// opened it (Shift+F10, the Menu key) otherwise has no way out, and the
|
|
307
|
+
// menu sits over the sheet swallowing every other key. Handled at the
|
|
308
|
+
// window so it works whatever holds focus while the menu is open.
|
|
309
|
+
if (contextMenuFor && (event.key === "Escape" || event.key === "Esc")) {
|
|
310
|
+
event.preventDefault();
|
|
311
|
+
event.stopPropagation();
|
|
312
|
+
closeContextMenu();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
289
315
|
</script>
|
|
290
316
|
|
|
317
|
+
<svelte:window onkeydown={onContextMenuKeydown} />
|
|
318
|
+
|
|
291
319
|
{#if tooltip}
|
|
292
320
|
<!-- Custom hover tooltip. Floats above the grid; positioned by
|
|
293
321
|
showTooltipFor(). Notes and column tooltips both surface here. -->
|
|
@@ -396,10 +424,12 @@
|
|
|
396
424
|
: menuActiveOperator === "regex"
|
|
397
425
|
? "Pattern..."
|
|
398
426
|
: "Filter value..."}
|
|
399
|
-
onfocus={
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
onblur={
|
|
427
|
+
onfocus={(event) => {
|
|
428
|
+
if (isSetOperatorFor(colId)) onSetOpFilterFocus(event.currentTarget as HTMLInputElement, colId);
|
|
429
|
+
}}
|
|
430
|
+
onblur={() => {
|
|
431
|
+
if (isSetOperatorFor(colId)) closeInSuggest();
|
|
432
|
+
}}
|
|
403
433
|
oninput={(event) => {
|
|
404
434
|
const input = event.currentTarget as HTMLInputElement;
|
|
405
435
|
updateFilterMenuValue(colId, input.value);
|