@x33025/sveltely 0.0.57 → 0.1.0

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 (187) hide show
  1. package/dist/actions/tooltip.d.ts +10 -0
  2. package/dist/actions/tooltip.js +255 -0
  3. package/dist/components/{AnimatedNumber.demo.svelte → Library/AnimatedNumber/AnimatedNumber.demo.svelte} +6 -10
  4. package/dist/components/{AnimatedNumber.demo.svelte.d.ts → Library/AnimatedNumber/AnimatedNumber.demo.svelte.d.ts} +0 -1
  5. package/dist/components/Library/AnimatedNumber/AnimatedNumber.svelte +29 -0
  6. package/dist/components/Library/AnimatedNumber/AnimatedNumber.svelte.d.ts +9 -0
  7. package/dist/components/Library/AnimatedNumber/index.d.ts +1 -0
  8. package/dist/components/Library/AnimatedNumber/index.js +1 -0
  9. package/dist/components/{AsyncButton.demo.svelte → Library/AsyncButton/AsyncButton.demo.svelte} +0 -1
  10. package/dist/components/Library/AsyncButton/AsyncButton.svelte +178 -0
  11. package/dist/components/{AsyncButton.svelte.d.ts → Library/AsyncButton/AsyncButton.svelte.d.ts} +7 -2
  12. package/dist/components/Library/AsyncButton/index.d.ts +1 -0
  13. package/dist/components/Library/AsyncButton/index.js +1 -0
  14. package/dist/components/Library/Button/Button.demo.svelte +17 -0
  15. package/dist/components/Library/Button/Button.demo.svelte.d.ts +23 -0
  16. package/dist/components/Library/Button/Button.svelte +134 -0
  17. package/dist/components/Library/Button/Button.svelte.d.ts +17 -0
  18. package/dist/components/Library/Button/index.d.ts +1 -0
  19. package/dist/components/Library/Button/index.js +1 -0
  20. package/dist/components/Library/Calendar/Calendar.demo.svelte +30 -0
  21. package/dist/components/Library/Calendar/Calendar.demo.svelte.d.ts +10 -0
  22. package/dist/components/Library/Calendar/Calendar.svelte +310 -0
  23. package/dist/components/Library/Calendar/Calendar.svelte.d.ts +10 -0
  24. package/dist/components/Library/Calendar/index.d.ts +1 -0
  25. package/dist/components/Library/Calendar/index.js +1 -0
  26. package/dist/components/Library/Checkbox/Checkbox.demo.svelte +20 -0
  27. package/dist/components/Library/Checkbox/Checkbox.demo.svelte.d.ts +8 -0
  28. package/dist/components/Library/Checkbox/Checkbox.svelte +134 -0
  29. package/dist/components/Library/Checkbox/Checkbox.svelte.d.ts +11 -0
  30. package/dist/components/Library/Checkbox/index.d.ts +1 -0
  31. package/dist/components/Library/Checkbox/index.js +1 -0
  32. package/dist/components/{ChipInput.demo.svelte → Library/ChipInput/ChipInput.demo.svelte} +1 -2
  33. package/dist/components/{ChipInput.demo.svelte.d.ts → Library/ChipInput/ChipInput.demo.svelte.d.ts} +0 -1
  34. package/dist/components/{ChipInput.svelte → Library/ChipInput/ChipInput.svelte} +77 -3
  35. package/dist/components/{ChipInput.svelte.d.ts → Library/ChipInput/ChipInput.svelte.d.ts} +2 -1
  36. package/dist/components/Library/ChipInput/index.d.ts +1 -0
  37. package/dist/components/Library/ChipInput/index.js +1 -0
  38. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +54 -0
  39. package/dist/components/Library/Dropdown/Dropdown.demo.svelte.d.ts +8 -0
  40. package/dist/components/Library/Dropdown/Dropdown.svelte +346 -0
  41. package/dist/components/Library/Dropdown/Dropdown.svelte.d.ts +40 -0
  42. package/dist/components/Library/Dropdown/index.d.ts +2 -0
  43. package/dist/components/Library/Dropdown/index.js +1 -0
  44. package/dist/components/Library/Dropdown/types.d.ts +27 -0
  45. package/dist/components/Library/Dropdown/types.js +1 -0
  46. package/dist/components/{Popover/Popover.svelte → Library/Floating/Floating.svelte} +155 -101
  47. package/dist/components/Library/Floating/Floating.svelte.d.ts +30 -0
  48. package/dist/components/Library/Floating/registry.svelte.d.ts +6 -0
  49. package/dist/components/{Popover → Library/Floating}/registry.svelte.js +2 -23
  50. package/dist/components/{GlowEffect.svelte → Library/GlowEffect/GlowEffect.svelte} +15 -6
  51. package/dist/components/{GlowEffect.svelte.d.ts → Library/GlowEffect/GlowEffect.svelte.d.ts} +3 -2
  52. package/dist/components/Library/GlowEffect/index.d.ts +1 -0
  53. package/dist/components/Library/GlowEffect/index.js +1 -0
  54. package/dist/components/Library/NavigationStack/NavigationStack.svelte +242 -0
  55. package/dist/components/Library/NavigationStack/NavigationStack.svelte.d.ts +15 -0
  56. package/dist/components/Library/NavigationStack/SidebarToggle.svelte +52 -0
  57. package/dist/components/Library/NavigationStack/SidebarToggle.svelte.d.ts +10 -0
  58. package/dist/components/Library/NavigationStack/Toolbar.svelte +59 -0
  59. package/dist/components/Library/NavigationStack/Toolbar.svelte.d.ts +11 -0
  60. package/dist/components/{Pagination.demo.svelte → Library/Pagination/Pagination.demo.svelte} +0 -1
  61. package/dist/components/{Pagination.demo.svelte.d.ts → Library/Pagination/Pagination.demo.svelte.d.ts} +0 -1
  62. package/dist/components/Library/Pagination/Pagination.svelte +227 -0
  63. package/dist/components/{Pagination.svelte.d.ts → Library/Pagination/Pagination.svelte.d.ts} +3 -3
  64. package/dist/components/Library/Pagination/index.d.ts +1 -0
  65. package/dist/components/Library/Pagination/index.js +1 -0
  66. package/dist/components/Library/Popover/Popover.demo.svelte +21 -0
  67. package/dist/components/Library/Popover/Popover.svelte +92 -0
  68. package/dist/components/Library/Popover/Popover.svelte.d.ts +14 -0
  69. package/dist/components/{Popover → Library/Popover}/PopoverDebugOverlay.svelte +1 -1
  70. package/dist/components/Library/Popover/index.d.ts +1 -0
  71. package/dist/components/Library/Popover/index.js +1 -0
  72. package/dist/components/Library/ScrollView/ScrollView.svelte +89 -0
  73. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +12 -0
  74. package/dist/components/Library/ScrollView/index.d.ts +1 -0
  75. package/dist/components/Library/ScrollView/index.js +1 -0
  76. package/dist/components/{SearchInput.demo.svelte → Library/SearchInput/SearchInput.demo.svelte} +2 -3
  77. package/dist/components/{SearchInput.demo.svelte.d.ts → Library/SearchInput/SearchInput.demo.svelte.d.ts} +0 -1
  78. package/dist/components/Library/SearchInput/SearchInput.svelte +88 -0
  79. package/dist/components/{SearchInput.svelte.d.ts → Library/SearchInput/SearchInput.svelte.d.ts} +3 -3
  80. package/dist/components/Library/SearchInput/index.d.ts +1 -0
  81. package/dist/components/Library/SearchInput/index.js +1 -0
  82. package/dist/components/{SegmentedPicker.demo.svelte → Library/SegmentedPicker/SegmentedPicker.demo.svelte} +2 -3
  83. package/dist/components/{SegmentedPicker.demo.svelte.d.ts → Library/SegmentedPicker/SegmentedPicker.demo.svelte.d.ts} +0 -1
  84. package/dist/components/Library/SegmentedPicker/SegmentedPicker.svelte +106 -0
  85. package/dist/components/{SegmentedPicker.svelte.d.ts → Library/SegmentedPicker/SegmentedPicker.svelte.d.ts} +2 -2
  86. package/dist/components/Library/SegmentedPicker/index.d.ts +1 -0
  87. package/dist/components/Library/SegmentedPicker/index.js +1 -0
  88. package/dist/components/{Sheet → Library/Sheet}/Sheet.demo.svelte +4 -17
  89. package/dist/components/Library/Sheet/Sheet.demo.svelte.d.ts +23 -0
  90. package/dist/components/Library/Sheet/Sheet.svelte +113 -0
  91. package/dist/components/{Sheet → Library/Sheet}/Sheet.svelte.d.ts +4 -2
  92. package/dist/components/{Slider.demo.svelte → Library/Slider/Slider.demo.svelte} +2 -3
  93. package/dist/components/{Slider.demo.svelte.d.ts → Library/Slider/Slider.demo.svelte.d.ts} +0 -1
  94. package/dist/components/Library/Slider/Slider.svelte +122 -0
  95. package/dist/components/{Slider.svelte.d.ts → Library/Slider/Slider.svelte.d.ts} +2 -3
  96. package/dist/components/Library/Slider/index.d.ts +1 -0
  97. package/dist/components/Library/Slider/index.js +1 -0
  98. package/dist/components/{Spinner.demo.svelte → Library/Spinner/Spinner.demo.svelte} +3 -1
  99. package/dist/components/Library/Spinner/Spinner.svelte +32 -0
  100. package/dist/components/{Spinner.svelte.d.ts → Library/Spinner/Spinner.svelte.d.ts} +3 -2
  101. package/dist/components/Library/Spinner/index.d.ts +1 -0
  102. package/dist/components/Library/Spinner/index.js +1 -0
  103. package/dist/components/Library/Switch/Switch.demo.svelte +20 -0
  104. package/dist/components/Library/Switch/Switch.demo.svelte.d.ts +8 -0
  105. package/dist/components/Library/Switch/Switch.svelte +168 -0
  106. package/dist/components/Library/Switch/Switch.svelte.d.ts +11 -0
  107. package/dist/components/Library/Switch/index.d.ts +1 -0
  108. package/dist/components/Library/Switch/index.js +1 -0
  109. package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte +14 -0
  110. package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte.d.ts +23 -0
  111. package/dist/components/Library/TextShimmer/TextShimmer.svelte +88 -0
  112. package/dist/components/Library/TextShimmer/TextShimmer.svelte.d.ts +11 -0
  113. package/dist/components/Library/TextShimmer/index.d.ts +1 -0
  114. package/dist/components/Library/TextShimmer/index.js +1 -0
  115. package/dist/components/Library/TimePicker/TimePicker.demo.svelte +18 -0
  116. package/dist/components/Library/TimePicker/TimePicker.demo.svelte.d.ts +10 -0
  117. package/dist/components/Library/TimePicker/TimePicker.svelte +143 -0
  118. package/dist/components/Library/TimePicker/TimePicker.svelte.d.ts +13 -0
  119. package/dist/components/Library/TimePicker/index.d.ts +2 -0
  120. package/dist/components/Library/TimePicker/index.js +1 -0
  121. package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte +19 -0
  122. package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte.d.ts +9 -0
  123. package/dist/components/Library/TokenSearchInput/TokenSearchInput.svelte +230 -0
  124. package/dist/components/Library/TokenSearchInput/TokenSearchInput.svelte.d.ts +14 -0
  125. package/dist/components/Library/TokenSearchInput/index.d.ts +1 -0
  126. package/dist/components/Library/TokenSearchInput/index.js +1 -0
  127. package/dist/components/Library/Tooltip/Tooltip.demo.svelte +14 -0
  128. package/dist/components/{Tooltip.demo.svelte.d.ts → Library/Tooltip/Tooltip.demo.svelte.d.ts} +0 -1
  129. package/dist/components/Library/Tooltip/index.d.ts +2 -0
  130. package/dist/components/Library/Tooltip/index.js +1 -0
  131. package/dist/components/Library/WheelPicker/WheelColumn.svelte +302 -0
  132. package/dist/components/Library/WheelPicker/WheelColumn.svelte.d.ts +29 -0
  133. package/dist/components/Library/WheelPicker/WheelPicker.svelte +114 -0
  134. package/dist/components/Library/WheelPicker/WheelPicker.svelte.d.ts +9 -0
  135. package/dist/components/Library/WheelPicker/index.d.ts +2 -0
  136. package/dist/components/Library/WheelPicker/index.js +1 -0
  137. package/dist/components/Library/WheelPicker/types.d.ts +10 -0
  138. package/dist/components/Library/WheelPicker/types.js +1 -0
  139. package/dist/components/Local/ComponentGrid.svelte +7 -6
  140. package/dist/components/Local/ComponentGrid.svelte.d.ts +1 -1
  141. package/dist/components/Local/HeroCard.svelte +18 -8
  142. package/dist/components/Local/HeroCard.svelte.d.ts +1 -1
  143. package/dist/components/Local/StyleControls.svelte +119 -0
  144. package/dist/components/Local/StyleControls.svelte.d.ts +15 -0
  145. package/dist/index.d.ts +24 -14
  146. package/dist/index.js +23 -14
  147. package/dist/style/index.css +61 -280
  148. package/dist/style/surface.d.ts +17 -0
  149. package/dist/style/surface.js +54 -0
  150. package/dist/style.css +102 -523
  151. package/dist/utils/positioning.d.ts +3 -2
  152. package/dist/utils/positioning.js +9 -5
  153. package/package.json +2 -1
  154. package/dist/components/AnimatedNumber.svelte +0 -18
  155. package/dist/components/AnimatedNumber.svelte.d.ts +0 -8
  156. package/dist/components/AsyncButton.svelte +0 -93
  157. package/dist/components/NavigationStack/NavigationStack.svelte +0 -76
  158. package/dist/components/NavigationStack/NavigationStack.svelte.d.ts +0 -10
  159. package/dist/components/NavigationStack/SidebarToggle.svelte +0 -36
  160. package/dist/components/NavigationStack/SidebarToggle.svelte.d.ts +0 -9
  161. package/dist/components/NavigationStack/Toolbar.svelte +0 -25
  162. package/dist/components/NavigationStack/Toolbar.svelte.d.ts +0 -9
  163. package/dist/components/Pagination.svelte +0 -144
  164. package/dist/components/Popover/Popover.demo.svelte +0 -35
  165. package/dist/components/Popover/Popover.svelte.d.ts +0 -13
  166. package/dist/components/Popover/index.d.ts +0 -2
  167. package/dist/components/Popover/index.js +0 -2
  168. package/dist/components/Popover/registry.svelte.d.ts +0 -18
  169. package/dist/components/SearchInput.svelte +0 -39
  170. package/dist/components/SegmentedPicker.svelte +0 -51
  171. package/dist/components/Sheet/Sheet.demo.svelte.d.ts +0 -8
  172. package/dist/components/Sheet/Sheet.svelte +0 -60
  173. package/dist/components/Slider.svelte +0 -47
  174. package/dist/components/Spinner.svelte +0 -7
  175. package/dist/components/TextShimmer.svelte +0 -60
  176. package/dist/components/TextShimmer.svelte.d.ts +0 -10
  177. package/dist/components/Tooltip.demo.svelte +0 -16
  178. package/dist/components/Tooltip.svelte +0 -79
  179. package/dist/components/Tooltip.svelte.d.ts +0 -12
  180. /package/dist/components/{AsyncButton.demo.svelte.d.ts → Library/AsyncButton/AsyncButton.demo.svelte.d.ts} +0 -0
  181. /package/dist/components/{NavigationStack → Library/NavigationStack}/index.d.ts +0 -0
  182. /package/dist/components/{NavigationStack → Library/NavigationStack}/index.js +0 -0
  183. /package/dist/components/{Popover → Library/Popover}/Popover.demo.svelte.d.ts +0 -0
  184. /package/dist/components/{Popover → Library/Popover}/PopoverDebugOverlay.svelte.d.ts +0 -0
  185. /package/dist/components/{Sheet → Library/Sheet}/index.d.ts +0 -0
  186. /package/dist/components/{Sheet → Library/Sheet}/index.js +0 -0
  187. /package/dist/components/{Spinner.demo.svelte.d.ts → Library/Spinner/Spinner.demo.svelte.d.ts} +0 -0
@@ -0,0 +1,302 @@
1
+ <script lang="ts" generics="T extends string | number">
2
+ import { tick } from 'svelte';
3
+ import type { WheelOption } from './types';
4
+
5
+ type Props = {
6
+ options: WheelOption<T>[];
7
+ value?: T;
8
+ onChange?: (value: T) => void;
9
+ };
10
+
11
+ let { options, value = $bindable<T>(), onChange }: Props = $props();
12
+
13
+ let viewport = $state<HTMLDivElement | null>(null);
14
+ let optionRefs = $state<(HTMLButtonElement | null)[]>([]);
15
+ let scrollTimeout = $state<ReturnType<typeof setTimeout> | null>(null);
16
+ let scrollingLockTimeout = $state<ReturnType<typeof setTimeout> | null>(null);
17
+ let isUserScrolling = $state(false);
18
+ let scrollAnimationFrame = $state<number | null>(null);
19
+ let visualUpdateFrame = $state<number | null>(null);
20
+
21
+ const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
22
+
23
+ const animateScrollTo = (
24
+ nextViewport: HTMLDivElement,
25
+ targetTop: number,
26
+ duration = 220
27
+ ) => {
28
+ if (scrollAnimationFrame) cancelAnimationFrame(scrollAnimationFrame);
29
+
30
+ const startTop = nextViewport.scrollTop;
31
+ const delta = Math.max(0, targetTop) - startTop;
32
+ if (Math.abs(delta) < 0.5) {
33
+ nextViewport.scrollTop = Math.max(0, targetTop);
34
+ scrollAnimationFrame = null;
35
+ return;
36
+ }
37
+
38
+ const startTime = performance.now();
39
+
40
+ const step = (now: number) => {
41
+ const progress = Math.min(1, (now - startTime) / duration);
42
+ nextViewport.scrollTop = startTop + delta * easeOutCubic(progress);
43
+ if (progress < 1) {
44
+ scrollAnimationFrame = requestAnimationFrame(step);
45
+ return;
46
+ }
47
+ scrollAnimationFrame = null;
48
+ };
49
+
50
+ scrollAnimationFrame = requestAnimationFrame(step);
51
+ };
52
+
53
+ const scrollSelectedIntoView = async (
54
+ nextViewport: HTMLDivElement | null,
55
+ element: HTMLButtonElement | null
56
+ ) => {
57
+ if (!nextViewport || !element) return;
58
+ await tick();
59
+ const viewportRect = nextViewport.getBoundingClientRect();
60
+ const elementRect = element.getBoundingClientRect();
61
+ const top =
62
+ nextViewport.scrollTop +
63
+ (elementRect.top - viewportRect.top) -
64
+ nextViewport.clientHeight / 2 +
65
+ element.clientHeight / 2;
66
+ animateScrollTo(nextViewport, top);
67
+ };
68
+
69
+ const getCenteredIndex = (
70
+ nextViewport: HTMLDivElement | null,
71
+ elements: Array<HTMLButtonElement | null>
72
+ ) => {
73
+ if (!nextViewport) return -1;
74
+ const viewportRect = nextViewport.getBoundingClientRect();
75
+ const viewportCenter = viewportRect.top + viewportRect.height / 2;
76
+ let bestIndex = -1;
77
+ let bestDistance = Number.POSITIVE_INFINITY;
78
+
79
+ for (const [index, element] of elements.entries()) {
80
+ if (!element) continue;
81
+ const rect = element.getBoundingClientRect();
82
+ const center = rect.top + rect.height / 2;
83
+ const distance = Math.abs(center - viewportCenter);
84
+ if (distance < bestDistance) {
85
+ bestDistance = distance;
86
+ bestIndex = index;
87
+ }
88
+ }
89
+
90
+ return bestIndex;
91
+ };
92
+
93
+ const getCenterDistance = (
94
+ nextViewport: HTMLDivElement | null,
95
+ element: HTMLButtonElement | null
96
+ ) => {
97
+ if (!nextViewport || !element) return Number.POSITIVE_INFINITY;
98
+ const viewportRect = nextViewport.getBoundingClientRect();
99
+ const elementRect = element.getBoundingClientRect();
100
+ const viewportCenter = viewportRect.top + viewportRect.height / 2;
101
+ const elementCenter = elementRect.top + elementRect.height / 2;
102
+ return Math.abs(elementCenter - viewportCenter);
103
+ };
104
+
105
+ const updateVisualDepth = () => {
106
+ if (!viewport) return;
107
+ const viewportRect = viewport.getBoundingClientRect();
108
+ const viewportCenter = viewportRect.top + viewportRect.height / 2;
109
+ const maxDistance = Math.max(viewportRect.height / 2, 1);
110
+
111
+ for (const element of optionRefs) {
112
+ if (!element) continue;
113
+ const rect = element.getBoundingClientRect();
114
+ const center = rect.top + rect.height / 2;
115
+ const ratio = Math.min(1, Math.abs(center - viewportCenter) / maxDistance);
116
+ const emphasis = Math.pow(Math.cos(ratio * (Math.PI / 2)), 2);
117
+ element.style.setProperty('--wheel-column-emphasis', emphasis.toFixed(3));
118
+ }
119
+ };
120
+
121
+ const scheduleVisualDepthUpdate = () => {
122
+ if (visualUpdateFrame) cancelAnimationFrame(visualUpdateFrame);
123
+ visualUpdateFrame = requestAnimationFrame(() => {
124
+ visualUpdateFrame = null;
125
+ updateVisualDepth();
126
+ });
127
+ };
128
+
129
+ const applyValue = (nextValue: T) => {
130
+ if (value === nextValue) return;
131
+ value = nextValue;
132
+ onChange?.(nextValue);
133
+ };
134
+
135
+ const selectOption = (option: WheelOption<T>, index: number) => {
136
+ applyValue(option.value);
137
+ void scrollSelectedIntoView(viewport, optionRefs[index] ?? null);
138
+ scheduleVisualDepthUpdate();
139
+ };
140
+
141
+ const syncToCurrentValue = () => {
142
+ if (isUserScrolling || !viewport) return;
143
+ const index = options.findIndex((option) => option.value === value);
144
+ if (index < 0) return;
145
+ const element = optionRefs[index] ?? null;
146
+ if (!element) return;
147
+ if (getCenterDistance(viewport, element) > 1) {
148
+ void scrollSelectedIntoView(viewport, element);
149
+ }
150
+ scheduleVisualDepthUpdate();
151
+ };
152
+
153
+ const handleScroll = () => {
154
+ scheduleVisualDepthUpdate();
155
+ isUserScrolling = true;
156
+ if (scrollingLockTimeout) clearTimeout(scrollingLockTimeout);
157
+ scrollingLockTimeout = setTimeout(() => {
158
+ isUserScrolling = false;
159
+ }, 180);
160
+
161
+ if (scrollTimeout) clearTimeout(scrollTimeout);
162
+ scrollTimeout = setTimeout(() => {
163
+ const centeredIndex = getCenteredIndex(viewport, optionRefs);
164
+ if (centeredIndex < 0) return;
165
+ const centeredOption = options[centeredIndex];
166
+ const centeredElement = optionRefs[centeredIndex] ?? null;
167
+ if (!centeredOption || !centeredElement) return;
168
+
169
+ const centerDistance = getCenterDistance(viewport, centeredElement);
170
+ if (centerDistance > 1) {
171
+ void scrollSelectedIntoView(viewport, centeredElement);
172
+ }
173
+
174
+ applyValue(centeredOption.value);
175
+ scheduleVisualDepthUpdate();
176
+ }, 140);
177
+ };
178
+
179
+ const viewportSync = (node: HTMLDivElement) => {
180
+ viewport = node;
181
+ void tick().then(() => {
182
+ syncToCurrentValue();
183
+ scheduleVisualDepthUpdate();
184
+ });
185
+
186
+ return {
187
+ update() {
188
+ void tick().then(() => {
189
+ syncToCurrentValue();
190
+ scheduleVisualDepthUpdate();
191
+ });
192
+ },
193
+ destroy() {
194
+ if (scrollTimeout) clearTimeout(scrollTimeout);
195
+ if (scrollingLockTimeout) clearTimeout(scrollingLockTimeout);
196
+ if (scrollAnimationFrame) cancelAnimationFrame(scrollAnimationFrame);
197
+ if (visualUpdateFrame) cancelAnimationFrame(visualUpdateFrame);
198
+ viewport = null;
199
+ }
200
+ };
201
+ };
202
+ </script>
203
+
204
+ <div
205
+ class="wheel-column-viewport"
206
+ bind:this={viewport}
207
+ use:viewportSync={{ value, options }}
208
+ onscroll={handleScroll}
209
+ >
210
+ <div class="wheel-column-options vstack">
211
+ {#each options as option, index (option.value)}
212
+ <button
213
+ bind:this={optionRefs[index]}
214
+ type="button"
215
+ class="wheel-column-option"
216
+ class:wheel-column-option-selected={option.value === value}
217
+ aria-pressed={option.value === value}
218
+ onclick={() => selectOption(option, index)}
219
+ >
220
+ {option.label}
221
+ </button>
222
+ {/each}
223
+ </div>
224
+ </div>
225
+
226
+ <style>
227
+ .wheel-column-viewport {
228
+ height: 100%;
229
+ display: flex;
230
+ flex-direction: column;
231
+ min-height: 0;
232
+ position: relative;
233
+ overflow-y: auto;
234
+ overflow-x: hidden;
235
+ overscroll-behavior-y: contain;
236
+ scrollbar-width: none;
237
+ -ms-overflow-style: none;
238
+ z-index: 1;
239
+ }
240
+
241
+ .wheel-column-viewport::-webkit-scrollbar {
242
+ display: none;
243
+ }
244
+
245
+ .wheel-column-viewport::before,
246
+ .wheel-column-viewport::after {
247
+ content: '';
248
+ display: block;
249
+ flex: 0 0 calc(50% - (var(--wheel-picker-option-height) / 2));
250
+ }
251
+
252
+ .wheel-column-options {
253
+ flex: 0 0 auto;
254
+ gap: 0;
255
+ }
256
+
257
+ .wheel-column-option {
258
+ --wheel-column-emphasis: 0;
259
+ width: 100%;
260
+ height: var(--wheel-picker-option-height);
261
+ border: none;
262
+ border-radius: var(--sveltely-border-radius);
263
+ background: transparent;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ padding:
268
+ 0
269
+ calc(var(--sveltely-padding-x) * 0.67 * var(--wheel-picker-scale));
270
+ font-size: calc(var(--wheel-picker-font-size) * 0.875);
271
+ line-height: 1;
272
+ color: var(--color-zinc-700);
273
+ text-align: center;
274
+ appearance: none;
275
+ position: relative;
276
+ z-index: 1;
277
+ opacity: calc(0.3 + (var(--wheel-column-emphasis) * 0.7));
278
+ transform: scale(calc(0.84 + (var(--wheel-column-emphasis) * 0.16)));
279
+ transform-origin: center;
280
+ transition:
281
+ color 160ms,
282
+ background-color 160ms,
283
+ opacity 160ms,
284
+ transform 160ms;
285
+ }
286
+
287
+ .wheel-column-option:hover {
288
+ background: var(--sveltely-hover-color);
289
+ }
290
+
291
+ .wheel-column-option:focus-visible {
292
+ outline: 2px solid color-mix(in oklab, var(--sveltely-primary-color) 24%, white);
293
+ outline-offset: 2px;
294
+ }
295
+
296
+ .wheel-column-option-selected {
297
+ background: transparent;
298
+ color: var(--sveltely-primary-color);
299
+ opacity: 1;
300
+ transform: scale(1);
301
+ }
302
+ </style>
@@ -0,0 +1,29 @@
1
+ import type { WheelOption } from './types';
2
+ declare function $$render<T extends string | number>(): {
3
+ props: {
4
+ options: WheelOption<T>[];
5
+ value?: T;
6
+ onChange?: (value: T) => void;
7
+ };
8
+ exports: {};
9
+ bindings: "value";
10
+ slots: {};
11
+ events: {};
12
+ };
13
+ declare class __sveltets_Render<T extends string | number> {
14
+ props(): ReturnType<typeof $$render<T>>['props'];
15
+ events(): ReturnType<typeof $$render<T>>['events'];
16
+ slots(): ReturnType<typeof $$render<T>>['slots'];
17
+ bindings(): "value";
18
+ exports(): {};
19
+ }
20
+ interface $$IsomorphicComponent {
21
+ new <T extends string | number>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
22
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
23
+ } & ReturnType<__sveltets_Render<T>['exports']>;
24
+ <T extends string | number>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
25
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
26
+ }
27
+ declare const WheelColumn: $$IsomorphicComponent;
28
+ type WheelColumn<T extends string | number> = InstanceType<typeof WheelColumn<T>>;
29
+ export default WheelColumn;
@@ -0,0 +1,114 @@
1
+ <script lang="ts">
2
+ import WheelColumn from './WheelColumn.svelte';
3
+ import { extractStyleProps, surfaceStyle, type StyleProps } from '../../../style/surface';
4
+ import type { WheelColumn as WheelColumnData } from './types';
5
+
6
+ type Props = {
7
+ columns: WheelColumnData[];
8
+ height?: number | string;
9
+ } & StyleProps & Record<string, unknown>;
10
+
11
+ const toCssLength = (value: number | string | undefined) =>
12
+ value === undefined ? undefined : typeof value === 'number' ? `${value}px` : value;
13
+
14
+ let { columns, height, ...restProps }: Props = $props();
15
+
16
+ const extractedStyleProps = $derived.by(() => extractStyleProps(restProps));
17
+ const styleProps = $derived(extractedStyleProps.styleProps);
18
+ const props = $derived(extractedStyleProps.restProps);
19
+ const rootStyle = $derived.by(() => surfaceStyle(styleProps, 'wheel-picker'));
20
+ const pickerStyle = $derived.by(() => {
21
+ const resolvedHeight = toCssLength(height);
22
+ if (!resolvedHeight) return rootStyle;
23
+ const heightStyle = `--wheel-picker-height: ${resolvedHeight};`;
24
+ return rootStyle ? `${rootStyle} ${heightStyle}` : heightStyle;
25
+ });
26
+
27
+ </script>
28
+
29
+ <div class="wheel-picker vstack" style={pickerStyle} {...props}>
30
+ <div class="wheel-picker-label-row hstack">
31
+ {#each columns as column, index (`label-${index}`)}
32
+ <div
33
+ class="wheel-picker-label-column"
34
+ style={`--wheel-picker-column-flex: ${column.options.length <= 3 ? 0.85 : 1};`}
35
+ >
36
+ {#if column.label}
37
+ <div class="wheel-picker-label">{column.label}</div>
38
+ {/if}
39
+ </div>
40
+ {/each}
41
+ </div>
42
+
43
+ <div class="wheel-picker-wheels hstack">
44
+ <div class="wheel-picker-overlay" aria-hidden="true"></div>
45
+ {#each columns as column, index (`wheel-${index}`)}
46
+ <div
47
+ class="wheel-picker-column"
48
+ style={`--wheel-picker-column-flex: ${column.options.length <= 3 ? 0.85 : 1};`}
49
+ >
50
+ <WheelColumn
51
+ options={column.options}
52
+ value={column.value}
53
+ onChange={column.onChange}
54
+ />
55
+ </div>
56
+ {/each}
57
+ </div>
58
+ </div>
59
+
60
+ <style>
61
+ .wheel-picker {
62
+ --wheel-picker-font-size: var(--sveltely-font-size);
63
+ --wheel-picker-scale: calc(var(--wheel-picker-font-size) / 1rem);
64
+ --wheel-picker-option-height: calc(
65
+ (calc(var(--wheel-picker-font-size) * 0.875) * 1.2) +
66
+ (calc(var(--sveltely-padding-y) * 0.67 * var(--wheel-picker-scale)) * 2) + 2px
67
+ );
68
+ height: var(--wheel-picker-height, calc(var(--wheel-picker-option-height) * 10));
69
+ gap: calc(var(--sveltely-gap) * 0.5);
70
+ position: relative;
71
+ }
72
+
73
+ .wheel-picker-label-row,
74
+ .wheel-picker-wheels {
75
+ gap: var(--sveltely-gap);
76
+ }
77
+
78
+ .wheel-picker-label-row {
79
+ flex: 0 0 auto;
80
+ }
81
+
82
+ .wheel-picker-label-column,
83
+ .wheel-picker-column {
84
+ flex: var(--wheel-picker-column-flex, 1) 1 0;
85
+ min-width: calc(var(--wheel-picker-font-size) * 3.75);
86
+ }
87
+
88
+ .wheel-picker-wheels {
89
+ flex: 1 1 auto;
90
+ min-height: 0;
91
+ position: relative;
92
+ align-items: stretch;
93
+ }
94
+
95
+ .wheel-picker-overlay {
96
+ position: absolute;
97
+ inset-inline: 0;
98
+ top: 50%;
99
+ height: var(--wheel-picker-option-height);
100
+ transform: translateY(-50%);
101
+ border-radius: var(--sveltely-border-radius);
102
+ background: color-mix(in oklab, var(--color-zinc-100) 85%, white);
103
+ pointer-events: none;
104
+ z-index: 0;
105
+ }
106
+
107
+ .wheel-picker-label {
108
+ padding-inline: calc(var(--sveltely-padding-x) * 0.33);
109
+ font-size: calc(var(--wheel-picker-font-size) * 0.75);
110
+ line-height: 1;
111
+ font-weight: 500;
112
+ color: var(--color-zinc-500);
113
+ }
114
+ </style>
@@ -0,0 +1,9 @@
1
+ import { type StyleProps } from '../../../style/surface';
2
+ import type { WheelColumn as WheelColumnData } from './types';
3
+ type Props = {
4
+ columns: WheelColumnData[];
5
+ height?: number | string;
6
+ } & StyleProps & Record<string, unknown>;
7
+ declare const WheelPicker: import("svelte").Component<Props, {}, "">;
8
+ type WheelPicker = ReturnType<typeof WheelPicker>;
9
+ export default WheelPicker;
@@ -0,0 +1,2 @@
1
+ export { default } from './WheelPicker.svelte';
2
+ export type { WheelColumn, WheelOption } from './types';
@@ -0,0 +1 @@
1
+ export { default } from './WheelPicker.svelte';
@@ -0,0 +1,10 @@
1
+ export type WheelOption<TValue extends string | number = string> = {
2
+ value: TValue;
3
+ label: string;
4
+ };
5
+ export type WheelColumn<TValue extends string | number = string> = {
6
+ label?: string;
7
+ value: TValue;
8
+ options: WheelOption<TValue>[];
9
+ onChange?: (value: TValue) => void;
10
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,8 +6,8 @@
6
6
  component: Component;
7
7
  name: string;
8
8
  description: string;
9
- isProminent: boolean;
10
9
  columnSpan?: 1 | 2;
10
+ rowSpan?: 1 | 2;
11
11
  };
12
12
 
13
13
  type Props = {
@@ -18,15 +18,16 @@
18
18
  </script>
19
19
 
20
20
  <div
21
- class="component-grid grid gap-4 overflow-auto p-6 md:grid-flow-dense md:grid-cols-2 xl:grid-cols-3"
21
+ class="component-grid grid gap-4 overflow-auto md:grid-flow-dense md:grid-cols-2 xl:grid-cols-3"
22
+ style="padding: calc(var(--sveltely-padding-y) * 2) calc(var(--sveltely-padding-x) * 2);"
22
23
  >
23
24
  {#each demos as entry}
24
25
  {@const DemoComponent = entry.component}
25
26
  <HeroCard
26
27
  title={entry.name}
27
28
  description={entry.description}
28
- isProminent={entry.isProminent}
29
29
  columnSpan={entry.columnSpan ?? 1}
30
+ rowSpan={entry.rowSpan ?? 1}
30
31
  >
31
32
  <DemoComponent />
32
33
  </HeroCard>
@@ -35,10 +36,10 @@
35
36
 
36
37
  <style>
37
38
  .component-grid :global(.hero-card) {
39
+ --sveltely-border-width: 1px;
38
40
  min-height: 14rem;
39
- border: 1px solid rgb(228 228 231);
40
- border-radius: 1rem;
41
- box-shadow: 0 1px 2px rgb(0 0 0 / 0.05);
41
+ border: 1px solid var(--sveltely-border-color);
42
+ border-radius: 0.75rem;
42
43
  align-items: stretch;
43
44
  }
44
45
 
@@ -3,8 +3,8 @@ type DemoEntry = {
3
3
  component: Component;
4
4
  name: string;
5
5
  description: string;
6
- isProminent: boolean;
7
6
  columnSpan?: 1 | 2;
7
+ rowSpan?: 1 | 2;
8
8
  };
9
9
  type Props = {
10
10
  demos: DemoEntry[];
@@ -5,14 +5,20 @@
5
5
  title?: string;
6
6
  description?: string;
7
7
  children?: Snippet;
8
- isProminent?: boolean;
9
8
  columnSpan?: 1 | 2;
9
+ rowSpan?: 1 | 2;
10
10
  };
11
11
 
12
- let { title, description = '', children, isProminent = false, columnSpan = 1 }: Props = $props();
12
+ let {
13
+ title,
14
+ description = '',
15
+ children,
16
+ columnSpan = 1,
17
+ rowSpan = 1
18
+ }: Props = $props();
13
19
  </script>
14
20
 
15
- <div class="hero-card vstack gap-2" data-column-span={columnSpan}>
21
+ <div class="hero-card vstack shrink-0 gap-2" data-column-span={columnSpan} data-row-span={rowSpan}>
16
22
  {#if title}
17
23
  <h1 class="text-3xl font-semibold tracking-tight text-zinc-950">{title}</h1>
18
24
  {#if description}
@@ -21,10 +27,6 @@
21
27
  {/if}
22
28
  <div
23
29
  class="hero-card-content center flex"
24
- class:overflow-hidden={isProminent}
25
- class:rounded-xl={isProminent}
26
- class:bg-zinc-50={isProminent}
27
- class:p-4={isProminent}
28
30
  >
29
31
  {#if children}
30
32
  {@render children()}
@@ -34,8 +36,12 @@
34
36
 
35
37
  <style>
36
38
  .hero-card {
39
+ --hero-card-inset-x: calc(var(--sveltely-padding-x) * 2);
40
+ --hero-card-inset-y: calc(var(--sveltely-padding-y) * 2);
41
+ --hero-card-inset: max(var(--hero-card-inset-x), var(--hero-card-inset-y));
42
+ --sveltely-nested-inset: var(--hero-card-inset);
37
43
  background: white;
38
- padding: 1.5rem;
44
+ padding: 1.5rem 1.5rem;
39
45
  }
40
46
 
41
47
  .hero-card-content {
@@ -47,5 +53,9 @@
47
53
  .hero-card[data-column-span='2'] {
48
54
  grid-column: span 2;
49
55
  }
56
+
57
+ .hero-card[data-row-span='2'] {
58
+ grid-row: span 2;
59
+ }
50
60
  }
51
61
  </style>
@@ -3,8 +3,8 @@ type Props = {
3
3
  title?: string;
4
4
  description?: string;
5
5
  children?: Snippet;
6
- isProminent?: boolean;
7
6
  columnSpan?: 1 | 2;
7
+ rowSpan?: 1 | 2;
8
8
  };
9
9
  declare const HeroCard: import("svelte").Component<Props, {}, "">;
10
10
  type HeroCard = ReturnType<typeof HeroCard>;