@svgrid/grid 2.6.21 → 2.6.23
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/CHANGELOG.md +62 -0
- package/README.md +22 -0
- package/dist/GridMenus.svelte +201 -18
- package/dist/SvAutoComplete.svelte +4 -0
- package/dist/SvComboBox.svelte +5 -1
- package/dist/SvDateRangeInput.svelte +25 -3
- package/dist/SvDropDownList.svelte +4 -0
- package/dist/SvForm.svelte +8 -8
- package/dist/SvGrid.controller.svelte.d.ts +61 -9
- package/dist/SvGrid.controller.svelte.js +363 -123
- package/dist/SvGrid.css +222 -1
- package/dist/SvGrid.helpers.d.ts +55 -0
- package/dist/SvGrid.helpers.js +83 -0
- package/dist/SvGrid.svelte +255 -56
- package/dist/SvGrid.types.d.ts +146 -1
- package/dist/SvGridCellEditor.svelte +99 -17
- package/dist/SvGridSelect.svelte +6 -2
- package/dist/SvGridSelect.svelte.d.ts +1 -1
- package/dist/SvListBox.svelte +8 -0
- package/dist/SvMultiSelect.svelte +6 -2
- package/dist/SvMultiSelect.svelte.d.ts +1 -1
- package/dist/SvNumberInput.svelte +4 -0
- package/dist/SvRichCell.svelte +125 -0
- package/dist/SvRichCell.svelte.d.ts +15 -0
- package/dist/SvTextArea.svelte +5 -1
- package/dist/SvTreeSelect.svelte +6 -2
- package/dist/SvTreeSelect.svelte.d.ts +1 -1
- package/dist/builtin-editors.d.ts +2 -2
- package/dist/builtin-editors.js +19 -3
- package/dist/cdn/GridMenus-BzWXQjv3.js +600 -0
- package/dist/cdn/GridMenus-xr_rHx8F.js +601 -0
- package/dist/cdn/SvDateRangeInput-CaOuMs8O.js +198 -0
- package/dist/cdn/SvDateRangeInput-DMLKmGEc.js +199 -0
- package/dist/cdn/SvDateTimePicker-CCbDZNZB.js +816 -0
- package/dist/cdn/SvDateTimePicker-sonaH0oh.js +812 -0
- package/dist/cdn/SvGridCellEditor-BAPSC7EL.js +550 -0
- package/dist/cdn/SvGridCellEditor-BwzmUWtL.js +549 -0
- package/dist/cdn/column-resize-DsfNXMom.js +102 -0
- package/dist/cdn/date-format-BNii4zeD.js +1393 -0
- package/dist/cdn/date-format-BnnHlqGw.js +1395 -0
- package/dist/cdn/{editor-registry-CiI0xlKg.js → editor-registry-BhgE3S84.js} +51 -25
- package/dist/cdn/row-resize-BRcimkUT.js +95 -0
- package/dist/cdn/{src-DBel9wRZ.js → src-DGo7IHug.js} +10017 -9488
- package/dist/cdn/{src-BYq-qyrp.js → src-skQN5eqh.js} +7829 -7300
- package/dist/cdn/svgrid.js +14 -10
- package/dist/cdn/svgrid.svelte-external.js +14 -10
- package/dist/cell-values.d.ts +16 -0
- package/dist/cell-values.js +28 -0
- package/dist/clipboard.d.ts +22 -0
- package/dist/clipboard.js +405 -27
- package/dist/column-groups.js +1 -1
- package/dist/column-resize.d.ts +46 -0
- package/dist/column-resize.js +205 -0
- package/dist/columns.d.ts +0 -3
- package/dist/columns.js +0 -57
- package/dist/core.d.ts +19 -4
- package/dist/core.js +460 -119
- package/dist/editing.js +12 -7
- package/dist/editors/cell-editors.d.ts +11 -0
- package/dist/editors/cell-editors.js +18 -1
- package/dist/filtering/excel-filters.js +28 -0
- package/dist/grid-messages.d.ts +15 -0
- package/dist/grid-messages.js +15 -0
- package/dist/group-display.d.ts +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +10 -0
- package/dist/list-option.d.ts +6 -0
- package/dist/menus.js +41 -8
- package/dist/row-resize.d.ts +11 -0
- package/dist/row-resize.js +7 -1
- package/dist/sanitize-html.d.ts +37 -0
- package/dist/sanitize-html.js +234 -0
- package/dist/selection-bar-view.svelte.d.ts +25 -0
- package/dist/selection-bar-view.svelte.js +13 -0
- package/dist/selection.d.ts +2 -1
- package/dist/selection.js +133 -8
- package/dist/spreadsheet.d.ts +1 -1
- package/dist/spreadsheet.js +1 -1
- package/package.json +1 -1
- package/src/GridMenus.svelte +201 -18
- package/src/SvAutoComplete.svelte +4 -0
- package/src/SvComboBox.svelte +5 -1
- package/src/SvDateRangeInput.svelte +25 -3
- package/src/SvDropDownList.svelte +4 -0
- package/src/SvForm.svelte +8 -8
- package/src/SvGrid.controller.svelte.ts +404 -133
- package/src/SvGrid.css +222 -1
- package/src/SvGrid.helpers.ts +87 -0
- package/src/SvGrid.svelte +255 -56
- package/src/SvGrid.types.ts +153 -1
- package/src/SvGridCellEditor.svelte +99 -17
- package/src/SvGridSelect.svelte +6 -2
- package/src/SvListBox.svelte +8 -0
- package/src/SvMultiSelect.svelte +6 -2
- package/src/SvNumberInput.svelte +4 -0
- package/src/SvRichCell.svelte +125 -0
- package/src/SvTextArea.svelte +5 -1
- package/src/SvTreeSelect.svelte +6 -2
- package/src/builtin-editors.test.ts +18 -1
- package/src/builtin-editors.ts +19 -3
- package/src/cell-values.ts +30 -0
- package/src/clipboard.test.ts +93 -20
- package/src/clipboard.ts +433 -33
- package/src/column-groups.ts +1 -1
- package/src/column-resize.test.ts +381 -0
- package/src/column-resize.ts +227 -0
- package/src/columns.test.ts +0 -103
- package/src/columns.ts +0 -58
- package/src/core.aggregate.test.ts +134 -0
- package/src/core.filter.test.ts +156 -0
- package/src/core.grouping.test.ts +146 -0
- package/src/core.row-shape.test.ts +119 -0
- package/src/core.rowmodel-cache.test.ts +121 -0
- package/src/core.sort.test.ts +293 -0
- package/src/core.ts +516 -119
- package/src/date-string-column.test.ts +87 -0
- package/src/editing.test.ts +25 -0
- package/src/editing.ts +12 -9
- package/src/editor-block-prop.test.ts +132 -0
- package/src/editors/cell-editors.ts +27 -1
- package/src/filtering/excel-filters.ts +30 -0
- package/src/filtering/normalize-fast-path.test.ts +104 -0
- package/src/grid-messages.ts +34 -0
- package/src/group-display.ts +1 -1
- package/src/index.ts +25 -1
- package/src/list-option.ts +6 -0
- package/src/menus.test.ts +43 -0
- package/src/menus.ts +38 -8
- package/src/move-cells.test.ts +850 -0
- package/src/number-editor-literal.test.ts +84 -0
- package/src/number-editor.grid.test.ts +160 -0
- package/src/resize-props.test.ts +361 -0
- package/src/row-resize.test.ts +31 -0
- package/src/row-resize.ts +21 -3
- package/src/sanitize-html.test.ts +182 -0
- package/src/sanitize-html.ts +235 -0
- package/src/selection-bar-view.svelte.ts +36 -0
- package/src/selection.test.ts +157 -0
- package/src/selection.ts +135 -8
- package/src/spreadsheet.ts +1 -1
- package/src/svgrid.filter-menu-listbox.svelte.test.ts +56 -10
- package/src/svgrid.in-suggest-snapshot.svelte.test.ts +91 -0
- package/src/svgrid.menu-scroll-close.test.ts +204 -0
- package/src/svgrid.selection-bar-seam.test.ts +185 -0
- package/src/svgrid.upsell-license.test.ts +117 -0
- package/dist/cdn/GridMenus-BfTAKn84.js +0 -488
- package/dist/cdn/GridMenus-C3bJd7w8.js +0 -489
- package/dist/cdn/SvDateTimePicker-CHnUkWcH.js +0 -2206
- package/dist/cdn/SvDateTimePicker-CRQH_U7E.js +0 -2201
- package/dist/cdn/SvGridCellEditor-BGUCzuPB.js +0 -523
- package/dist/cdn/SvGridCellEditor-G8IMWIws.js +0 -522
package/src/clipboard.test.ts
CHANGED
|
@@ -20,6 +20,12 @@ interface FakeOptions {
|
|
|
20
20
|
groupRows?: Set<number>
|
|
21
21
|
/** Predicate for editability; default true. */
|
|
22
22
|
editableAt?: (r: number, c: number) => boolean
|
|
23
|
+
/**
|
|
24
|
+
* Data indices in DISPLAY order, i.e. what a sort/filter produces. Default is
|
|
25
|
+
* `[0, 1, 2, …]`, where display and data order coincide - which is exactly
|
|
26
|
+
* the case that hides row-index bugs, so the ordering tests pass a permutation.
|
|
27
|
+
*/
|
|
28
|
+
displayOrder?: number[]
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
function makeCtx(opts: FakeOptions = {}) {
|
|
@@ -41,15 +47,22 @@ function makeCtx(opts: FakeOptions = {}) {
|
|
|
41
47
|
},
|
|
42
48
|
}))
|
|
43
49
|
|
|
44
|
-
// allRows
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
// allRows are the rows AS DISPLAYED. By default that mirrors internalData by
|
|
51
|
+
// index (row.id === index as a string); `displayOrder` reorders them the way
|
|
52
|
+
// a sort or filter would, leaving `original` pointing at the same objects.
|
|
53
|
+
const rowsFrom = (source: Array<Record<string, unknown>>) => {
|
|
54
|
+
const order = opts.displayOrder ?? source.map((_, i) => i)
|
|
55
|
+
return order
|
|
56
|
+
.filter((dataIndex) => source[dataIndex] !== undefined)
|
|
57
|
+
.map((dataIndex) => ({
|
|
58
|
+
id: String(dataIndex),
|
|
59
|
+
original: source[dataIndex],
|
|
60
|
+
getCanExpand: () => opts.groupRows?.has(dataIndex) ?? false,
|
|
61
|
+
getCellValueByColumnId: (colId: string) =>
|
|
62
|
+
(source[dataIndex] as Record<string, unknown>)[colId],
|
|
63
|
+
}))
|
|
64
|
+
}
|
|
65
|
+
const buildRows = () => rowsFrom(data)
|
|
53
66
|
|
|
54
67
|
let activeCell: { rowIndex: number; colIndex: number } | null = null
|
|
55
68
|
|
|
@@ -107,13 +120,7 @@ function makeCtx(opts: FakeOptions = {}) {
|
|
|
107
120
|
get: () => backing,
|
|
108
121
|
set: (next: Array<Record<string, unknown>>) => {
|
|
109
122
|
backing = next
|
|
110
|
-
ctx._rows = next
|
|
111
|
-
id: String(index),
|
|
112
|
-
original: row,
|
|
113
|
-
getCanExpand: () => opts.groupRows?.has(index) ?? false,
|
|
114
|
-
getCellValueByColumnId: (colId: string) =>
|
|
115
|
-
(row as Record<string, unknown>)[colId],
|
|
116
|
-
}))
|
|
123
|
+
ctx._rows = rowsFrom(next)
|
|
117
124
|
},
|
|
118
125
|
})
|
|
119
126
|
|
|
@@ -195,6 +202,53 @@ describe('writeCellRaw', () => {
|
|
|
195
202
|
cb.writeCellRaw(0, 'noField', 5)
|
|
196
203
|
expect(ctx.internalData[0]).toEqual({ a: 1 })
|
|
197
204
|
})
|
|
205
|
+
|
|
206
|
+
describe('when the view is sorted or filtered (display order != data order)', () => {
|
|
207
|
+
// `rowIndex` is a DISPLAY index. These functions used to index
|
|
208
|
+
// `internalData` with it, which is the same row only while the two orders
|
|
209
|
+
// coincide - so the fill handle and enterprise bulk edit read from one row
|
|
210
|
+
// and wrote to another as soon as a column was sorted.
|
|
211
|
+
const sorted = () =>
|
|
212
|
+
makeCtx({
|
|
213
|
+
columns: [{ id: 'a', field: 'a', editable: true, editorType: 'text' }],
|
|
214
|
+
data: [{ a: 'data0' }, { a: 'data1' }, { a: 'data2' }],
|
|
215
|
+
displayOrder: [2, 0, 1],
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('readCellRaw reads the row shown at that position', () => {
|
|
219
|
+
const cb = createClipboard(sorted())
|
|
220
|
+
expect(cb.readCellRaw(0, 'a')).toBe('data2')
|
|
221
|
+
expect(cb.readCellRaw(1, 'a')).toBe('data0')
|
|
222
|
+
expect(cb.readCellRaw(2, 'a')).toBe('data1')
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('writeCellRaw writes the row shown at that position', () => {
|
|
226
|
+
const ctx = sorted()
|
|
227
|
+
const cb = createClipboard(ctx)
|
|
228
|
+
cb.writeCellRaw(0, 'a', 'WRITTEN')
|
|
229
|
+
expect(ctx.internalData.map((d: any) => d.a)).toEqual([
|
|
230
|
+
'data0',
|
|
231
|
+
'data1',
|
|
232
|
+
'WRITTEN',
|
|
233
|
+
])
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
it('reports the position in props.data to onCellValueChange', () => {
|
|
237
|
+
const ctx = sorted()
|
|
238
|
+
const onCellValueChange = vi.fn()
|
|
239
|
+
ctx.props.onCellValueChange = onCellValueChange
|
|
240
|
+
createClipboard(ctx).writeCellRaw(0, 'a', 'WRITTEN')
|
|
241
|
+
expect(onCellValueChange).toHaveBeenCalledWith(
|
|
242
|
+
expect.objectContaining({ rowIndex: 2, oldValue: 'data2', newValue: 'WRITTEN' }),
|
|
243
|
+
)
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('records the edit under the displayed row id', () => {
|
|
247
|
+
const ctx = sorted()
|
|
248
|
+
createClipboard(ctx).writeCellRaw(1, 'a', 'WRITTEN')
|
|
249
|
+
expect(ctx.editedCellValues['0:a']).toBe('WRITTEN')
|
|
250
|
+
})
|
|
251
|
+
})
|
|
198
252
|
})
|
|
199
253
|
|
|
200
254
|
describe('clearSelectedCellValues', () => {
|
|
@@ -753,14 +807,14 @@ describe('clearSelectedCells', () => {
|
|
|
753
807
|
expect(ctx.internalData[0].a).toBe('x')
|
|
754
808
|
})
|
|
755
809
|
|
|
756
|
-
it('skips
|
|
810
|
+
it('skips a row whose data object is not in the data array', () => {
|
|
757
811
|
const ctx = makeCtx({
|
|
758
812
|
columns: [{ id: 'a', field: 'a', editable: true, editorType: 'text' }],
|
|
759
813
|
data: [{ a: 'x' }],
|
|
760
814
|
})
|
|
761
|
-
//
|
|
762
|
-
//
|
|
763
|
-
ctx._rows[0].
|
|
815
|
+
// A row model pointing at an object that is no longer in `internalData`
|
|
816
|
+
// (a stale model after data was replaced) has no slot to write to.
|
|
817
|
+
ctx._rows[0].original = { a: 'stale' }
|
|
764
818
|
ctx.selectionRange = {
|
|
765
819
|
anchor: { rowIndex: 0, colIndex: 0 },
|
|
766
820
|
focus: { rowIndex: 0, colIndex: 0 },
|
|
@@ -769,6 +823,25 @@ describe('clearSelectedCells', () => {
|
|
|
769
823
|
expect(cb.clearSelectedCells()).toBe(false)
|
|
770
824
|
expect(ctx.internalData[0].a).toBe('x')
|
|
771
825
|
})
|
|
826
|
+
|
|
827
|
+
it('clears the selected row when getRowId does not return the array index', () => {
|
|
828
|
+
// The bug this guards: the row -> data-slot lookup used to be
|
|
829
|
+
// `Number(row.id)`, which is the array index only under the DEFAULT
|
|
830
|
+
// getRowId. Ids that are 1-based (or not numbers at all) cleared the row
|
|
831
|
+
// below the selection, or silently cleared nothing.
|
|
832
|
+
const ctx = makeCtx({
|
|
833
|
+
columns: [{ id: 'a', field: 'a', editable: true, editorType: 'text' }],
|
|
834
|
+
data: [{ a: 'x0' }, { a: 'x1' }, { a: 'x2' }],
|
|
835
|
+
})
|
|
836
|
+
ctx._rows.forEach((r: any, i: number) => { r.id = `PLAT-${i + 1}` })
|
|
837
|
+
ctx.selectionRange = {
|
|
838
|
+
anchor: { rowIndex: 1, colIndex: 0 },
|
|
839
|
+
focus: { rowIndex: 1, colIndex: 0 },
|
|
840
|
+
}
|
|
841
|
+
const cb = createClipboard(ctx)
|
|
842
|
+
expect(cb.clearSelectedCells()).toBe(true)
|
|
843
|
+
expect(ctx.internalData.map((d: any) => d.a)).toEqual(['x0', '', 'x2'])
|
|
844
|
+
})
|
|
772
845
|
})
|
|
773
846
|
|
|
774
847
|
describe('cutSelectionToClipboard', () => {
|