@svgrid/grid 1.0.0 → 1.1.0
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/LICENSE +1 -1
- package/README.md +137 -39
- package/dist/GridFooter.svelte +164 -0
- package/dist/GridFooter.svelte.d.ts +29 -0
- package/dist/GridMenus.svelte +570 -0
- package/dist/GridMenus.svelte.d.ts +31 -0
- package/dist/SvGrid.controller.svelte.d.ts +429 -0
- package/dist/SvGrid.controller.svelte.js +1732 -0
- package/dist/SvGrid.css +1709 -0
- package/dist/SvGrid.helpers.d.ts +35 -0
- package/dist/SvGrid.helpers.js +160 -0
- package/dist/SvGrid.svelte +344 -7043
- package/dist/SvGrid.svelte.d.ts +4 -357
- package/dist/SvGrid.types.d.ts +436 -0
- package/dist/SvGrid.types.js +1 -0
- package/dist/SvGridChart.svelte +1060 -23
- package/dist/SvGridChart.svelte.d.ts +17 -0
- package/dist/build-api.d.ts +5 -0
- package/dist/build-api.js +527 -0
- package/dist/cell-render.d.ts +15 -0
- package/dist/cell-render.js +246 -0
- package/dist/cell-values.d.ts +28 -0
- package/dist/cell-values.js +89 -0
- package/dist/chart.d.ts +370 -3
- package/dist/chart.js +1135 -42
- package/dist/clipboard.d.ts +15 -0
- package/dist/clipboard.js +356 -0
- package/dist/columns.d.ts +30 -0
- package/dist/columns.js +277 -0
- package/dist/core.d.ts +1 -1
- package/dist/css.d.ts +3 -0
- package/dist/editing.d.ts +24 -0
- package/dist/editing.js +343 -0
- package/dist/editors/cell-editors.d.ts +1 -1
- package/dist/facet-buckets.d.ts +13 -0
- package/dist/facet-buckets.js +54 -0
- package/dist/features.d.ts +5 -0
- package/dist/features.js +30 -0
- package/dist/filter-operators.d.ts +16 -0
- package/dist/filter-operators.js +69 -0
- package/dist/hyperformula-adapter.d.ts +82 -0
- package/dist/hyperformula-adapter.js +73 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/keyboard-handlers.d.ts +7 -0
- package/dist/keyboard-handlers.js +197 -0
- package/dist/menus.d.ts +40 -0
- package/dist/menus.js +389 -0
- package/dist/named-views.d.ts +27 -0
- package/dist/named-views.js +39 -0
- package/dist/row-resize.d.ts +43 -0
- package/dist/row-resize.js +158 -0
- package/dist/scroll-sync.d.ts +9 -0
- package/dist/scroll-sync.js +86 -0
- package/dist/selection.d.ts +26 -0
- package/dist/selection.js +387 -0
- package/dist/spreadsheet.d.ts +80 -0
- package/dist/spreadsheet.js +194 -0
- package/dist/summaries.d.ts +12 -0
- package/dist/summaries.js +65 -0
- package/dist/sv-grid-scrollbar.js +7 -1
- package/dist/svgrid-wrapper.types.d.ts +12 -1
- package/dist/svgrid.comments-autocomplete.test.d.ts +1 -0
- package/dist/svgrid.comments-autocomplete.test.js +96 -0
- package/dist/svgrid.context-menu.test.d.ts +1 -0
- package/dist/svgrid.context-menu.test.js +102 -0
- package/dist/svgrid.new-features.wrapper.test.js +30 -4
- package/dist/svgrid.wrapper.test.js +27 -1
- package/dist/virtualization/column-virtualizer.d.ts +2 -0
- package/dist/virtualization/scroll-scaling.d.ts +28 -0
- package/dist/virtualization/scroll-scaling.js +64 -0
- package/dist/virtualization/scroll-scaling.test.d.ts +1 -0
- package/dist/virtualization/scroll-scaling.test.js +86 -0
- package/dist/virtualization/svelte-virtualizer.svelte.d.ts +2 -0
- package/dist/virtualization/svelte-virtualizer.svelte.js +2 -0
- package/dist/virtualization/virtualizer.d.ts +7 -0
- package/dist/virtualization/virtualizer.js +30 -0
- package/package.json +1 -1
- package/src/GridFooter.svelte +164 -0
- package/src/GridMenus.svelte +570 -0
- package/src/SvGrid.controller.svelte.ts +2195 -0
- package/src/SvGrid.css +1747 -0
- package/src/SvGrid.helpers.test.ts +415 -0
- package/src/SvGrid.helpers.ts +185 -0
- package/src/SvGrid.svelte +348 -7043
- package/src/SvGrid.types.ts +456 -0
- package/src/SvGridChart.svelte +1060 -23
- package/src/build-api.coverage.test.ts +532 -0
- package/src/build-api.ts +663 -0
- package/src/cell-render.test.ts +451 -0
- package/src/cell-render.ts +426 -0
- package/src/cell-values.ts +114 -0
- package/src/chart-export.test.ts +370 -0
- package/src/chart.coverage.test.ts +814 -0
- package/src/chart.ts +1352 -47
- package/src/clipboard.test.ts +731 -0
- package/src/clipboard.ts +524 -0
- package/src/collaboration.coverage.test.ts +220 -0
- package/src/columns.test.ts +702 -0
- package/src/columns.ts +419 -0
- package/src/core.ts +8 -0
- package/src/css.d.ts +3 -0
- package/src/editing.test.ts +837 -0
- package/src/editing.ts +513 -0
- package/src/editors/cell-editors.coverage.test.ts +156 -0
- package/src/editors/cell-editors.ts +1 -0
- package/src/facet-buckets.test.ts +353 -0
- package/src/facet-buckets.ts +67 -0
- package/src/features.ts +128 -0
- package/src/filter-operators.test.ts +174 -0
- package/src/filter-operators.ts +87 -0
- package/src/hyperformula-adapter.test.ts +256 -0
- package/src/hyperformula-adapter.ts +124 -0
- package/src/index.ts +37 -0
- package/src/keyboard-handlers.coverage.test.ts +560 -0
- package/src/keyboard-handlers.ts +353 -0
- package/src/keyboard.ts +97 -97
- package/src/menus.test.ts +620 -0
- package/src/menus.ts +554 -0
- package/src/named-views.coverage.test.ts +210 -0
- package/src/named-views.ts +48 -0
- package/src/row-resize.test.ts +369 -0
- package/src/row-resize.ts +171 -0
- package/src/scroll-sync.test.ts +330 -0
- package/src/scroll-sync.ts +216 -0
- package/src/selection.test.ts +722 -0
- package/src/selection.ts +545 -0
- package/src/server-data-source.coverage.test.ts +180 -0
- package/src/spreadsheet.test.ts +445 -0
- package/src/spreadsheet.ts +246 -0
- package/src/summaries.ts +204 -0
- package/src/sv-grid-scrollbar.ts +21 -2
- package/src/svgrid-wrapper.types.ts +12 -1
- package/src/svgrid.behavior.test.ts +22 -0
- package/src/svgrid.comments-autocomplete.test.ts +112 -0
- package/src/svgrid.context-menu.test.ts +126 -0
- package/src/svgrid.interaction.test.ts +30 -0
- package/src/svgrid.new-features.wrapper.test.ts +65 -4
- package/src/svgrid.wrapper.test.ts +27 -1
- package/src/test-setup.ts +9 -6
- package/src/virtualization/scroll-scaling.test.ts +148 -0
- package/src/virtualization/scroll-scaling.ts +121 -0
- package/src/virtualization/svelte-virtualizer.svelte.ts +2 -0
- package/src/virtualization/virtualizer.ts +26 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// scroll-sync handlers extracted from the controller. Imperative event handlers
|
|
2
|
+
// reading/writing controller state via the `ctx` handle; the reactive core
|
|
3
|
+
// ($state/$derived/$effect) stays in the controller.
|
|
4
|
+
import {
|
|
5
|
+
applyExcelFilter,
|
|
6
|
+
normalizeForFilter,
|
|
7
|
+
createColumnVirtualizer,
|
|
8
|
+
createCoreRowModel,
|
|
9
|
+
createExpandedRowModel,
|
|
10
|
+
createFilteredRowModel,
|
|
11
|
+
createGroupedRowModel,
|
|
12
|
+
createPaginatedRowModel,
|
|
13
|
+
createSvelteVirtualizer,
|
|
14
|
+
createSortedRowModel,
|
|
15
|
+
createSvGrid,
|
|
16
|
+
filterFns,
|
|
17
|
+
getGridCellA11yProps,
|
|
18
|
+
getGridCellDomId,
|
|
19
|
+
getGridHeaderA11yProps,
|
|
20
|
+
getGridRootA11yProps,
|
|
21
|
+
getGridRowA11yProps,
|
|
22
|
+
parseEditorValue,
|
|
23
|
+
normalizeEditorOptions,
|
|
24
|
+
sortFns,
|
|
25
|
+
tableFeatures,
|
|
26
|
+
rowSortingFeature,
|
|
27
|
+
columnFilteringFeature,
|
|
28
|
+
columnGroupingFeature,
|
|
29
|
+
type CellContext,
|
|
30
|
+
type EditorContext,
|
|
31
|
+
type CellEditorOption,
|
|
32
|
+
type CellEditorType,
|
|
33
|
+
type CellFormatter,
|
|
34
|
+
type CellFormatConfig,
|
|
35
|
+
type Column,
|
|
36
|
+
type ColumnDef,
|
|
37
|
+
type Row,
|
|
38
|
+
type RowData,
|
|
39
|
+
type SvGridApi,
|
|
40
|
+
type TableFeatures,
|
|
41
|
+
} from "./index";
|
|
42
|
+
import "./sv-grid-scrollbar";
|
|
43
|
+
import type { Snippet } from "svelte";
|
|
44
|
+
import { getKeyboardIntent, getNextActiveCell } from "./keyboard";
|
|
45
|
+
import {
|
|
46
|
+
formatNumericWithConfig,
|
|
47
|
+
getDateFormatter,
|
|
48
|
+
resolveDatePattern,
|
|
49
|
+
} from "./cell-formatting";
|
|
50
|
+
import {
|
|
51
|
+
RenderSnippetConfig,
|
|
52
|
+
RenderComponentConfig,
|
|
53
|
+
} from "./render-component";
|
|
54
|
+
import { buildFillPattern } from "./fill-patterns";
|
|
55
|
+
import { buildSparkline, toSparklineValues } from "./sparkline";
|
|
56
|
+
import {
|
|
57
|
+
resolveCellFormat,
|
|
58
|
+
computeColumnStat,
|
|
59
|
+
formatsNeedingStats,
|
|
60
|
+
type ColumnStat,
|
|
61
|
+
type ResolvedCellFormat,
|
|
62
|
+
} from "./conditional-formatting";
|
|
63
|
+
import SvGridDropdown from "./SvGridDropdown.svelte";
|
|
64
|
+
import type {
|
|
65
|
+
Props,
|
|
66
|
+
SelectionPoint,
|
|
67
|
+
SelectionRange,
|
|
68
|
+
CellEditState,
|
|
69
|
+
FilterOperator,
|
|
70
|
+
FilterOption,
|
|
71
|
+
MenuPosition,
|
|
72
|
+
} from "./SvGrid.types";
|
|
73
|
+
import {
|
|
74
|
+
cfTextStyle,
|
|
75
|
+
fmtStat,
|
|
76
|
+
getCellKey,
|
|
77
|
+
resolveClassList,
|
|
78
|
+
toDateInputValue,
|
|
79
|
+
toDateTimeLocalInputValue,
|
|
80
|
+
getEditableInputValue,
|
|
81
|
+
getEditorInputType,
|
|
82
|
+
toValueArray,
|
|
83
|
+
getOptionLabel,
|
|
84
|
+
getOptionColor,
|
|
85
|
+
colorfulChipStyle,
|
|
86
|
+
getEditorClass,
|
|
87
|
+
asDate,
|
|
88
|
+
clampMenuX,
|
|
89
|
+
cssEscape,
|
|
90
|
+
rawToNumber,
|
|
91
|
+
formatFacetNumber,
|
|
92
|
+
formatFacetDate,
|
|
93
|
+
} from "./SvGrid.helpers";
|
|
94
|
+
import { createKeyboard } from "./keyboard-handlers";
|
|
95
|
+
import { createSummaries } from "./summaries";
|
|
96
|
+
import { createMenus } from "./menus";
|
|
97
|
+
import { createCellRender } from "./cell-render";
|
|
98
|
+
import { createEditing } from "./editing";
|
|
99
|
+
import { createSelection } from "./selection";
|
|
100
|
+
import { createColumns } from "./columns";
|
|
101
|
+
import { createGridApi } from "./build-api";
|
|
102
|
+
import { createClipboard } from "./clipboard";
|
|
103
|
+
import {
|
|
104
|
+
filterOperatorOptions,
|
|
105
|
+
fallbackOperatorOption,
|
|
106
|
+
TEXT_OPERATORS,
|
|
107
|
+
NUMBER_OPERATORS,
|
|
108
|
+
DATE_OPERATORS,
|
|
109
|
+
CHECKBOX_OPERATORS,
|
|
110
|
+
operatorOption,
|
|
111
|
+
operatorsForColumn,
|
|
112
|
+
defaultOperatorFor,
|
|
113
|
+
operatorLabelFor,
|
|
114
|
+
} from "./filter-operators";
|
|
115
|
+
import {
|
|
116
|
+
type FacetBucket,
|
|
117
|
+
isBucketableColumn,
|
|
118
|
+
buildBuckets,
|
|
119
|
+
isInBucket,
|
|
120
|
+
} from "./facet-buckets";
|
|
121
|
+
import {
|
|
122
|
+
getColumnBaseValue,
|
|
123
|
+
isGroupRow,
|
|
124
|
+
toolPanelHeaderLabel,
|
|
125
|
+
formatSummaryNumeric,
|
|
126
|
+
getColumnAlign,
|
|
127
|
+
getPinnedCellValue,
|
|
128
|
+
getColumnAccessorValue,
|
|
129
|
+
columnDefMatchesId,
|
|
130
|
+
} from "./cell-values";
|
|
131
|
+
|
|
132
|
+
export function createScrollSync<
|
|
133
|
+
TFeatures extends TableFeatures = TableFeatures,
|
|
134
|
+
TData extends RowData = RowData,
|
|
135
|
+
>(ctx: any) {
|
|
136
|
+
function showTooltipFor(el: HTMLElement, text: string) {
|
|
137
|
+
if (!text) return
|
|
138
|
+
if (ctx.tooltipTimer) window.clearTimeout(ctx.tooltipTimer)
|
|
139
|
+
ctx.tooltipTimer = window.setTimeout(() => {
|
|
140
|
+
const rect = el.getBoundingClientRect()
|
|
141
|
+
const vw = window.innerWidth
|
|
142
|
+
const vh = window.innerHeight
|
|
143
|
+
const below = rect.bottom + 64 < vh
|
|
144
|
+
// Clamp x so the 280px-wide tooltip doesn't fall off the viewport.
|
|
145
|
+
const x = Math.min(Math.max(rect.left + 6, 10), vw - 290)
|
|
146
|
+
const y = below ? rect.bottom + 6 : rect.top - 6
|
|
147
|
+
ctx.tooltip = { text, x, y, below }
|
|
148
|
+
}, 250)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function hideTooltip() {
|
|
152
|
+
if (ctx.tooltipTimer) { window.clearTimeout(ctx.tooltipTimer); ctx.tooltipTimer = null }
|
|
153
|
+
ctx.tooltip = null
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function flushScheduledScrollSync() {
|
|
157
|
+
ctx.scrollSyncRaf = null;
|
|
158
|
+
ctx.scrollVersion += 1;
|
|
159
|
+
if (ctx.rowVirtualizationEnabled)
|
|
160
|
+
ctx.virtualizer.setScrollOffset(ctx.domToLogicalRowOffset(ctx.pendingScrollTop));
|
|
161
|
+
if (ctx.columnVirtualizationEnabled)
|
|
162
|
+
ctx.columnVirtualizer.setHorizontalOffset(ctx.pendingScrollLeft);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Sync the virtualizer to the user's scroll position once per frame.
|
|
167
|
+
*
|
|
168
|
+
* The browser's smooth-scroll animation fires a `scroll` event on
|
|
169
|
+
* every frame of the ~250 ms ramp after each wheel notch - so a
|
|
170
|
+
* single wheel notch produces ~16 calls to `onBodyScroll`. Without
|
|
171
|
+
* batching, each one ran a full virtualizer recalc + Svelte re-render
|
|
172
|
+
* synchronously, which (a) made the work pile up on heavy demos and
|
|
173
|
+
* (b) read on screen as "the grid keeps scrolling after the wheel
|
|
174
|
+
* stopped" because each scroll event ticked the rendered window one
|
|
175
|
+
* row at a time over a quarter-second.
|
|
176
|
+
*
|
|
177
|
+
* Batching to a single rAF flush per frame means each animation
|
|
178
|
+
* frame produces ONE virtualizer update at the latest known scroll
|
|
179
|
+
* position. Smooth-scroll still feels smooth (the browser is still
|
|
180
|
+
* animating `scrollTop`), but the grid's per-frame cost is bounded
|
|
181
|
+
* and the visible rows match the current `scrollTop` exactly when
|
|
182
|
+
* the wheel stops - no trailing updates.
|
|
183
|
+
*/
|
|
184
|
+
function scheduleScrollSync(scrollTop: number, scrollLeft: number) {
|
|
185
|
+
ctx.pendingScrollTop = scrollTop;
|
|
186
|
+
ctx.pendingScrollLeft = scrollLeft;
|
|
187
|
+
if (ctx.scrollSyncRaf !== null) return;
|
|
188
|
+
ctx.scrollSyncRaf = requestAnimationFrame(flushScheduledScrollSync);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function onBodyScroll(event: Event) {
|
|
192
|
+
const container = event.currentTarget as HTMLDivElement | null;
|
|
193
|
+
if (!container) return;
|
|
194
|
+
if (ctx.columnMenuFor || ctx.operatorMenuFor) ctx.closeMenus();
|
|
195
|
+
scheduleScrollSync(container.scrollTop, container.scrollLeft);
|
|
196
|
+
|
|
197
|
+
if (ctx.props.onScrollBottomReached) {
|
|
198
|
+
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
199
|
+
const atBottom = scrollTop + clientHeight >= scrollHeight - 32;
|
|
200
|
+
if (atBottom && ctx.scrollBottomArmed) {
|
|
201
|
+
ctx.scrollBottomArmed = false;
|
|
202
|
+
ctx.props.onScrollBottomReached({ scrollTop, scrollHeight, clientHeight });
|
|
203
|
+
} else if (!atBottom && !ctx.scrollBottomArmed) {
|
|
204
|
+
ctx.scrollBottomArmed = true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
showTooltipFor,
|
|
211
|
+
hideTooltip,
|
|
212
|
+
flushScheduledScrollSync,
|
|
213
|
+
scheduleScrollSync,
|
|
214
|
+
onBodyScroll,
|
|
215
|
+
};
|
|
216
|
+
}
|