@svelte-atoms/core 1.0.0-alpha.27 → 1.0.0-alpha.28

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 (163) hide show
  1. package/README.md +856 -645
  2. package/dist/components/accordion/accordion-root.svelte +61 -61
  3. package/dist/components/accordion/item/accordion-item-body.svelte +42 -42
  4. package/dist/components/accordion/item/accordion-item-header.svelte +50 -50
  5. package/dist/components/accordion/item/accordion-item-indicator.svelte +50 -50
  6. package/dist/components/accordion/item/accordion-item-root.svelte +65 -65
  7. package/dist/components/alert/alert-actions.svelte +2 -1
  8. package/dist/components/alert/alert-close-button.svelte +18 -20
  9. package/dist/components/alert/alert-content.svelte +2 -1
  10. package/dist/components/alert/alert-description.svelte +2 -1
  11. package/dist/components/alert/alert-icon.svelte +2 -1
  12. package/dist/components/alert/alert-root.svelte +3 -2
  13. package/dist/components/alert/alert-title.svelte +2 -1
  14. package/dist/components/alert/alert.stories.svelte +401 -40
  15. package/dist/components/alert/alert.stories.svelte.d.ts +2 -5
  16. package/dist/components/atom/html-atom.svelte +205 -201
  17. package/dist/components/atom/snippet-renderer.svelte +5 -0
  18. package/dist/components/atom/snippet-renderer.svelte.d.ts +5 -0
  19. package/dist/components/avatar/avatar.stories.svelte.d.ts +1 -1
  20. package/dist/components/badge/badge.stories.svelte.d.ts +1 -1
  21. package/dist/components/breadcrumb/breadcrumb.stories.svelte.d.ts +1 -1
  22. package/dist/components/button/button.stories.svelte +60 -57
  23. package/dist/components/calendar/atoms.d.ts +5 -0
  24. package/dist/components/calendar/atoms.js +5 -0
  25. package/dist/components/calendar/bond.svelte.d.ts +72 -0
  26. package/dist/components/calendar/bond.svelte.js +132 -0
  27. package/dist/components/calendar/calendar-body.svelte +107 -0
  28. package/dist/components/calendar/calendar-body.svelte.d.ts +8 -0
  29. package/dist/components/calendar/calendar-day.svelte +97 -0
  30. package/dist/components/calendar/calendar-day.svelte.d.ts +4 -0
  31. package/dist/components/calendar/calendar-header.svelte +33 -0
  32. package/dist/components/calendar/calendar-header.svelte.d.ts +7 -0
  33. package/dist/components/calendar/calendar-root.svelte +208 -0
  34. package/dist/components/calendar/calendar-root.svelte.d.ts +8 -0
  35. package/dist/components/calendar/calendar-week-day.svelte +34 -0
  36. package/dist/components/calendar/calendar-week-day.svelte.d.ts +9 -0
  37. package/dist/components/calendar/calendar.css +26 -0
  38. package/dist/components/calendar/calendar.stories.svelte +36 -0
  39. package/dist/components/calendar/calendar.stories.svelte.d.ts +6 -0
  40. package/dist/components/calendar/index.d.ts +4 -0
  41. package/dist/components/calendar/index.js +4 -0
  42. package/dist/components/calendar/runes.svelte.d.ts +3 -0
  43. package/dist/components/calendar/runes.svelte.js +25 -0
  44. package/dist/components/calendar/types.d.ts +62 -0
  45. package/dist/components/calendar/types.js +1 -0
  46. package/dist/components/card/card-body.svelte +39 -39
  47. package/dist/components/card/card-description.svelte +41 -41
  48. package/dist/components/card/card-footer.svelte +41 -41
  49. package/dist/components/card/card-header.svelte +41 -41
  50. package/dist/components/card/card-media.svelte +41 -41
  51. package/dist/components/card/card-root.svelte +91 -91
  52. package/dist/components/card/card-subtitle.svelte +41 -41
  53. package/dist/components/card/card-title.svelte +45 -45
  54. package/dist/components/collapsible/collapsible-body.svelte +39 -39
  55. package/dist/components/collapsible/collapsible-header.svelte +39 -39
  56. package/dist/components/collapsible/collapsible-indicator.svelte +50 -50
  57. package/dist/components/collapsible/collapsible-root.svelte +66 -66
  58. package/dist/components/combobox/combobox-root.svelte +65 -65
  59. package/dist/components/container/container.stories.svelte.d.ts +1 -1
  60. package/dist/components/contextmenu/contextmenu-trigger.svelte.d.ts +1 -1
  61. package/dist/components/datagrid/bond.svelte.d.ts +2 -2
  62. package/dist/components/datagrid/datagrid-body.svelte +37 -37
  63. package/dist/components/datagrid/datagrid-checkbox.svelte +101 -101
  64. package/dist/components/datagrid/datagrid-footer.svelte +34 -34
  65. package/dist/components/datagrid/datagrid-header.svelte +49 -49
  66. package/dist/components/datagrid/datagrid-root.svelte +59 -59
  67. package/dist/components/datagrid/td/datagrid-td.svelte +66 -66
  68. package/dist/components/datagrid/th/datagrid-th.svelte +106 -106
  69. package/dist/components/datagrid/tr/datagrid-tr.svelte +88 -88
  70. package/dist/components/date-picker/atoms.d.ts +7 -0
  71. package/dist/components/date-picker/atoms.js +7 -0
  72. package/dist/components/date-picker/bond.svelte.d.ts +67 -0
  73. package/dist/components/date-picker/bond.svelte.js +174 -0
  74. package/dist/components/date-picker/date-picker-calendar.svelte +42 -0
  75. package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +7 -0
  76. package/dist/components/date-picker/date-picker-header.svelte +105 -0
  77. package/dist/components/date-picker/date-picker-header.svelte.d.ts +7 -0
  78. package/dist/components/date-picker/date-picker-months.svelte +150 -0
  79. package/dist/components/date-picker/date-picker-months.svelte.d.ts +7 -0
  80. package/dist/components/date-picker/date-picker-root.svelte +94 -0
  81. package/dist/components/date-picker/date-picker-root.svelte.d.ts +17 -0
  82. package/dist/components/date-picker/date-picker-years.svelte +214 -0
  83. package/dist/components/date-picker/date-picker-years.svelte.d.ts +7 -0
  84. package/dist/components/date-picker/date-picker.stories.svelte +51 -0
  85. package/dist/components/date-picker/date-picker.stories.svelte.d.ts +3 -0
  86. package/dist/components/date-picker/index.d.ts +3 -0
  87. package/dist/components/date-picker/index.js +3 -0
  88. package/dist/components/date-picker/types.d.ts +1 -0
  89. package/dist/components/date-picker/types.js +1 -0
  90. package/dist/components/dialog/dialog-body.svelte +39 -39
  91. package/dist/components/dialog/dialog-close-button.svelte +58 -58
  92. package/dist/components/dialog/dialog-content.svelte +62 -62
  93. package/dist/components/dialog/dialog-description.svelte +40 -40
  94. package/dist/components/dialog/dialog-footer.svelte +39 -39
  95. package/dist/components/dialog/dialog-header.svelte +39 -39
  96. package/dist/components/dialog/dialog-root.svelte +110 -110
  97. package/dist/components/dialog/dialog-title.svelte +41 -41
  98. package/dist/components/drawer/drawer-backdrop.svelte +38 -38
  99. package/dist/components/drawer/drawer-body.svelte +42 -42
  100. package/dist/components/drawer/drawer-content.svelte +42 -42
  101. package/dist/components/drawer/drawer-description.svelte +44 -44
  102. package/dist/components/drawer/drawer-footer.svelte +41 -41
  103. package/dist/components/drawer/drawer-header.svelte +43 -43
  104. package/dist/components/drawer/drawer-root.svelte +93 -93
  105. package/dist/components/drawer/drawer-title.svelte +44 -44
  106. package/dist/components/dropdown/dropdown-query.svelte +54 -54
  107. package/dist/components/dropdown/dropdown-root.svelte +59 -59
  108. package/dist/components/dropdown/dropdown-trigger.svelte +41 -41
  109. package/dist/components/dropdown/dropdown-value.svelte +60 -60
  110. package/dist/components/element/html-element.svelte +85 -85
  111. package/dist/components/form/bond.svelte.d.ts +1 -1
  112. package/dist/components/form/field/field-control.svelte +48 -48
  113. package/dist/components/form/field/field-label.svelte +24 -24
  114. package/dist/components/form/field/field-root.svelte +59 -59
  115. package/dist/components/icon/icon.svelte +44 -44
  116. package/dist/components/image/image.stories.svelte.d.ts +1 -1
  117. package/dist/components/index.d.ts +3 -0
  118. package/dist/components/index.js +3 -0
  119. package/dist/components/input/input-control.svelte +103 -103
  120. package/dist/components/label/label.svelte +25 -25
  121. package/dist/components/popover/popover-arrow.svelte +111 -111
  122. package/dist/components/popover/popover-content.svelte +46 -7
  123. package/dist/components/popover/popover-root.svelte +48 -49
  124. package/dist/components/popover/popover.stories.svelte +52 -67
  125. package/dist/components/portal/portal-root.svelte +83 -83
  126. package/dist/components/portal/teleport.svelte +50 -50
  127. package/dist/components/qr-code/index.d.ts +1 -0
  128. package/dist/components/qr-code/index.js +1 -0
  129. package/dist/components/qr-code/qr-code.stories.svelte +24 -0
  130. package/dist/components/qr-code/qr-code.stories.svelte.d.ts +26 -0
  131. package/dist/components/qr-code/qr-code.svelte +25 -0
  132. package/dist/components/qr-code/qr-code.svelte.d.ts +6 -0
  133. package/dist/components/radio/radio.svelte +109 -109
  134. package/dist/components/radio/types.svelte.d.ts +1 -1
  135. package/dist/components/scrollable/scrollable-container.svelte +82 -82
  136. package/dist/components/scrollable/scrollable-content.svelte +41 -41
  137. package/dist/components/scrollable/scrollable-root.svelte +100 -100
  138. package/dist/components/scrollable/scrollable-thumb.svelte +75 -75
  139. package/dist/components/scrollable/scrollable-track.svelte +59 -59
  140. package/dist/components/scrollable/scrollable.stories.svelte.d.ts +1 -1
  141. package/dist/components/tabs/tab/tab-body.svelte +52 -52
  142. package/dist/components/tabs/tab/tab-description.svelte +41 -41
  143. package/dist/components/tabs/tab/tab-header.svelte +71 -71
  144. package/dist/components/tabs/tab/tab-root.svelte +86 -86
  145. package/dist/components/toast/toast-description.svelte +38 -38
  146. package/dist/components/toast/toast-root.svelte +61 -61
  147. package/dist/components/toast/toast-title.svelte +35 -35
  148. package/dist/components/tree/tree-body.svelte +39 -39
  149. package/dist/components/tree/tree-header.svelte +54 -54
  150. package/dist/components/tree/tree-indicator.svelte +40 -40
  151. package/dist/components/tree/tree-root.svelte +65 -65
  152. package/dist/components/virtual/virtual-root.svelte +239 -239
  153. package/dist/context/preset.svelte.d.ts +1 -1
  154. package/dist/icons/icon-arrow-down.svelte.d.ts +1 -1
  155. package/dist/icons/icon-checkmark.svelte.d.ts +1 -1
  156. package/dist/icons/icon-close.svelte.d.ts +1 -1
  157. package/dist/icons/icon-more-vert.svelte.d.ts +1 -1
  158. package/dist/runes/container.svelte.d.ts +2 -2
  159. package/dist/shared/bond.svelte.d.ts +1 -1
  160. package/dist/utils/state.d.ts +1 -1
  161. package/dist/utils/state.js +2 -1
  162. package/llm/variants.md +1261 -712
  163. package/package.json +464 -437
@@ -1,239 +1,239 @@
1
- <script lang="ts" generics="T">
2
- import type { VirtualListViewportProps } from './types';
3
- import { throttle } from 'es-toolkit';
4
- import { onMount, tick } from 'svelte';
5
- import { twMerge } from 'tailwind-merge';
6
-
7
- let {
8
- class: klass = '',
9
- data = [],
10
- itemHeight,
11
- overscan = 5,
12
- children,
13
- header,
14
- onScroll,
15
- scrollToIndex,
16
- ...restProps
17
- }: VirtualListViewportProps<T> = $props();
18
-
19
- // Internal state
20
- let start = $state(0);
21
- let end = $state(0);
22
-
23
- const visibleItems = $derived(
24
- data.slice(start, end).map((d, i) => ({ index: i + start, data: d }))
25
- );
26
-
27
- let viewportElement: HTMLElement | undefined = $state();
28
- let contentElement: HTMLElement | undefined = $state();
29
- let top = $state(0);
30
- let bottom = $state(0);
31
- let viewportHeight = $state(0);
32
-
33
- // Height management with exponential moving average
34
- let heightMap: number[] = $state([]);
35
- let averageHeight = $state(itemHeight || 50);
36
- let heightSampleCount = $state(0);
37
-
38
- let rows: HTMLElement[] = $state([]);
39
- let mounted = $state(false);
40
-
41
- // trigger initial refresh
42
- onMount(() => {
43
- if (!contentElement) return;
44
-
45
- rows = Array.from(contentElement.getElementsByClassName('virtual-list-row')) as HTMLElement[];
46
-
47
- mounted = true;
48
-
49
- // Give the browser time to render and measure the viewport
50
- setTimeout(() => {
51
- if (viewportElement) {
52
- viewportHeight = viewportElement.offsetHeight;
53
- }
54
-
55
- refresh();
56
- }, 0);
57
- });
58
-
59
- // Watch for data changes and viewport size changes
60
- $effect(() => {
61
- if (mounted) refresh();
62
- });
63
-
64
- // Handle scroll to specific index
65
- $effect(() => {
66
- if (scrollToIndex !== undefined && viewportElement && mounted) {
67
- scrollToItem(scrollToIndex);
68
- }
69
- });
70
-
71
- const handleScroll = throttle(async () => {
72
- if (!viewportElement) return;
73
-
74
- const { scrollTop } = viewportElement;
75
-
76
- // Call user's onScroll callback
77
- onScroll?.(scrollTop);
78
-
79
- await refresh();
80
- }, 1000 / 60);
81
-
82
- // Improved height estimation using exponential moving average
83
- function updateAverageHeight(newHeight: number) {
84
- if (heightSampleCount < 1) {
85
- averageHeight = newHeight;
86
- heightSampleCount = 1;
87
- } else {
88
- // Exponential moving average with alpha = 0.1 for stability
89
- const alpha = Math.min(0.1, 1 / heightSampleCount);
90
- averageHeight = alpha * newHeight + (1 - alpha) * averageHeight;
91
- heightSampleCount++;
92
- }
93
- }
94
-
95
- function getItemHeight(index: number): number {
96
- return heightMap[index] || itemHeight || averageHeight;
97
- }
98
-
99
- async function refresh() {
100
- if (!viewportElement || !mounted) return;
101
-
102
- const { scrollTop } = viewportElement;
103
-
104
- // Calculate visible range with overscan buffer
105
- const startIndex = Math.max(0, findStartIndex(scrollTop) - overscan);
106
- const endIndex = Math.min(data.length, findEndIndex(scrollTop, startIndex) + overscan);
107
-
108
- start = startIndex;
109
- end = endIndex;
110
-
111
- await tick(); // Wait for DOM update
112
-
113
- // Update height measurements for visible items
114
- updateHeights();
115
- updatePadding();
116
- }
117
-
118
- function findStartIndex(scrollTop: number): number {
119
- let index = 0;
120
- let accumulatedHeight = 0;
121
-
122
- while (index < data.length && accumulatedHeight + getItemHeight(index) <= scrollTop) {
123
- accumulatedHeight += getItemHeight(index);
124
- index++;
125
- }
126
-
127
- return index;
128
- }
129
-
130
- function findEndIndex(scrollTop: number, startIndex: number): number {
131
- let index = startIndex;
132
- let accumulatedHeight = 0;
133
-
134
- // Start from the scroll position
135
- for (let i = 0; i < startIndex; i++) {
136
- accumulatedHeight += getItemHeight(i);
137
- }
138
-
139
- // Use a minimum viewport height to ensure we render enough items initially
140
- const effectiveViewportHeight = Math.max(viewportHeight, 800);
141
-
142
- while (index < data.length && accumulatedHeight <= scrollTop + effectiveViewportHeight) {
143
- accumulatedHeight += getItemHeight(index);
144
- index++;
145
- }
146
-
147
- return index;
148
- }
149
-
150
- function updateHeights() {
151
- if (!contentElement) return;
152
-
153
- rows = Array.from(contentElement.getElementsByClassName('virtual-list-row')) as HTMLElement[];
154
-
155
- // Update heights for currently rendered items
156
- rows.forEach((row, i) => {
157
- const actualIndex = start + i;
158
- const measuredHeight = itemHeight || row.offsetHeight;
159
-
160
- if (heightMap[actualIndex] !== measuredHeight) {
161
- heightMap[actualIndex] = measuredHeight;
162
- if (!itemHeight) {
163
- updateAverageHeight(measuredHeight);
164
- }
165
- }
166
- });
167
- }
168
-
169
- function updatePadding() {
170
- // Calculate top padding (sum of heights above visible area)
171
- let topPadding = 0;
172
- for (let i = 0; i < start; i++) {
173
- topPadding += getItemHeight(i);
174
- }
175
-
176
- // Calculate bottom padding (estimated heights below visible area)
177
- let bottomPadding = 0;
178
- for (let i = end; i < data.length; i++) {
179
- bottomPadding += getItemHeight(i);
180
- }
181
-
182
- top = topPadding;
183
- bottom = bottomPadding;
184
- }
185
-
186
- async function scrollToItem(index: number) {
187
- if (!viewportElement || index < 0 || index >= data.length) return;
188
-
189
- let targetScrollTop = 0;
190
- for (let i = 0; i < index; i++) {
191
- targetScrollTop += getItemHeight(i);
192
- }
193
-
194
- viewportElement.scrollTo({
195
- top: targetScrollTop,
196
- behavior: 'smooth'
197
- });
198
- }
199
- </script>
200
-
201
- <div class="absolute inset-0 block size-full max-h-full">
202
- <div
203
- bind:this={viewportElement}
204
- bind:offsetHeight={viewportHeight}
205
- class={twMerge(
206
- 'virtual-list-viewport virtual-list-viewport relative block h-full max-h-full w-full flex-1 overflow-y-auto',
207
- klass
208
- )}
209
- onscroll={handleScroll}
210
- >
211
- <table class={twMerge('virtual-list-contents w-full')} {...restProps}>
212
- {@render header?.()}
213
-
214
- <tbody bind:this={contentElement}>
215
- <!-- Top spacer row -->
216
- {#if top > 0}
217
- <tr style="height: {top}px;">
218
- <td colspan="100" style="padding: 0; border: none;"></td>
219
- </tr>
220
- {/if}
221
-
222
- {@render children?.({ items: visibleItems })}
223
-
224
- <!-- Bottom spacer row -->
225
- {#if bottom > 0}
226
- <tr style="height: {bottom}px;">
227
- <td colspan="100" style="padding: 0; border: none;"></td>
228
- </tr>
229
- {/if}
230
- </tbody>
231
- </table>
232
- </div>
233
- </div>
234
-
235
- <style>
236
- .virtual-list-viewport {
237
- -webkit-overflow-scrolling: touch;
238
- }
239
- </style>
1
+ <script lang="ts" generics="T">
2
+ import type { VirtualListViewportProps } from './types';
3
+ import { throttle } from 'es-toolkit';
4
+ import { onMount, tick } from 'svelte';
5
+ import { twMerge } from 'tailwind-merge';
6
+
7
+ let {
8
+ class: klass = '',
9
+ data = [],
10
+ itemHeight,
11
+ overscan = 5,
12
+ children,
13
+ header,
14
+ onScroll,
15
+ scrollToIndex,
16
+ ...restProps
17
+ }: VirtualListViewportProps<T> = $props();
18
+
19
+ // Internal state
20
+ let start = $state(0);
21
+ let end = $state(0);
22
+
23
+ const visibleItems = $derived(
24
+ data.slice(start, end).map((d, i) => ({ index: i + start, data: d }))
25
+ );
26
+
27
+ let viewportElement: HTMLElement | undefined = $state();
28
+ let contentElement: HTMLElement | undefined = $state();
29
+ let top = $state(0);
30
+ let bottom = $state(0);
31
+ let viewportHeight = $state(0);
32
+
33
+ // Height management with exponential moving average
34
+ let heightMap: number[] = $state([]);
35
+ let averageHeight = $state(itemHeight || 50);
36
+ let heightSampleCount = $state(0);
37
+
38
+ let rows: HTMLElement[] = $state([]);
39
+ let mounted = $state(false);
40
+
41
+ // trigger initial refresh
42
+ onMount(() => {
43
+ if (!contentElement) return;
44
+
45
+ rows = Array.from(contentElement.getElementsByClassName('virtual-list-row')) as HTMLElement[];
46
+
47
+ mounted = true;
48
+
49
+ // Give the browser time to render and measure the viewport
50
+ setTimeout(() => {
51
+ if (viewportElement) {
52
+ viewportHeight = viewportElement.offsetHeight;
53
+ }
54
+
55
+ refresh();
56
+ }, 0);
57
+ });
58
+
59
+ // Watch for data changes and viewport size changes
60
+ $effect(() => {
61
+ if (mounted) refresh();
62
+ });
63
+
64
+ // Handle scroll to specific index
65
+ $effect(() => {
66
+ if (scrollToIndex !== undefined && viewportElement && mounted) {
67
+ scrollToItem(scrollToIndex);
68
+ }
69
+ });
70
+
71
+ const handleScroll = throttle(async () => {
72
+ if (!viewportElement) return;
73
+
74
+ const { scrollTop } = viewportElement;
75
+
76
+ // Call user's onScroll callback
77
+ onScroll?.(scrollTop);
78
+
79
+ await refresh();
80
+ }, 1000 / 60);
81
+
82
+ // Improved height estimation using exponential moving average
83
+ function updateAverageHeight(newHeight: number) {
84
+ if (heightSampleCount < 1) {
85
+ averageHeight = newHeight;
86
+ heightSampleCount = 1;
87
+ } else {
88
+ // Exponential moving average with alpha = 0.1 for stability
89
+ const alpha = Math.min(0.1, 1 / heightSampleCount);
90
+ averageHeight = alpha * newHeight + (1 - alpha) * averageHeight;
91
+ heightSampleCount++;
92
+ }
93
+ }
94
+
95
+ function getItemHeight(index: number): number {
96
+ return heightMap[index] || itemHeight || averageHeight;
97
+ }
98
+
99
+ async function refresh() {
100
+ if (!viewportElement || !mounted) return;
101
+
102
+ const { scrollTop } = viewportElement;
103
+
104
+ // Calculate visible range with overscan buffer
105
+ const startIndex = Math.max(0, findStartIndex(scrollTop) - overscan);
106
+ const endIndex = Math.min(data.length, findEndIndex(scrollTop, startIndex) + overscan);
107
+
108
+ start = startIndex;
109
+ end = endIndex;
110
+
111
+ await tick(); // Wait for DOM update
112
+
113
+ // Update height measurements for visible items
114
+ updateHeights();
115
+ updatePadding();
116
+ }
117
+
118
+ function findStartIndex(scrollTop: number): number {
119
+ let index = 0;
120
+ let accumulatedHeight = 0;
121
+
122
+ while (index < data.length && accumulatedHeight + getItemHeight(index) <= scrollTop) {
123
+ accumulatedHeight += getItemHeight(index);
124
+ index++;
125
+ }
126
+
127
+ return index;
128
+ }
129
+
130
+ function findEndIndex(scrollTop: number, startIndex: number): number {
131
+ let index = startIndex;
132
+ let accumulatedHeight = 0;
133
+
134
+ // Start from the scroll position
135
+ for (let i = 0; i < startIndex; i++) {
136
+ accumulatedHeight += getItemHeight(i);
137
+ }
138
+
139
+ // Use a minimum viewport height to ensure we render enough items initially
140
+ const effectiveViewportHeight = Math.max(viewportHeight, 800);
141
+
142
+ while (index < data.length && accumulatedHeight <= scrollTop + effectiveViewportHeight) {
143
+ accumulatedHeight += getItemHeight(index);
144
+ index++;
145
+ }
146
+
147
+ return index;
148
+ }
149
+
150
+ function updateHeights() {
151
+ if (!contentElement) return;
152
+
153
+ rows = Array.from(contentElement.getElementsByClassName('virtual-list-row')) as HTMLElement[];
154
+
155
+ // Update heights for currently rendered items
156
+ rows.forEach((row, i) => {
157
+ const actualIndex = start + i;
158
+ const measuredHeight = itemHeight || row.offsetHeight;
159
+
160
+ if (heightMap[actualIndex] !== measuredHeight) {
161
+ heightMap[actualIndex] = measuredHeight;
162
+ if (!itemHeight) {
163
+ updateAverageHeight(measuredHeight);
164
+ }
165
+ }
166
+ });
167
+ }
168
+
169
+ function updatePadding() {
170
+ // Calculate top padding (sum of heights above visible area)
171
+ let topPadding = 0;
172
+ for (let i = 0; i < start; i++) {
173
+ topPadding += getItemHeight(i);
174
+ }
175
+
176
+ // Calculate bottom padding (estimated heights below visible area)
177
+ let bottomPadding = 0;
178
+ for (let i = end; i < data.length; i++) {
179
+ bottomPadding += getItemHeight(i);
180
+ }
181
+
182
+ top = topPadding;
183
+ bottom = bottomPadding;
184
+ }
185
+
186
+ async function scrollToItem(index: number) {
187
+ if (!viewportElement || index < 0 || index >= data.length) return;
188
+
189
+ let targetScrollTop = 0;
190
+ for (let i = 0; i < index; i++) {
191
+ targetScrollTop += getItemHeight(i);
192
+ }
193
+
194
+ viewportElement.scrollTo({
195
+ top: targetScrollTop,
196
+ behavior: 'smooth'
197
+ });
198
+ }
199
+ </script>
200
+
201
+ <div class="absolute inset-0 block size-full max-h-full">
202
+ <div
203
+ bind:this={viewportElement}
204
+ bind:offsetHeight={viewportHeight}
205
+ class={twMerge(
206
+ 'virtual-list-viewport virtual-list-viewport relative block h-full max-h-full w-full flex-1 overflow-y-auto',
207
+ klass
208
+ )}
209
+ onscroll={handleScroll}
210
+ >
211
+ <table class={twMerge('virtual-list-contents w-full')} {...restProps}>
212
+ {@render header?.()}
213
+
214
+ <tbody bind:this={contentElement}>
215
+ <!-- Top spacer row -->
216
+ {#if top > 0}
217
+ <tr style="height: {top}px;">
218
+ <td colspan="100" style="padding: 0; border: none;"></td>
219
+ </tr>
220
+ {/if}
221
+
222
+ {@render children?.({ items: visibleItems })}
223
+
224
+ <!-- Bottom spacer row -->
225
+ {#if bottom > 0}
226
+ <tr style="height: {bottom}px;">
227
+ <td colspan="100" style="padding: 0; border: none;"></td>
228
+ </tr>
229
+ {/if}
230
+ </tbody>
231
+ </table>
232
+ </div>
233
+ </div>
234
+
235
+ <style>
236
+ .virtual-list-viewport {
237
+ -webkit-overflow-scrolling: touch;
238
+ }
239
+ </style>
@@ -1,7 +1,7 @@
1
1
  import type { ClassValue } from 'svelte/elements';
2
2
  import type { Base } from '../components/atom';
3
3
  import type { Bond } from '../shared';
4
- export type PresetModuleName = 'accordion' | 'accordion.item.body' | 'accordion.item.header' | 'accordion.item.indicator' | 'accordion.item' | 'alert.actions' | 'alert.close-button' | 'alert.content' | 'alert.description' | 'alert.icon' | 'alert' | 'alert.title' | 'card.content' | 'card.description' | 'card.footer' | 'card.header' | 'card.media' | 'card' | 'card.subtitle' | 'card.title' | 'collapsible.body' | 'collapsible.header' | 'collapsible.indicator' | 'collapsible' | 'combobox.control' | 'combobox.trigger' | 'combobox.item' | 'dialog.close-button' | 'dialog.body' | 'dialog.content' | 'dialog.description' | 'dialog.footer' | 'dialog.header' | 'dialog' | 'dialog.title' | 'divider' | 'dropdown.placeholder' | 'dropdown.query' | 'dropdown.trigger' | 'dropdown.value' | 'dropdown' | 'field.control' | 'field.label' | 'field' | 'form' | 'icon' | 'input' | 'input.control' | 'input.placeholder' | 'label' | 'layer.inner' | 'layer' | 'link' | 'list.divider' | 'list.group' | 'list.item' | 'list.item' | 'list.item' | 'dropdown.item' | 'menu.body' | 'popover.arrow' | 'popover.indicator' | 'popover.content' | 'popover.trigger' | 'portal.inner' | 'portal' | 'root' | 'root.portals' | 'sidebar.content' | 'sidebar' | 'drawer.backdrop' | 'drawer.body' | 'drawer.content' | 'drawer.description' | 'drawer.title' | 'drawer.footer' | 'drawer.header' | 'drawer' | 'stack.root' | 'stack.item' | 'tabs.body' | 'tabs.header' | 'tabs' | 'tab.header' | 'tab.body' | 'tab.description' | 'tab' | 'tree.body' | 'tree.header' | 'tree.indicator' | 'tree' | 'datagrid' | 'datagrid.header' | 'datagrid.th' | 'datagrid.body' | 'datagrid.tr' | 'datagrid.td' | 'datagrid.footer' | 'datagrid.checkbox' | 'datagrid.sort-icon' | 'scrollable' | 'scrollable.container' | 'scrollable.content' | 'scrollable.track' | 'scrollable.thumb' | 'breadcrumb' | 'breadcrumb.item' | 'breadcrumb.separator' | 'badge' | 'button' | 'checkbox' | 'checkbox.checkmark' | 'checkbox.indeterminate' | 'radio' | 'radio.group' | 'container';
4
+ export type PresetModuleName = 'accordion' | 'accordion.item.body' | 'accordion.item.header' | 'accordion.item.indicator' | 'accordion.item' | 'alert.actions' | 'alert.close-button' | 'alert.content' | 'alert.description' | 'alert.icon' | 'alert' | 'alert.title' | 'card.content' | 'card.description' | 'card.footer' | 'card.header' | 'card.media' | 'card' | 'card.subtitle' | 'card.title' | 'collapsible.body' | 'collapsible.header' | 'collapsible.indicator' | 'collapsible' | 'combobox.control' | 'combobox.trigger' | 'combobox.item' | 'dialog.close-button' | 'dialog.body' | 'dialog.content' | 'dialog.description' | 'dialog.footer' | 'dialog.header' | 'dialog' | 'dialog.title' | 'divider' | 'dropdown.placeholder' | 'dropdown.query' | 'dropdown.trigger' | 'dropdown.value' | 'dropdown' | 'field.control' | 'field.label' | 'field' | 'form' | 'icon' | 'input' | 'input.control' | 'input.placeholder' | 'label' | 'layer.inner' | 'layer' | 'link' | 'list.divider' | 'list.group' | 'list.item' | 'list.item' | 'list.item' | 'dropdown.item' | 'menu.body' | 'popover.arrow' | 'popover.indicator' | 'popover.content' | 'popover.trigger' | 'portal.inner' | 'portal' | 'root' | 'root.portals' | 'sidebar.content' | 'sidebar' | 'drawer.backdrop' | 'drawer.body' | 'drawer.content' | 'drawer.description' | 'drawer.title' | 'drawer.footer' | 'drawer.header' | 'drawer' | 'stack.root' | 'stack.item' | 'tabs.body' | 'tabs.header' | 'tabs' | 'tab.header' | 'tab.body' | 'tab.description' | 'tab' | 'tree.body' | 'tree.header' | 'tree.indicator' | 'tree' | 'datagrid' | 'datagrid.header' | 'datagrid.th' | 'datagrid.body' | 'datagrid.tr' | 'datagrid.td' | 'datagrid.footer' | 'datagrid.checkbox' | 'datagrid.sort-icon' | 'scrollable' | 'scrollable.container' | 'scrollable.content' | 'scrollable.track' | 'scrollable.thumb' | 'breadcrumb' | 'breadcrumb.item' | 'breadcrumb.separator' | 'badge' | 'button' | 'checkbox' | 'checkbox.checkmark' | 'checkbox.indeterminate' | 'radio' | 'radio.group' | 'container' | 'calendar' | 'calendar.day' | 'calendar.header' | 'calendar.weekday' | 'calendar.body' | 'datepicker.trigger' | 'datepicker.calendar' | 'datepicker.years' | 'datepicker.months' | 'datepicker.header';
5
5
  export type PresetEntryRecord = {
6
6
  [key: string]: unknown;
7
7
  class?: ClassValue;
@@ -4,7 +4,7 @@ type IconArrowDown = SvelteComponent<{
4
4
  }, {
5
5
  [evt: string]: CustomEvent<any>;
6
6
  }, {}> & {
7
- $$bindings?: string | undefined;
7
+ $$bindings?: string;
8
8
  };
9
9
  declare const IconArrowDown: $$__sveltets_2_IsomorphicComponent<{
10
10
  [x: string]: never;
@@ -4,7 +4,7 @@ type IconCheckmark = SvelteComponent<{
4
4
  }, {
5
5
  [evt: string]: CustomEvent<any>;
6
6
  }, {}> & {
7
- $$bindings?: string | undefined;
7
+ $$bindings?: string;
8
8
  };
9
9
  declare const IconCheckmark: $$__sveltets_2_IsomorphicComponent<{
10
10
  [x: string]: never;
@@ -4,7 +4,7 @@ type IconClose = SvelteComponent<{
4
4
  }, {
5
5
  [evt: string]: CustomEvent<any>;
6
6
  }, {}> & {
7
- $$bindings?: string | undefined;
7
+ $$bindings?: string;
8
8
  };
9
9
  declare const IconClose: $$__sveltets_2_IsomorphicComponent<{
10
10
  [x: string]: never;
@@ -4,7 +4,7 @@ type IconMoreVert = SvelteComponent<{
4
4
  }, {
5
5
  [evt: string]: CustomEvent<any>;
6
6
  }, {}> & {
7
- $$bindings?: string | undefined;
7
+ $$bindings?: string;
8
8
  };
9
9
  declare const IconMoreVert: $$__sveltets_2_IsomorphicComponent<{
10
10
  [x: string]: never;
@@ -1,7 +1,7 @@
1
1
  export declare function container(): {
2
2
  readonly current: {
3
- width?: number | undefined;
4
- height?: number | undefined;
3
+ width?: number;
4
+ height?: number;
5
5
  };
6
6
  attach: (node: HTMLElement) => void;
7
7
  };
@@ -1,4 +1,4 @@
1
- export type BondStateProps = Record<string, unknown> & {
1
+ export type BondStateProps = {
2
2
  id?: string;
3
3
  };
4
4
  export type BondElements = Record<string, Element | undefined>;
@@ -1,3 +1,3 @@
1
1
  export type StateDefiner<T extends object> = (base: T) => T;
2
2
  export declare function defineState<T extends object>(definers: StateDefiner<Partial<T>>[], base?: () => Partial<T>): T;
3
- export declare function defineProperty<T extends object, R>(property: keyof T | (string & {}), get: () => R, set?: (value: R) => void): (base: T) => T;
3
+ export declare function defineProperty<T extends Record<string, unknown>, R>(property: keyof T | (string & {}), get: () => R, set?: (value: R) => void): (base: T) => T;
@@ -12,7 +12,8 @@ export function defineProperty(property, get, set) {
12
12
  }
13
13
  return Object.defineProperty(base, property, {
14
14
  get: get,
15
- set: set
15
+ set: set,
16
+ enumerable: true
16
17
  });
17
18
  };
18
19
  }