@svgrid/grid 2.2.0 → 2.2.1

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 (114) hide show
  1. package/dist/FlexRender.svelte +96 -96
  2. package/dist/GridFooter.svelte +178 -178
  3. package/dist/SvCarousel.svelte +141 -141
  4. package/dist/SvColorInput.svelte +187 -187
  5. package/dist/SvContextMenu.svelte +116 -116
  6. package/dist/SvDrawer.svelte +250 -250
  7. package/dist/SvGrid.svelte +3131 -3131
  8. package/dist/SvGridBoard.svelte +2339 -2339
  9. package/dist/SvGridChart.svelte +1724 -1724
  10. package/dist/SvGridChartPanel.svelte +485 -485
  11. package/dist/SvGridDropdown.svelte +689 -689
  12. package/dist/SvGroupCell.svelte +109 -109
  13. package/dist/SvMenu.svelte +124 -124
  14. package/dist/SvMenuList.svelte +117 -117
  15. package/dist/SvNumberInput.svelte +131 -131
  16. package/dist/SvOtpInput.svelte +158 -158
  17. package/dist/SvPopover.svelte +139 -139
  18. package/dist/SvRowGroupPanel.svelte +170 -170
  19. package/dist/SvScrollArea.svelte +61 -61
  20. package/dist/SvTooltip.svelte +127 -127
  21. package/dist/SvTour.svelte +204 -204
  22. package/dist/SvTree.svelte +377 -377
  23. package/dist/SvTreeSelect.svelte +230 -230
  24. package/dist/cdn/svgrid.js +8 -8
  25. package/dist/cdn/svgrid.svelte-external.js +8 -8
  26. package/dist/chart-export.js +8 -8
  27. package/package.json +10 -10
  28. package/src/FlexRender.svelte +96 -96
  29. package/src/GridFooter.svelte +178 -178
  30. package/src/SvCarousel.svelte +141 -141
  31. package/src/SvColorInput.svelte +187 -187
  32. package/src/SvContextMenu.svelte +116 -116
  33. package/src/SvDrawer.svelte +250 -250
  34. package/src/SvGrid.controller.svelte.ts +3158 -3158
  35. package/src/SvGrid.svelte +3131 -3131
  36. package/src/SvGrid.types.ts +1489 -1489
  37. package/src/SvGridBoard.svelte +2339 -2339
  38. package/src/SvGridChart.svelte +1724 -1724
  39. package/src/SvGridChartPanel.svelte +485 -485
  40. package/src/SvGridDropdown.svelte +689 -689
  41. package/src/SvGroupCell.svelte +109 -109
  42. package/src/SvMenu.svelte +124 -124
  43. package/src/SvMenu.test.ts +97 -97
  44. package/src/SvMenuList.svelte +117 -117
  45. package/src/SvNumberInput.svelte +131 -131
  46. package/src/SvOtpInput.svelte +158 -158
  47. package/src/SvPopover.svelte +139 -139
  48. package/src/SvRowGroupPanel.svelte +170 -170
  49. package/src/SvScrollArea.svelte +61 -61
  50. package/src/SvTooltip.svelte +127 -127
  51. package/src/SvTour.svelte +204 -204
  52. package/src/SvTree.svelte +377 -377
  53. package/src/SvTreeSelect.svelte +230 -230
  54. package/src/a11y.contract.test.ts +49 -49
  55. package/src/a11y.test.ts +59 -59
  56. package/src/a11y.ts +61 -61
  57. package/src/build-api.ts +870 -870
  58. package/src/cell-formatting.ts +169 -169
  59. package/src/cell-render.ts +469 -469
  60. package/src/chart-export.ts +201 -201
  61. package/src/chart.ts +2296 -2296
  62. package/src/collaboration.test.ts +104 -104
  63. package/src/collaboration.ts +167 -167
  64. package/src/core.performance.test.ts +30 -30
  65. package/src/core.ts +1111 -1111
  66. package/src/createAutocomplete.svelte.ts +132 -132
  67. package/src/createCombobox.svelte.ts +179 -179
  68. package/src/createCountryInput.svelte.ts +157 -157
  69. package/src/createDropdownList.svelte.ts +162 -162
  70. package/src/createGrid.svelte.ts +42 -42
  71. package/src/createGrid.test.ts +10 -10
  72. package/src/createGridState.svelte.ts +17 -17
  73. package/src/createMenu.svelte.ts +202 -202
  74. package/src/createPopoverSelect.svelte.ts +206 -206
  75. package/src/createTree.svelte.ts +319 -319
  76. package/src/editing.test.ts +859 -859
  77. package/src/editing.ts +675 -675
  78. package/src/export-data-api.test.ts +126 -126
  79. package/src/export-format.test.ts +107 -107
  80. package/src/export-format.ts +598 -598
  81. package/src/flex-render.ts +3 -3
  82. package/src/index.ts +623 -623
  83. package/src/keyboard.test.ts +59 -59
  84. package/src/keyboard.ts +97 -97
  85. package/src/list-nav.test.ts +49 -49
  86. package/src/list-nav.ts +29 -29
  87. package/src/menus.ts +639 -639
  88. package/src/merge-objects.ts +48 -48
  89. package/src/overlays.test.ts +90 -90
  90. package/src/render-component.ts +28 -28
  91. package/src/selection.test.ts +754 -754
  92. package/src/selection.ts +600 -600
  93. package/src/server-data-source.test.ts +289 -289
  94. package/src/server-data-source.ts +413 -413
  95. package/src/sparkline.test.ts +68 -68
  96. package/src/sparkline.ts +169 -169
  97. package/src/spreadsheet.test.ts +489 -489
  98. package/src/spreadsheet.ts +312 -312
  99. package/src/static-functions.ts +11 -11
  100. package/src/subscribe.ts +38 -38
  101. package/src/svgrid-wrapper.types.ts +501 -501
  102. package/src/svgrid.behavior.test.ts +706 -706
  103. package/src/svgrid.charting.test.ts +527 -527
  104. package/src/svgrid.features.test.ts +157 -157
  105. package/src/svgrid.new-features.wrapper.test.ts +251 -251
  106. package/src/svgrid.wrapper.test.ts +40 -40
  107. package/src/test-setup.ts +62 -62
  108. package/src/themes/index.ts +159 -159
  109. package/src/virtualization/column-virtualizer.test.ts +27 -27
  110. package/src/virtualization/column-virtualizer.ts +30 -30
  111. package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
  112. package/src/virtualization/types.ts +30 -30
  113. package/src/virtualization/virtualizer.test.ts +47 -47
  114. package/src/virtualization/virtualizer.ts +296 -296
@@ -1,127 +1,127 @@
1
- <script lang="ts">
2
- /**
3
- * SvTooltip - a small hover/focus tooltip anchored to its child, portalled to
4
- * <body> so it is never clipped. Shows after a short delay, hides on leave /
5
- * blur / Escape, and is wired via `aria-describedby` (role="tooltip") onto the
6
- * focusable child itself, so AT users get it announced on focus, not just
7
- * sighted users on hover.
8
- *
9
- * ```svelte
10
- * <SvTooltip text="Delete row"><button aria-label="Delete">🗑</button></SvTooltip>
11
- * ```
12
- */
13
- import type { Snippet } from 'svelte'
14
- import { portalToBody, popIn } from './popover'
15
- import { getFocusable } from './a11y/focus-trap'
16
- import { createTooltip } from './createTooltip.svelte'
17
-
18
- type Props = {
19
- text: string
20
- placement?: 'top' | 'bottom'
21
- /** Show delay in ms. Default 300. */
22
- delay?: number
23
- disabled?: boolean
24
- children?: Snippet
25
- }
26
-
27
- let { text, placement = 'top', delay = 300, disabled = false, children }: Props = $props()
28
-
29
- let anchorEl = $state<HTMLSpanElement | null>(null)
30
- let tipEl = $state<HTMLDivElement | null>(null)
31
- let pos = $state({ top: 0, left: 0, arrowX: 12 })
32
-
33
- // Open state, show-delay and Escape-to-hide live in the shared headless core;
34
- // this component owns only the DOM concerns (positioning + describedby merge).
35
- const tip = createTooltip({ text: () => text, disabled: () => disabled, delay: () => delay })
36
- const tid = tip.tipId
37
-
38
- function place() {
39
- if (!anchorEl) return
40
- const r = anchorEl.getBoundingClientRect()
41
- const tipH = tipEl?.offsetHeight ?? 30
42
- const tipW = tipEl?.offsetWidth ?? 0
43
- const top = placement === 'top' ? r.top - tipH - 8 : r.bottom + 8
44
- let left = r.left + r.width / 2 - tipW / 2
45
- left = Math.max(4, Math.min(left, window.innerWidth - tipW - 4))
46
- // Keep the arrow under the anchor's center even when the tip is clamped.
47
- const arrowX = Math.max(10, Math.min(tipW - 10, r.left + r.width / 2 - left))
48
- pos = { top, left, arrowX }
49
- }
50
-
51
- // Reposition while open (and on scroll/resize). Escape-to-hide is the core's.
52
- $effect(() => {
53
- if (!tip.open) return
54
- queueMicrotask(place)
55
- const rp = () => place()
56
- window.addEventListener('scroll', rp, true)
57
- window.addEventListener('resize', rp)
58
- return () => {
59
- window.removeEventListener('scroll', rp, true)
60
- window.removeEventListener('resize', rp)
61
- }
62
- })
63
-
64
- // The wrapper span above is never itself Tab-focusable, so putting
65
- // aria-describedby only on it does nothing for keyboard/AT users - they
66
- // focus the real interactive child (e.g. the <button> in the doc example),
67
- // and that's the element whose accessible description actually gets
68
- // announced. Mirror the id onto that child too, merging with (and later
69
- // restoring) any aria-describedby it already carries.
70
- $effect(() => {
71
- if (!tip.open || !anchorEl) return
72
- const child = getFocusable(anchorEl)[0]
73
- if (!child) return
74
- const before = child.getAttribute('aria-describedby')
75
- const ids = new Set((before ?? '').split(/\s+/).filter(Boolean))
76
- ids.add(tid)
77
- child.setAttribute('aria-describedby', [...ids].join(' '))
78
- return () => {
79
- const remaining = (child.getAttribute('aria-describedby') ?? '')
80
- .split(/\s+/)
81
- .filter((id) => id && id !== tid)
82
- if (remaining.length) child.setAttribute('aria-describedby', remaining.join(' '))
83
- else child.removeAttribute('aria-describedby')
84
- }
85
- })
86
- </script>
87
-
88
- <!-- svelte-ignore a11y_no_static_element_interactions -->
89
- <span
90
- bind:this={anchorEl}
91
- class="sv-tip__anchor"
92
- {...tip.anchorProps()}
93
- >
94
- {@render children?.()}
95
- </span>
96
-
97
- {#if tip.open}
98
- <div
99
- bind:this={tipEl}
100
- id={tid}
101
- class="sv-tip"
102
- role="tooltip"
103
- use:portalToBody
104
- use:popIn={{ up: placement === 'top', duration: 110, scale: 0.9 }}
105
- class:sv-tip--bottom={placement === 'bottom'}
106
- style:position="fixed"
107
- style:top={`${pos.top}px`}
108
- style:left={`${pos.left}px`}
109
- style:--tip-arrow-x={`${pos.arrowX}px`}
110
- >{text}<span class="sv-tip__arrow" aria-hidden="true"></span></div>
111
- {/if}
112
-
113
- <style>
114
- .sv-tip__anchor { display: inline-flex; }
115
- :global(.sv-tip) {
116
- z-index: 2147483647; pointer-events: none; position: relative;
117
- max-width: 240px; padding: 5px 9px; font-size: 12px; line-height: 1.4; font-weight: 500;
118
- background: var(--sg-fg, #0f172a); color: var(--sg-bg, #fff);
119
- border-radius: 6px; box-shadow: 0 6px 20px -6px rgba(15, 23, 42, 0.5); white-space: normal;
120
- }
121
- :global(.sv-tip__arrow) {
122
- position: absolute; inset-inline-start: var(--tip-arrow-x, 12px); width: 8px; height: 8px;
123
- background: var(--sg-fg, #0f172a); transform: translateX(-50%) rotate(45deg);
124
- }
125
- :global(.sv-tip:not(.sv-tip--bottom) .sv-tip__arrow) { bottom: -3px; }
126
- :global(.sv-tip--bottom .sv-tip__arrow) { top: -3px; }
127
- </style>
1
+ <script lang="ts">
2
+ /**
3
+ * SvTooltip - a small hover/focus tooltip anchored to its child, portalled to
4
+ * <body> so it is never clipped. Shows after a short delay, hides on leave /
5
+ * blur / Escape, and is wired via `aria-describedby` (role="tooltip") onto the
6
+ * focusable child itself, so AT users get it announced on focus, not just
7
+ * sighted users on hover.
8
+ *
9
+ * ```svelte
10
+ * <SvTooltip text="Delete row"><button aria-label="Delete">🗑</button></SvTooltip>
11
+ * ```
12
+ */
13
+ import type { Snippet } from 'svelte'
14
+ import { portalToBody, popIn } from './popover'
15
+ import { getFocusable } from './a11y/focus-trap'
16
+ import { createTooltip } from './createTooltip.svelte'
17
+
18
+ type Props = {
19
+ text: string
20
+ placement?: 'top' | 'bottom'
21
+ /** Show delay in ms. Default 300. */
22
+ delay?: number
23
+ disabled?: boolean
24
+ children?: Snippet
25
+ }
26
+
27
+ let { text, placement = 'top', delay = 300, disabled = false, children }: Props = $props()
28
+
29
+ let anchorEl = $state<HTMLSpanElement | null>(null)
30
+ let tipEl = $state<HTMLDivElement | null>(null)
31
+ let pos = $state({ top: 0, left: 0, arrowX: 12 })
32
+
33
+ // Open state, show-delay and Escape-to-hide live in the shared headless core;
34
+ // this component owns only the DOM concerns (positioning + describedby merge).
35
+ const tip = createTooltip({ text: () => text, disabled: () => disabled, delay: () => delay })
36
+ const tid = tip.tipId
37
+
38
+ function place() {
39
+ if (!anchorEl) return
40
+ const r = anchorEl.getBoundingClientRect()
41
+ const tipH = tipEl?.offsetHeight ?? 30
42
+ const tipW = tipEl?.offsetWidth ?? 0
43
+ const top = placement === 'top' ? r.top - tipH - 8 : r.bottom + 8
44
+ let left = r.left + r.width / 2 - tipW / 2
45
+ left = Math.max(4, Math.min(left, window.innerWidth - tipW - 4))
46
+ // Keep the arrow under the anchor's center even when the tip is clamped.
47
+ const arrowX = Math.max(10, Math.min(tipW - 10, r.left + r.width / 2 - left))
48
+ pos = { top, left, arrowX }
49
+ }
50
+
51
+ // Reposition while open (and on scroll/resize). Escape-to-hide is the core's.
52
+ $effect(() => {
53
+ if (!tip.open) return
54
+ queueMicrotask(place)
55
+ const rp = () => place()
56
+ window.addEventListener('scroll', rp, true)
57
+ window.addEventListener('resize', rp)
58
+ return () => {
59
+ window.removeEventListener('scroll', rp, true)
60
+ window.removeEventListener('resize', rp)
61
+ }
62
+ })
63
+
64
+ // The wrapper span above is never itself Tab-focusable, so putting
65
+ // aria-describedby only on it does nothing for keyboard/AT users - they
66
+ // focus the real interactive child (e.g. the <button> in the doc example),
67
+ // and that's the element whose accessible description actually gets
68
+ // announced. Mirror the id onto that child too, merging with (and later
69
+ // restoring) any aria-describedby it already carries.
70
+ $effect(() => {
71
+ if (!tip.open || !anchorEl) return
72
+ const child = getFocusable(anchorEl)[0]
73
+ if (!child) return
74
+ const before = child.getAttribute('aria-describedby')
75
+ const ids = new Set((before ?? '').split(/\s+/).filter(Boolean))
76
+ ids.add(tid)
77
+ child.setAttribute('aria-describedby', [...ids].join(' '))
78
+ return () => {
79
+ const remaining = (child.getAttribute('aria-describedby') ?? '')
80
+ .split(/\s+/)
81
+ .filter((id) => id && id !== tid)
82
+ if (remaining.length) child.setAttribute('aria-describedby', remaining.join(' '))
83
+ else child.removeAttribute('aria-describedby')
84
+ }
85
+ })
86
+ </script>
87
+
88
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
89
+ <span
90
+ bind:this={anchorEl}
91
+ class="sv-tip__anchor"
92
+ {...tip.anchorProps()}
93
+ >
94
+ {@render children?.()}
95
+ </span>
96
+
97
+ {#if tip.open}
98
+ <div
99
+ bind:this={tipEl}
100
+ id={tid}
101
+ class="sv-tip"
102
+ role="tooltip"
103
+ use:portalToBody
104
+ use:popIn={{ up: placement === 'top', duration: 110, scale: 0.9 }}
105
+ class:sv-tip--bottom={placement === 'bottom'}
106
+ style:position="fixed"
107
+ style:top={`${pos.top}px`}
108
+ style:left={`${pos.left}px`}
109
+ style:--tip-arrow-x={`${pos.arrowX}px`}
110
+ >{text}<span class="sv-tip__arrow" aria-hidden="true"></span></div>
111
+ {/if}
112
+
113
+ <style>
114
+ .sv-tip__anchor { display: inline-flex; }
115
+ :global(.sv-tip) {
116
+ z-index: 2147483647; pointer-events: none; position: relative;
117
+ max-width: 240px; padding: 5px 9px; font-size: 12px; line-height: 1.4; font-weight: 500;
118
+ background: var(--sg-fg, #0f172a); color: var(--sg-bg, #fff);
119
+ border-radius: 6px; box-shadow: 0 6px 20px -6px rgba(15, 23, 42, 0.5); white-space: normal;
120
+ }
121
+ :global(.sv-tip__arrow) {
122
+ position: absolute; inset-inline-start: var(--tip-arrow-x, 12px); width: 8px; height: 8px;
123
+ background: var(--sg-fg, #0f172a); transform: translateX(-50%) rotate(45deg);
124
+ }
125
+ :global(.sv-tip:not(.sv-tip--bottom) .sv-tip__arrow) { bottom: -3px; }
126
+ :global(.sv-tip--bottom .sv-tip__arrow) { top: -3px; }
127
+ </style>