@svgrid/grid 1.1.0 → 1.1.2

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.
Files changed (148) hide show
  1. package/dist/FlexRender.svelte +96 -96
  2. package/dist/GridMenus.svelte +205 -127
  3. package/dist/SvGrid.controller.svelte.d.ts +44 -1
  4. package/dist/SvGrid.controller.svelte.js +240 -44
  5. package/dist/SvGrid.css +325 -22
  6. package/dist/SvGrid.helpers.test.d.ts +1 -0
  7. package/dist/SvGrid.helpers.test.js +298 -0
  8. package/dist/SvGrid.svelte +729 -203
  9. package/dist/SvGrid.types.d.ts +91 -4
  10. package/dist/aligned-grids.d.ts +6 -0
  11. package/dist/aligned-grids.js +84 -0
  12. package/dist/aligned-grids.test.d.ts +1 -0
  13. package/dist/aligned-grids.test.js +75 -0
  14. package/dist/build-api.coverage.test.d.ts +20 -0
  15. package/dist/build-api.coverage.test.js +505 -0
  16. package/dist/build-api.js +61 -31
  17. package/dist/cell-render.test.d.ts +1 -0
  18. package/dist/cell-render.test.js +338 -0
  19. package/dist/cell-values.d.ts +1 -1
  20. package/dist/cell-values.js +7 -7
  21. package/dist/chart-export.test.d.ts +1 -0
  22. package/dist/chart-export.test.js +302 -0
  23. package/dist/chart.coverage.test.d.ts +1 -0
  24. package/dist/chart.coverage.test.js +748 -0
  25. package/dist/clipboard.js +88 -24
  26. package/dist/clipboard.test.d.ts +1 -0
  27. package/dist/clipboard.test.js +700 -0
  28. package/dist/collaboration.coverage.test.d.ts +1 -0
  29. package/dist/collaboration.coverage.test.js +200 -0
  30. package/dist/column-groups.d.ts +19 -0
  31. package/dist/column-groups.js +62 -0
  32. package/dist/column-groups.test.d.ts +1 -0
  33. package/dist/column-groups.test.js +56 -0
  34. package/dist/column-types.d.ts +10 -0
  35. package/dist/column-types.js +63 -0
  36. package/dist/column-types.test.d.ts +1 -0
  37. package/dist/column-types.test.js +62 -0
  38. package/dist/columns.test.d.ts +1 -0
  39. package/dist/columns.test.js +625 -0
  40. package/dist/core.d.ts +86 -1
  41. package/dist/core.js +2 -2
  42. package/dist/editing.d.ts +7 -0
  43. package/dist/editing.js +191 -5
  44. package/dist/editing.test.d.ts +1 -0
  45. package/dist/editing.test.js +732 -0
  46. package/dist/editors/cell-editors.coverage.test.d.ts +1 -0
  47. package/dist/editors/cell-editors.coverage.test.js +139 -0
  48. package/dist/facet-buckets.test.d.ts +1 -0
  49. package/dist/facet-buckets.test.js +296 -0
  50. package/dist/filter-operators.test.d.ts +1 -0
  51. package/dist/filter-operators.test.js +135 -0
  52. package/dist/hyperformula-adapter.test.d.ts +1 -0
  53. package/dist/hyperformula-adapter.test.js +205 -0
  54. package/dist/index.d.ts +5 -2
  55. package/dist/index.js +4 -1
  56. package/dist/keyboard-handlers.coverage.test.d.ts +1 -0
  57. package/dist/keyboard-handlers.coverage.test.js +495 -0
  58. package/dist/keyboard-handlers.js +7 -2
  59. package/dist/menus.js +1 -0
  60. package/dist/menus.test.d.ts +1 -0
  61. package/dist/menus.test.js +560 -0
  62. package/dist/named-views.coverage.test.d.ts +1 -0
  63. package/dist/named-views.coverage.test.js +180 -0
  64. package/dist/row-drag.d.ts +49 -0
  65. package/dist/row-drag.js +221 -0
  66. package/dist/row-drag.test.d.ts +1 -0
  67. package/dist/row-drag.test.js +142 -0
  68. package/dist/row-resize.test.d.ts +1 -0
  69. package/dist/row-resize.test.js +329 -0
  70. package/dist/scroll-sync.js +3 -0
  71. package/dist/scroll-sync.test.d.ts +1 -0
  72. package/dist/scroll-sync.test.js +290 -0
  73. package/dist/selection.d.ts +7 -1
  74. package/dist/selection.js +76 -36
  75. package/dist/selection.multi-range.test.d.ts +1 -0
  76. package/dist/selection.multi-range.test.js +55 -0
  77. package/dist/selection.test.d.ts +1 -0
  78. package/dist/selection.test.js +647 -0
  79. package/dist/server-data-source.coverage.test.d.ts +1 -0
  80. package/dist/server-data-source.coverage.test.js +154 -0
  81. package/dist/spreadsheet.d.ts +30 -0
  82. package/dist/spreadsheet.js +48 -0
  83. package/dist/spreadsheet.test.d.ts +1 -0
  84. package/dist/spreadsheet.test.js +446 -0
  85. package/dist/summaries.js +4 -4
  86. package/dist/sv-grid-scrollbar.js +13 -1
  87. package/dist/svgrid-wrapper.types.d.ts +19 -0
  88. package/dist/svgrid.behavior.test.js +20 -0
  89. package/dist/svgrid.interaction.test.js +31 -0
  90. package/dist/svgrid.new-features.wrapper.test.js +34 -2
  91. package/dist/test-setup.js +9 -3
  92. package/dist/virtualization/scroll-scaling.d.ts +17 -0
  93. package/dist/virtualization/scroll-scaling.js +35 -0
  94. package/dist/virtualization/scroll-scaling.test.js +42 -1
  95. package/package.json +2 -1
  96. package/src/FlexRender.svelte +96 -96
  97. package/src/GridMenus.svelte +205 -127
  98. package/src/SvGrid.controller.svelte.ts +204 -36
  99. package/src/SvGrid.css +277 -12
  100. package/src/SvGrid.svelte +727 -205
  101. package/src/SvGrid.types.ts +85 -4
  102. package/src/a11y.contract.test.ts +49 -49
  103. package/src/a11y.test.ts +59 -59
  104. package/src/a11y.ts +59 -59
  105. package/src/aligned-grids.test.ts +80 -0
  106. package/src/aligned-grids.ts +87 -0
  107. package/src/build-api.ts +43 -23
  108. package/src/cell-formatting.ts +169 -169
  109. package/src/cell-values.ts +4 -4
  110. package/src/clipboard.test.ts +49 -0
  111. package/src/clipboard.ts +51 -23
  112. package/src/column-groups.test.ts +59 -0
  113. package/src/column-groups.ts +80 -0
  114. package/src/column-types.test.ts +68 -0
  115. package/src/column-types.ts +82 -0
  116. package/src/core.performance.test.ts +30 -30
  117. package/src/core.ts +1077 -999
  118. package/src/createGrid.svelte.ts +42 -42
  119. package/src/createGrid.test.ts +10 -10
  120. package/src/createGridState.svelte.ts +17 -17
  121. package/src/editing.ts +161 -5
  122. package/src/flex-render.ts +3 -3
  123. package/src/index.ts +208 -196
  124. package/src/keyboard.test.ts +59 -59
  125. package/src/keyboard.ts +97 -97
  126. package/src/menus.ts +1 -0
  127. package/src/merge-objects.ts +48 -48
  128. package/src/render-component.ts +28 -28
  129. package/src/row-drag.test.ts +168 -0
  130. package/src/row-drag.ts +255 -0
  131. package/src/scroll-sync.ts +2 -0
  132. package/src/selection.multi-range.test.ts +61 -0
  133. package/src/selection.ts +71 -37
  134. package/src/spreadsheet.test.ts +46 -2
  135. package/src/spreadsheet.ts +58 -0
  136. package/src/static-functions.ts +11 -11
  137. package/src/subscribe.ts +38 -38
  138. package/src/summaries.ts +4 -4
  139. package/src/svgrid-wrapper.types.ts +412 -393
  140. package/src/svgrid.features.test.ts +157 -157
  141. package/src/svgrid.new-features.wrapper.test.ts +2 -2
  142. package/src/svgrid.wrapper.test.ts +40 -40
  143. package/src/virtualization/column-virtualizer.test.ts +27 -27
  144. package/src/virtualization/column-virtualizer.ts +30 -30
  145. package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
  146. package/src/virtualization/types.ts +30 -30
  147. package/src/virtualization/virtualizer.test.ts +47 -47
  148. package/src/virtualization/virtualizer.ts +296 -296
package/src/SvGrid.css CHANGED
@@ -90,33 +90,48 @@
90
90
  100% { background-position: -200% 0; }
91
91
  }
92
92
 
93
- .sv-grid-tool-panel-toggle {
94
- position: absolute;
95
- top: 6px;
96
- right: 6px;
97
- z-index: 21;
93
+ /* Grid toolbar strip above the shell - hosts the tool-panel trigger (and is a
94
+ natural home for future grid-level actions). */
95
+ .sv-grid-toolbar {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 8px;
99
+ padding: 6px 2px;
100
+ }
101
+ .sv-grid-toolbar-btn {
98
102
  display: inline-flex;
99
103
  align-items: center;
100
- justify-content: center;
101
- width: 30px;
102
- height: 30px;
104
+ gap: 6px;
105
+ padding: 6px 12px;
103
106
  border: 1px solid var(--sg-border, #e2e8f0);
104
107
  border-radius: var(--sg-radius, 6px);
105
108
  background: var(--sg-bg, #fff);
106
- color: var(--sg-muted, #64748b);
109
+ color: var(--sg-fg, #0f172a);
110
+ font-size: 12.5px;
111
+ font-weight: 600;
107
112
  cursor: pointer;
113
+ transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
108
114
  }
109
- .sv-grid-tool-panel-toggle:hover,
110
- .sv-grid-tool-panel-toggle.is-open {
115
+ .sv-grid-toolbar-btn:hover {
116
+ border-color: var(--sg-accent, #2563eb);
111
117
  color: var(--sg-accent, #2563eb);
118
+ }
119
+ .sv-grid-toolbar-btn.is-active {
120
+ background: var(--sg-accent, #2563eb);
112
121
  border-color: var(--sg-accent, #2563eb);
122
+ color: #fff;
113
123
  }
114
124
  .sv-grid-tool-panel {
115
125
  position: absolute;
116
126
  top: 0;
117
127
  right: 0;
118
128
  bottom: 0;
119
- z-index: 20;
129
+ /* Above the grid's sticky header (z-index 30) and custom scrollbars (z ~900)
130
+ so the docked panel fully overlays the grid instead of the header/right
131
+ columns bleeding through its top-right. Ties the menu layer (901) but the
132
+ menus render later in the DOM, so a column menu opened over the panel still
133
+ wins. */
134
+ z-index: 901;
120
135
  width: 250px;
121
136
  display: flex;
122
137
  flex-direction: column;
@@ -205,6 +220,83 @@
205
220
  opacity: 0.35;
206
221
  cursor: default;
207
222
  }
223
+ /* Tool-panel tab bar (Columns | Filters) */
224
+ .sv-grid-tool-panel-tabs {
225
+ display: flex;
226
+ gap: 2px;
227
+ padding: 6px 6px 0;
228
+ border-bottom: 1px solid var(--sg-border, #e2e8f0);
229
+ }
230
+ .sv-grid-tool-panel-tab {
231
+ flex: 1;
232
+ padding: 6px 8px;
233
+ border: 0;
234
+ border-bottom: 2px solid transparent;
235
+ background: transparent;
236
+ color: var(--sg-muted, #64748b);
237
+ font-size: 12px;
238
+ font-weight: 600;
239
+ cursor: pointer;
240
+ }
241
+ .sv-grid-tool-panel-tab:hover {
242
+ color: var(--sg-fg, #0f172a);
243
+ }
244
+ .sv-grid-tool-panel-tab.is-active {
245
+ color: var(--sg-accent, #2563eb);
246
+ border-bottom-color: var(--sg-accent, #2563eb);
247
+ }
248
+ /* Filters tab: one control block per filterable column */
249
+ .sv-grid-tool-panel-filters {
250
+ padding: 6px;
251
+ overflow-y: auto;
252
+ flex: 1;
253
+ display: flex;
254
+ flex-direction: column;
255
+ gap: 8px;
256
+ }
257
+ .sv-grid-tp-filter {
258
+ display: flex;
259
+ flex-direction: column;
260
+ gap: 4px;
261
+ padding: 6px;
262
+ border: 1px solid var(--sg-border, #e2e8f0);
263
+ border-radius: 6px;
264
+ }
265
+ .sv-grid-tp-filter.is-filtered {
266
+ border-color: var(--sg-accent, #2563eb);
267
+ }
268
+ .sv-grid-tp-filter-head {
269
+ display: flex;
270
+ align-items: center;
271
+ justify-content: space-between;
272
+ }
273
+ .sv-grid-tp-filter-name {
274
+ font-size: 12px;
275
+ font-weight: 600;
276
+ color: var(--sg-fg, #0f172a);
277
+ }
278
+ .sv-grid-tp-filter-clear {
279
+ border: 0;
280
+ background: transparent;
281
+ color: var(--sg-muted, #64748b);
282
+ font-size: 11px;
283
+ cursor: pointer;
284
+ padding: 0 2px;
285
+ }
286
+ .sv-grid-tp-filter-clear:hover {
287
+ color: var(--sg-accent, #2563eb);
288
+ }
289
+ .sv-grid-tp-filter-op,
290
+ .sv-grid-tp-filter-input {
291
+ width: 100%;
292
+ box-sizing: border-box;
293
+ padding: 4px 6px;
294
+ font-size: 12px;
295
+ border: 1px solid var(--sg-border, #e2e8f0);
296
+ border-radius: 5px;
297
+ background: var(--sg-bg, #fff);
298
+ color: var(--sg-fg, #0f172a);
299
+ }
208
300
  /* Root wrapper fill mode: only takes effect when consumer passes
209
301
  * containerHeight='100%'. The shell becomes a flex item that expands
210
302
  * while the pager keeps its natural height. */
@@ -459,6 +551,48 @@
459
551
  .sv-grid-column.is-drag-target-after::after { right: -2px; }
460
552
  @keyframes sg-drop-pulse { from { opacity: 0.55; } to { opacity: 1; } }
461
553
 
554
+ /* Managed row dragging ----------------------------------------------------- */
555
+ /* The whole row is the drag source; the row-number cell shows a grip so the
556
+ * affordance is discoverable. Pair `rowDragManaged` with `showRowNumbers` for
557
+ * the grip; without row numbers the grab cursor still hints it. */
558
+ .sv-grid-row-draggable { cursor: grab; }
559
+ .sv-grid-row-draggable:active { cursor: grabbing; }
560
+ .sv-grid-row-draggable .sv-grid-row-number-cell {
561
+ position: relative;
562
+ padding-left: 14px;
563
+ }
564
+ .sv-grid-row-draggable .sv-grid-row-number-cell::before {
565
+ content: "\2807"; /* braille grip glyph */
566
+ position: absolute;
567
+ left: 3px;
568
+ top: 50%;
569
+ transform: translateY(-50%);
570
+ font-size: 13px;
571
+ line-height: 1;
572
+ color: var(--sg-muted, #94a3b8);
573
+ opacity: 0.4;
574
+ transition: opacity 120ms ease;
575
+ pointer-events: none;
576
+ }
577
+ .sv-grid-row-draggable:hover .sv-grid-row-number-cell::before { opacity: 1; }
578
+
579
+ /* Default highlight for an external drop zone (use:rowDropZone) while a
580
+ matching row is dragged over it. Consumers can override the class. */
581
+ .sv-grid-row-dropzone-over {
582
+ outline: 2px dashed var(--sg-accent, #6366f1);
583
+ outline-offset: -2px;
584
+ background: color-mix(in srgb, var(--sg-accent, #6366f1) 10%, transparent);
585
+ }
586
+
587
+ /* Drop indicator: a glowing line on the row's top (before) or bottom (after)
588
+ * edge. Painted on the cells so it spans the full row across table layouts. */
589
+ .sv-grid-row-drop-before > td {
590
+ box-shadow: inset 0 2px 0 0 var(--sg-accent, #6366f1);
591
+ }
592
+ .sv-grid-row-drop-after > td {
593
+ box-shadow: inset 0 -2px 0 0 var(--sg-accent, #6366f1);
594
+ }
595
+
462
596
  /* Pinned rows (top / bottom). Each cell sticks individually so the
463
597
  * row tracks scroll on every browser. Top rows stick below the sticky
464
598
  * thead via --sg-thead-h; bottom rows stick to the bottom of the
@@ -514,6 +648,34 @@
514
648
  text-overflow: ellipsis;
515
649
  white-space: nowrap;
516
650
  }
651
+ /* Collapse toggle on a collapsible column group header. */
652
+ .sv-grid-group-toggle {
653
+ display: inline-flex;
654
+ align-items: center;
655
+ gap: 5px;
656
+ max-width: 100%;
657
+ border: 0;
658
+ background: transparent;
659
+ color: inherit;
660
+ font: inherit;
661
+ letter-spacing: inherit;
662
+ text-transform: inherit;
663
+ cursor: pointer;
664
+ padding: 2px 6px;
665
+ border-radius: 5px;
666
+ }
667
+ .sv-grid-group-toggle:hover {
668
+ background: color-mix(in srgb, var(--sg-accent, #2563eb) 12%, transparent);
669
+ color: var(--sg-accent, #2563eb);
670
+ }
671
+ .sv-grid-group-caret {
672
+ flex-shrink: 0;
673
+ transition: transform 140ms ease;
674
+ }
675
+ /* Collapsed: point the caret right (like a closed disclosure). */
676
+ .sv-grid-group-toggle.is-collapsed .sv-grid-group-caret {
677
+ transform: rotate(-90deg);
678
+ }
517
679
 
518
680
  .sv-grid-foot {
519
681
  position: sticky;
@@ -685,6 +847,23 @@
685
847
  background-color 120ms ease;
686
848
  }
687
849
 
850
+ /* Full-row editor: inline editors shown for every editable cell of a row
851
+ in full-row edit. Fill the cell so the row reads as a form line. */
852
+ .sv-grid-fr-editor {
853
+ width: 100%;
854
+ box-sizing: border-box;
855
+ }
856
+ select.sv-grid-fr-editor {
857
+ height: 100%;
858
+ min-height: 26px;
859
+ }
860
+ .sv-grid-fr-checkbox {
861
+ width: 16px;
862
+ height: 16px;
863
+ accent-color: var(--sg-accent, #3b82f6);
864
+ cursor: pointer;
865
+ }
866
+
688
867
  /* Color editor - native HTML color input filling the cell so the
689
868
  swatch is clickable across the whole cell area, not just the tiny
690
869
  OS default size. */
@@ -759,6 +938,19 @@
759
938
  pointer-events: none;
760
939
  }
761
940
 
941
+ /* Built-in cell flash (ColumnDef `cellFlash`). Theme-tinted fade; consumers
942
+ can pass their own class (e.g. up/down colouring) via `cellFlash.className`. */
943
+ @keyframes sv-grid-cell-flash-kf {
944
+ 0% { background-color: var(--sg-cell-flash, color-mix(in oklab, var(--sg-accent, #3b82f6) 42%, transparent)); }
945
+ 100% { background-color: transparent; }
946
+ }
947
+ .sv-grid-cell-flash {
948
+ animation: sv-grid-cell-flash-kf 0.7s ease-out;
949
+ }
950
+ @media (prefers-reduced-motion: reduce) {
951
+ .sv-grid-cell-flash { animation: none; }
952
+ }
953
+
762
954
  .sv-grid-cell-active,
763
955
  .sv-grid-cell-editing {
764
956
  position: relative;
@@ -1325,6 +1517,32 @@
1325
1517
  .sv-grid-column-menu {
1326
1518
  width: 260px;
1327
1519
  }
1520
+ /* Column-menu tab bar (General / Filter / Columns). */
1521
+ .sv-grid-menu-tabs {
1522
+ display: flex;
1523
+ gap: 2px;
1524
+ margin: -2px -2px 4px;
1525
+ padding: 2px 2px 0;
1526
+ border-bottom: 1px solid var(--sg-border, #e2e8f0);
1527
+ }
1528
+ .sv-grid-menu-tab {
1529
+ flex: 1;
1530
+ padding: 6px 6px;
1531
+ border: 0;
1532
+ border-bottom: 2px solid transparent;
1533
+ background: transparent;
1534
+ color: var(--sg-muted, #64748b);
1535
+ font-size: 12px;
1536
+ font-weight: 600;
1537
+ cursor: pointer;
1538
+ }
1539
+ .sv-grid-menu-tab:hover {
1540
+ color: var(--sg-fg, #0f172a);
1541
+ }
1542
+ .sv-grid-menu-tab.is-active {
1543
+ color: var(--sg-accent, #2563eb);
1544
+ border-bottom-color: var(--sg-accent, #2563eb);
1545
+ }
1328
1546
 
1329
1547
  .sv-grid-operator-menu {
1330
1548
  width: 184px;
@@ -1487,6 +1705,53 @@
1487
1705
  font: inherit;
1488
1706
  }
1489
1707
 
1708
+ /* Multi-condition filter: AND/OR join toggle + add-condition button. */
1709
+ .sv-grid-menu-add-cond {
1710
+ align-self: flex-start;
1711
+ margin-top: 2px;
1712
+ padding: 3px 8px;
1713
+ font-size: 11.5px;
1714
+ font-weight: 600;
1715
+ color: var(--sg-accent, #3b82f6);
1716
+ background: transparent;
1717
+ border: 1px dashed var(--sg-border, #cbd5e1);
1718
+ border-radius: 5px;
1719
+ cursor: pointer;
1720
+ }
1721
+ .sv-grid-menu-add-cond:hover {
1722
+ background: color-mix(in oklab, var(--sg-accent, #3b82f6) 8%, transparent);
1723
+ border-style: solid;
1724
+ }
1725
+ .sv-grid-menu-join {
1726
+ display: inline-flex;
1727
+ align-items: center;
1728
+ gap: 2px;
1729
+ margin: 2px 0;
1730
+ }
1731
+ .sv-grid-menu-join button {
1732
+ padding: 2px 10px;
1733
+ font-size: 11px;
1734
+ font-weight: 700;
1735
+ color: var(--sg-muted, #64748b);
1736
+ background: transparent;
1737
+ border: 1px solid var(--sg-border, #cbd5e1);
1738
+ cursor: pointer;
1739
+ }
1740
+ .sv-grid-menu-join button:first-child { border-radius: 5px 0 0 5px; }
1741
+ .sv-grid-menu-join button:nth-child(2) { border-radius: 0; border-left: 0; }
1742
+ .sv-grid-menu-join button.is-on {
1743
+ background: var(--sg-accent, #3b82f6);
1744
+ color: #fff;
1745
+ border-color: var(--sg-accent, #3b82f6);
1746
+ }
1747
+ .sv-grid-menu-join-x {
1748
+ margin-left: auto;
1749
+ border-radius: 5px !important;
1750
+ font-size: 14px;
1751
+ line-height: 1;
1752
+ padding: 2px 7px !important;
1753
+ }
1754
+
1490
1755
  .sv-grid-facet-list {
1491
1756
  max-height: 200px;
1492
1757
  overflow: auto;