@svgrid/grid 3.0.7 → 3.0.9
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 +1 -1
- package/dist/GridMenus.svelte +3 -2
- package/dist/SvGrid.controller.svelte.d.ts +60 -8
- package/dist/SvGrid.controller.svelte.js +490 -114
- package/dist/SvGrid.css +186 -3
- package/dist/SvGrid.svelte +285 -164
- package/dist/SvGrid.types.d.ts +24 -7
- package/dist/cdn/{GridMenus-CcwU8I4t.js → GridMenus-B1sipj6y.js} +165 -165
- package/dist/cdn/{GridMenus-BgUS-W3o.js → GridMenus-DlAzfHLk.js} +201 -201
- package/dist/cdn/server-block-cache-Dj-KPqEQ.js +1289 -0
- package/dist/cdn/{src-kE9B98r6.js → src-BYsa66I0.js} +9747 -10178
- package/dist/cdn/{src-25JmJ_7g.js → src-pA4RroLV.js} +10709 -11140
- package/dist/cdn/svgrid.js +27 -27
- package/dist/cdn/svgrid.svelte-external.js +27 -27
- package/dist/cdn/validate-XuMe4_KR.js +80 -0
- package/dist/cell-render.js +25 -3
- package/dist/columns.js +16 -1
- package/dist/conditional-formatting.js +9 -2
- package/dist/core.d.ts +93 -0
- package/dist/core.js +313 -47
- package/dist/filtering/excel-filters.js +41 -6
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/keyboard-handlers.js +5 -1
- package/dist/selection.d.ts +2 -2
- package/dist/selection.js +46 -12
- package/dist/server-block-cache.d.ts +7 -32
- package/dist/server-block-cache.js +21 -12
- package/dist/server-data-source.js +3 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/spreadsheet.js +7 -0
- package/dist/{subscribe.js → subscribe.svelte.js} +5 -1
- package/dist/validate.js +13 -14
- package/dist/virtualization/column-virtualizer.d.ts +4 -0
- package/dist/virtualization/column-virtualizer.js +2 -0
- package/dist/virtualization/types.d.ts +20 -0
- package/dist/virtualization/virtualizer.js +90 -24
- package/dist/windowed-brand.d.ts +22 -0
- package/dist/windowed-brand.js +60 -0
- package/dist/windowed-data.d.ts +6 -0
- package/dist/windowed-data.js +34 -0
- package/dist/windowed-row-model.d.ts +1 -0
- package/dist/windowed-row-model.js +97 -0
- package/package.json +1 -1
- package/src/GridMenus.svelte +3 -2
- package/src/SvGrid.controller.svelte.ts +483 -122
- package/src/SvGrid.css +186 -3
- package/src/SvGrid.svelte +285 -164
- package/src/SvGrid.types.ts +24 -7
- package/src/cell-render.ts +24 -2
- package/src/columns.ts +16 -1
- package/src/conditional-formatting.ts +6 -4
- package/src/core.sort.test.ts +61 -0
- package/src/core.ts +309 -49
- package/src/counting-cell.test.svelte +11 -0
- package/src/filtering/excel-filters.ts +39 -6
- package/src/headless.reactivity.svelte.test.ts +89 -0
- package/src/headless.ts +1 -1
- package/src/index.ts +7 -1
- package/src/keyboard-handlers.ts +5 -1
- package/src/new-features.test.ts +24 -0
- package/src/selection.test.ts +51 -0
- package/src/selection.ts +47 -14
- package/src/server-block-cache.ts +27 -10
- package/src/server-data-source.ts +3 -1
- package/src/server.ts +6 -0
- package/src/spreadsheet.ts +6 -0
- package/src/{subscribe.test.ts → subscribe.svelte.test.ts} +1 -1
- package/src/{subscribe.ts → subscribe.svelte.ts} +5 -1
- package/src/svgrid.behavior.test.ts +58 -0
- package/src/svgrid.column-cell-recycling.test.ts +120 -0
- package/src/svgrid.interaction.test.ts +4 -1
- package/src/svgrid.new-features.wrapper.test.ts +5 -4
- package/src/svgrid.pinned-column-virtualization.test.ts +162 -0
- package/src/svgrid.row-model-prop.svelte.test.ts +15 -3
- package/src/validate.test.ts +20 -4
- package/src/validate.ts +13 -16
- package/src/virtualization/column-virtualizer.ts +6 -0
- package/src/virtualization/types.ts +20 -0
- package/src/virtualization/virtualizer.test.ts +152 -0
- package/src/virtualization/virtualizer.ts +93 -27
- package/src/windowed-brand.ts +67 -0
- package/src/windowed-data.test.ts +105 -0
- package/src/windowed-data.ts +36 -0
- package/src/windowed-row-model.ts +113 -0
- package/dist/cdn/server-block-cache-DIqb3VZn.js +0 -241
- package/dist/cdn/validate-AZoD8BoR.js +0 -80
- /package/dist/{subscribe.d.ts → subscribe.svelte.d.ts} +0 -0
package/src/SvGrid.css
CHANGED
|
@@ -955,6 +955,15 @@
|
|
|
955
955
|
.sv-grid-container {
|
|
956
956
|
scrollbar-width: auto;
|
|
957
957
|
-ms-overflow-style: auto;
|
|
958
|
+
/* An opaque background is what lets Chrome scroll the body on the
|
|
959
|
+
compositor. Without one, at fractional display scaling (110-125%,
|
|
960
|
+
where Chrome keeps LCD text), it did not composite this scroller: every
|
|
961
|
+
scroll frame repainted the rows on the main thread while the compositor
|
|
962
|
+
placed the sticky header, and the two drifted apart - the header shook
|
|
963
|
+
a few pixels up and down during a vertical scroll and showed the tops of
|
|
964
|
+
the letters behind it. Composited, rows and header move together. A
|
|
965
|
+
theme that sets a transparent `--sg-bg` keeps the old behaviour. */
|
|
966
|
+
background-color: var(--sg-bg, #fff);
|
|
958
967
|
/* Trap wheel scroll inside the grid. Without this, hitting the top
|
|
959
968
|
* or bottom edge of the grid lets the wheel event chain to the
|
|
960
969
|
* outer page (or any scrollable ancestor), so what feels like one
|
|
@@ -3213,9 +3222,14 @@ select.sv-grid-fr-editor {
|
|
|
3213
3222
|
border-right-color: var(--sg-header-bg, #f1f5f9);
|
|
3214
3223
|
}
|
|
3215
3224
|
/* The detail-toggle gutter fuses with the row numbers the same way; only
|
|
3216
|
-
its own right edge keeps a line, between the chrome and the data.
|
|
3217
|
-
|
|
3218
|
-
.
|
|
3225
|
+
its own right edge keeps a line, between the chrome and the data. The
|
|
3226
|
+
table carries a class for "row numbers directly before the toggle" (no
|
|
3227
|
+
selection column between them). This was `:has(+ .sv-grid-detail-toggle-cell)`,
|
|
3228
|
+
and a sibling `:has()` makes Chrome restyle every cell of a row whenever a
|
|
3229
|
+
cell is added to or taken out of it: each horizontal column move restyled
|
|
3230
|
+
~1,500 elements (8 ms) instead of ~400 (3 ms) in a grid with row numbers. */
|
|
3231
|
+
.sv-grid-numbers-beside-toggle .sv-grid-row-number-cell,
|
|
3232
|
+
.sv-grid-numbers-beside-toggle .sv-grid-row-number-column {
|
|
3219
3233
|
border-right-color: var(--sg-header-bg, #f1f5f9);
|
|
3220
3234
|
}
|
|
3221
3235
|
|
|
@@ -3496,3 +3510,172 @@ select.sv-grid-fr-editor {
|
|
|
3496
3510
|
.sv-grid-chart-tab.is-active .sv-grid-chart-tab-label { color: var(--sg-accent, #2563eb); }
|
|
3497
3511
|
.sv-grid-chart-tab-x { border: 0; background: transparent; color: var(--sg-muted, #64748b); font-size: 14px; line-height: 1; padding: 0 6px 0 2px; cursor: pointer; }
|
|
3498
3512
|
.sv-grid-chart-tab-x:hover { color: var(--sg-fg, #0f172a); }
|
|
3513
|
+
|
|
3514
|
+
/* ===========================================================================
|
|
3515
|
+
Flex rows (`.sv-grid-table-flex`, the default; see the `rowLayout` prop).
|
|
3516
|
+
A table marked `data-row-layout="table"` (spreadsheetLayout, whose
|
|
3517
|
+
merges are DOM colspan / rowspan) keeps table layout.
|
|
3518
|
+
|
|
3519
|
+
Every row is a flex line of fixed-width cells instead of a table row. The
|
|
3520
|
+
cells already carry their width inline, so the columns line up the same;
|
|
3521
|
+
what changes is the cost of a change. A table lays every row out again
|
|
3522
|
+
when one cell is added or removed (a horizontal scroll adds a column of
|
|
3523
|
+
cells per frame): ~7 ms of layout a frame on a wide grid. A flex row lays
|
|
3524
|
+
out its own cells only: ~1.5 ms. Table layout stays available for what
|
|
3525
|
+
only a table can draw - a merged cell spanning rows - and the grid picks it
|
|
3526
|
+
automatically then.
|
|
3527
|
+
|
|
3528
|
+
Every selector walks the grid's own structure with child combinators
|
|
3529
|
+
(table > section > tr > cell): a table inside a detail panel or a cell,
|
|
3530
|
+
or a nested grid, keeps its own layout.
|
|
3531
|
+
=========================================================================== */
|
|
3532
|
+
.sv-grid-table-flex:not([data-row-layout="table"]),
|
|
3533
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) {
|
|
3534
|
+
display: block;
|
|
3535
|
+
}
|
|
3536
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr {
|
|
3537
|
+
display: flex;
|
|
3538
|
+
}
|
|
3539
|
+
/* A collapsed row (a sheet's hidden or filtered row) leaves the flow, as it
|
|
3540
|
+
does in table layout. The rule above outranks .sv-grid-row-collapsed, and
|
|
3541
|
+
a 0px flex row still paints its cells' bottom border 1px into the next. */
|
|
3542
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > tr.sv-grid-row-collapsed {
|
|
3543
|
+
display: none;
|
|
3544
|
+
}
|
|
3545
|
+
/* Rows are not contained by default. Each body row used to be its own
|
|
3546
|
+
layout and paint island (`contain: layout paint`), so a scroll frame
|
|
3547
|
+
re-recorded only the rows that changed. Once the body scrolled on the
|
|
3548
|
+
compositor (the scroller's own background) that saving was gone, and
|
|
3549
|
+
every contained row was a separate clipped piece of paint Chrome sorted
|
|
3550
|
+
into layers again on each frame: layerize took 4-7x longer, and a
|
|
3551
|
+
horizontal wheel scroll of the 1M-row x 1,000-column demo about twice the
|
|
3552
|
+
main-thread work. An app can still opt in with --sg-row-contain. */
|
|
3553
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > tr {
|
|
3554
|
+
contain: var(--sg-row-contain, none);
|
|
3555
|
+
}
|
|
3556
|
+
/* Cells: a fixed-width flex item each, centring what they hold vertically
|
|
3557
|
+
the way a table cell's `vertical-align: middle` did. */
|
|
3558
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > :is(td, th) {
|
|
3559
|
+
display: flex;
|
|
3560
|
+
flex: none;
|
|
3561
|
+
}
|
|
3562
|
+
/* Zero specificity, so `.my-grid .sv-grid-cell { align-items: flex-start }`
|
|
3563
|
+
re-aligns cells (docs/help/rows/styling-rows.md). */
|
|
3564
|
+
:where(.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > :is(td, th)) {
|
|
3565
|
+
align-items: center;
|
|
3566
|
+
}
|
|
3567
|
+
/* What a cell holds may shrink below its content's width, so the cell clips
|
|
3568
|
+
and ellipsizes it rather than overflowing. Named by class, not `> *`: a
|
|
3569
|
+
universal right-hand selector is tested against every element on each
|
|
3570
|
+
style recalc, which cost ~0.5 ms a frame of vertical scroll. Outside a flex
|
|
3571
|
+
row `min-width: 0` is already the computed default, so these rules are
|
|
3572
|
+
unscoped. */
|
|
3573
|
+
.sv-grid-header-cell,
|
|
3574
|
+
.sv-grid-filter-row-control,
|
|
3575
|
+
.sv-grid-row-number-head,
|
|
3576
|
+
.sv-grid-group-content,
|
|
3577
|
+
.sv-grid-cf-content {
|
|
3578
|
+
min-width: 0;
|
|
3579
|
+
}
|
|
3580
|
+
/* `th` is centred by the user-agent sheet (`text-align: center`); flex items
|
|
3581
|
+
follow `justify-content` instead. */
|
|
3582
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > th {
|
|
3583
|
+
justify-content: center;
|
|
3584
|
+
}
|
|
3585
|
+
/* A header cell's inline content used to sit on a line box, whose height
|
|
3586
|
+
(the inherited line-height) set the cell's minimum height; a flex cell has
|
|
3587
|
+
no line box, so a band like the column-group row shrank from 33px to 20px.
|
|
3588
|
+
A zero-width text strut puts the line height back. `:where` keeps it at
|
|
3589
|
+
the lowest specificity, so the drag-indicator ::before rules replace it. */
|
|
3590
|
+
:where(.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > th)::before {
|
|
3591
|
+
content: "\200b";
|
|
3592
|
+
width: 0;
|
|
3593
|
+
overflow: hidden;
|
|
3594
|
+
}
|
|
3595
|
+
/* A cell's text sits in its own span so the ellipsis still works: a flex
|
|
3596
|
+
container cannot clip and ellipsize a bare text node. The span takes the
|
|
3597
|
+
cell's width, so `text-align` keeps aligning it. */
|
|
3598
|
+
.sv-grid-cell-text {
|
|
3599
|
+
min-width: 0;
|
|
3600
|
+
overflow: hidden;
|
|
3601
|
+
text-overflow: ellipsis;
|
|
3602
|
+
white-space: inherit;
|
|
3603
|
+
}
|
|
3604
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > :is(td, th) .sv-grid-cell-text,
|
|
3605
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > td > .sv-grid-cf-content {
|
|
3606
|
+
flex: 1 1 auto;
|
|
3607
|
+
}
|
|
3608
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > td > .sv-grid-cf-content {
|
|
3609
|
+
overflow: hidden;
|
|
3610
|
+
text-overflow: ellipsis;
|
|
3611
|
+
}
|
|
3612
|
+
/* Non-text content (checkbox, chips, icons) follows the column alignment.
|
|
3613
|
+
`right` is physical, like the `text-align: right` it stands beside, so a
|
|
3614
|
+
right-aligned column stays right under `dir="rtl"`. */
|
|
3615
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > .sv-grid-cell[data-align="right"] {
|
|
3616
|
+
justify-content: right;
|
|
3617
|
+
}
|
|
3618
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > :is(
|
|
3619
|
+
.sv-grid-cell[data-align="center"],
|
|
3620
|
+
.sv-grid-selection-cell,
|
|
3621
|
+
.sv-grid-selection-column,
|
|
3622
|
+
.sv-grid-detail-toggle-cell,
|
|
3623
|
+
.sv-grid-detail-toggle-column
|
|
3624
|
+
) {
|
|
3625
|
+
justify-content: center;
|
|
3626
|
+
}
|
|
3627
|
+
/* The header cell's content fills it, and so does the row-number corner, so
|
|
3628
|
+
a `text-align` set on the header cell (an app re-centring its headers)
|
|
3629
|
+
still places them. */
|
|
3630
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > thead > tr > th > :is(.sv-grid-header-cell, .sv-grid-row-number-head) {
|
|
3631
|
+
flex: 1 1 auto;
|
|
3632
|
+
}
|
|
3633
|
+
/* A cell that spans the whole row (a group banner, a detail panel, a failed
|
|
3634
|
+
block's message) has no width of its own: it fills the row. A merged cell
|
|
3635
|
+
spans columns too, but carries its own width. */
|
|
3636
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > tr > td[colspan]:not([data-merge-origin]) {
|
|
3637
|
+
flex: 1 1 auto;
|
|
3638
|
+
min-width: 0;
|
|
3639
|
+
}
|
|
3640
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > tr > td.sv-grid-detail-cell {
|
|
3641
|
+
display: block;
|
|
3642
|
+
}
|
|
3643
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > tr > td.sv-grid-group-cell > .sv-grid-group-content {
|
|
3644
|
+
flex: 1 1 auto;
|
|
3645
|
+
}
|
|
3646
|
+
/* Pinned rows stick as a band: a sticky cell cannot leave its flex row, so
|
|
3647
|
+
the band's body is the sticky box instead of each cell. */
|
|
3648
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody.sv-grid-pinned-top-body {
|
|
3649
|
+
position: sticky;
|
|
3650
|
+
top: var(--sg-thead-h, 36px);
|
|
3651
|
+
z-index: 4;
|
|
3652
|
+
}
|
|
3653
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody.sv-grid-pinned-bottom-body {
|
|
3654
|
+
position: sticky;
|
|
3655
|
+
bottom: 0;
|
|
3656
|
+
z-index: 4;
|
|
3657
|
+
}
|
|
3658
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > tbody > .sv-grid-pinned-row > td {
|
|
3659
|
+
top: auto;
|
|
3660
|
+
bottom: auto;
|
|
3661
|
+
}
|
|
3662
|
+
/* A flex row is exactly as tall as its `height`, which is the row height the
|
|
3663
|
+
virtualizer places it at. A rule here used to turn that into a minimum, as
|
|
3664
|
+
a table row's is, so content taller than `rowHeight` grew the row; the
|
|
3665
|
+
virtualizer still placed every row at `rowHeight`, so the rows drifted and
|
|
3666
|
+
jumped while scrolling (the 1M-row demo: 25 px rows placed as 18). Taller
|
|
3667
|
+
content is clipped by its cell now; `autoRowHeight` is the way to let rows
|
|
3668
|
+
grow. */
|
|
3669
|
+
/* A body cell's content line (see the bodyRow snippet). Block-level, so the
|
|
3670
|
+
inline content in it sits on one line box exactly as it did directly in a
|
|
3671
|
+
table cell; it carries the ellipsis and takes the cell's text-align. */
|
|
3672
|
+
.sv-grid-cell-line {
|
|
3673
|
+
display: block;
|
|
3674
|
+
min-width: 0;
|
|
3675
|
+
overflow: hidden;
|
|
3676
|
+
text-overflow: ellipsis;
|
|
3677
|
+
white-space: inherit;
|
|
3678
|
+
}
|
|
3679
|
+
.sv-grid-table-flex:not([data-row-layout="table"]) > :is(thead, tbody, tfoot) > tr > td > .sv-grid-cell-line {
|
|
3680
|
+
flex: 1 1 auto;
|
|
3681
|
+
}
|