@x33025/sveltely 0.1.18 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/LoaderOverlay.svelte +33 -8
- package/dist/actions/LoaderOverlay.svelte.d.ts +3 -0
- package/dist/actions/loader.d.ts +3 -0
- package/dist/actions/loader.js +20 -7
- package/dist/components/Library/AnimatedNumber/AnimatedNumber.demo.svelte +3 -9
- package/dist/components/Library/ArticleEditor/ArticleEditor.svelte +1 -1
- package/dist/components/Library/ArticleEditor/ArticleEditorHeader.svelte +20 -30
- package/dist/components/Library/ArticleEditor/Blocks/Code.svelte +0 -1
- package/dist/components/Library/ArticleEditor/Blocks/FAQ.svelte +1 -1
- package/dist/components/Library/ArticleEditor/Blocks/Heading.svelte +7 -7
- package/dist/components/Library/ArticleEditor/Blocks/Image.svelte +20 -36
- package/dist/components/Library/ArticleEditor/Blocks/Image.svelte.d.ts +1 -0
- package/dist/components/Library/ArticleEditor/Blocks/List.svelte +2 -2
- package/dist/components/Library/ArticleEditor/Blocks/Paragraph.svelte +1 -1
- package/dist/components/Library/ArticleEditor/Blocks/index.d.ts +0 -1
- package/dist/components/Library/ArticleEditor/Blocks/index.js +0 -1
- package/dist/components/Library/AsyncButton/AsyncButton.demo.svelte +2 -6
- package/dist/components/Library/AsyncButton/AsyncButton.svelte +9 -5
- package/dist/components/Library/AsyncButton/AsyncButton.svelte.d.ts +2 -1
- package/dist/components/Library/Button/Button.demo.svelte +2 -17
- package/dist/components/Library/Button/Button.demo.svelte.d.ts +0 -1
- package/dist/components/Library/Button/Button.svelte +15 -16
- package/dist/components/Library/Button/Button.svelte.d.ts +2 -1
- package/dist/components/Library/Calendar/Calendar.svelte +17 -27
- package/dist/components/Library/Checkbox/Checkbox.demo.svelte +7 -4
- package/dist/components/Library/Checkbox/Checkbox.svelte +24 -61
- package/dist/components/Library/Checkbox/Checkbox.svelte.d.ts +2 -4
- package/dist/components/Library/ChipInput/ChipInput.demo.svelte +2 -2
- package/dist/components/Library/ChipInput/ChipInput.svelte +7 -11
- package/dist/components/Library/ChipInput/ChipInput.svelte.d.ts +3 -2
- package/dist/components/Library/Dropdown/Action.svelte +1 -1
- package/dist/components/Library/Dropdown/Dropdown.demo.svelte +10 -10
- package/dist/components/Library/Dropdown/Dropdown.svelte +2 -6
- package/dist/components/Library/Dropdown/Item.svelte +2 -2
- package/dist/components/Library/Dropdown/Section.svelte +1 -1
- package/dist/components/Library/Dropdown/Trigger.svelte +3 -7
- package/dist/components/Library/Image/Image.demo.svelte +3 -3
- package/dist/components/Library/Image/Image.svelte +57 -12
- package/dist/components/Library/Image/Image.svelte.d.ts +1 -2
- package/dist/components/Library/Image/ImagePlaceholder.demo.svelte +12 -0
- package/dist/components/Library/Image/ImagePlaceholder.demo.svelte.d.ts +23 -0
- package/dist/components/Library/Image/ImagePlaceholder.svelte +28 -4
- package/dist/components/Library/Image/ImagePlaceholder.svelte.d.ts +1 -1
- package/dist/components/Library/Image/index.d.ts +1 -0
- package/dist/components/Library/Image/index.js +1 -0
- package/dist/components/Library/ImageMask/BrushPreview.svelte +6 -6
- package/dist/components/Library/ImageMask/ImageMask.demo.svelte +10 -8
- package/dist/components/Library/ImageMask/ImageMask.svelte +14 -6
- package/dist/components/Library/ImageMask/ImageMask.svelte.d.ts +1 -2
- package/dist/components/Library/ImageMask/MaskLayer.svelte +12 -6
- package/dist/components/Library/Label/Label.demo.svelte +16 -3
- package/dist/components/Library/Label/Label.svelte +15 -3
- package/dist/components/Library/Label/Label.svelte.d.ts +1 -0
- package/dist/components/Library/Link/Link.svelte +10 -22
- package/dist/components/Library/Link/Link.svelte.d.ts +2 -3
- package/dist/components/Library/Loader/Loader.demo.svelte +9 -3
- package/dist/components/Library/NavigationStack/Link.svelte +8 -12
- package/dist/components/Library/NavigationStack/Link.svelte.d.ts +1 -3
- package/dist/components/Library/NavigationStack/SidebarToggle.svelte +8 -2
- package/dist/components/Library/NumberField/NumberField.svelte +21 -17
- package/dist/components/Library/NumberField/NumberField.svelte.d.ts +4 -2
- package/dist/components/Library/Pagination/Pagination.svelte +3 -3
- package/dist/components/Library/Popover/Popover.svelte +2 -7
- package/dist/components/Library/ScrollView/ScrollView.demo.svelte +50 -0
- package/dist/components/Library/ScrollView/ScrollView.demo.svelte.d.ts +10 -0
- package/dist/components/Library/ScrollView/ScrollView.svelte +414 -67
- package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +17 -1
- package/dist/components/Library/ScrollView/index.d.ts +1 -1
- package/dist/components/Library/SearchField/SearchField.demo.svelte +2 -2
- package/dist/components/Library/SearchField/SearchField.svelte +9 -4
- package/dist/components/Library/SearchField/SearchField.svelte.d.ts +2 -1
- package/dist/components/Library/SegmentedPicker/SegmentedPicker.demo.svelte +2 -2
- package/dist/components/Library/SegmentedPicker/SegmentedPicker.svelte +7 -7
- package/dist/components/Library/Sheet/Sheet.demo.svelte +1 -1
- package/dist/components/Library/Sheet/Sheet.svelte +2 -7
- package/dist/components/Library/Slider/Slider.demo.svelte +1 -1
- package/dist/components/Library/Slider/Slider.svelte +11 -7
- package/dist/components/Library/Slider/Slider.svelte.d.ts +2 -1
- package/dist/components/Library/Spinner/Spinner.demo.svelte +1 -1
- package/dist/components/Library/Switch/Switch.demo.svelte +7 -4
- package/dist/components/Library/Switch/Switch.svelte +28 -68
- package/dist/components/Library/Switch/Switch.svelte.d.ts +2 -4
- package/dist/components/Library/Table/Column.svelte +81 -0
- package/dist/components/Library/Table/Column.svelte.d.ts +39 -0
- package/dist/components/Library/Table/Table.demo.svelte +148 -0
- package/dist/components/Library/Table/Table.demo.svelte.d.ts +10 -0
- package/dist/components/Library/Table/Table.svelte +624 -0
- package/dist/components/Library/Table/Table.svelte.d.ts +42 -0
- package/dist/components/Library/Table/context.d.ts +5 -0
- package/dist/components/Library/Table/context.js +2 -0
- package/dist/components/Library/Table/index.js +5 -0
- package/dist/components/Library/Table/types.d.ts +37 -0
- package/dist/components/Library/Table/types.js +1 -0
- package/dist/components/Library/Text/Text.demo.svelte +21 -0
- package/dist/components/Library/Text/Text.demo.svelte.d.ts +24 -0
- package/dist/components/Library/Text/Text.svelte +41 -0
- package/dist/components/Library/Text/Text.svelte.d.ts +9 -0
- package/dist/components/Library/Text/index.d.ts +1 -0
- package/dist/components/Library/Text/index.js +1 -0
- package/dist/components/Library/TextEditor/TextEditor.svelte +15 -9
- package/dist/components/Library/TextEditor/TextEditor.svelte.d.ts +2 -4
- package/dist/components/Library/TextField/TextField.demo.svelte +1 -1
- package/dist/components/Library/TextField/TextField.svelte +21 -18
- package/dist/components/Library/TextField/TextField.svelte.d.ts +4 -2
- package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte +1 -1
- package/dist/components/Library/TimePicker/TimePicker.demo.svelte +10 -2
- package/dist/components/Library/TimePicker/TimePicker.svelte +10 -5
- package/dist/components/Library/TokenSearchField/TokenSearchField.demo.svelte +4 -2
- package/dist/components/Library/TokenSearchField/TokenSearchField.svelte +11 -11
- package/dist/components/Library/TokenSearchField/TokenSearchField.svelte.d.ts +2 -1
- package/dist/components/Library/WheelPicker/WheelColumn.svelte +183 -126
- package/dist/components/Library/WheelPicker/WheelPicker.svelte +4 -4
- package/dist/components/Library/WheelPicker/WheelPicker.svelte.d.ts +2 -2
- package/dist/components/Library/WheelPicker/index.d.ts +1 -1
- package/dist/components/Library/WheelPicker/types.d.ts +6 -0
- package/dist/components/Local/ColorStyleControls.svelte +201 -0
- package/dist/components/Local/ColorStyleControls.svelte.d.ts +13 -0
- package/dist/components/Local/HeroCard.svelte +3 -3
- package/dist/components/Local/LayoutStyleControls.svelte +67 -0
- package/dist/components/Local/LayoutStyleControls.svelte.d.ts +11 -0
- package/dist/components/Local/StyleControls.svelte +48 -124
- package/dist/components/Local/StyleControls.svelte.d.ts +7 -5
- package/dist/index.d.ts +9 -2
- package/dist/index.js +5 -1
- package/dist/style/index.css +7 -12
- package/dist/style/label.d.ts +2 -1
- package/dist/style/label.js +2 -1
- package/dist/style/surface.js +4 -0
- package/dist/style/text-editor.d.ts +2 -13
- package/dist/style/text-editor.js +1 -12
- package/dist/style/text.d.ts +26 -0
- package/dist/style/text.js +69 -0
- package/dist/style/tooltip.d.ts +4 -0
- package/dist/style/tooltip.js +1 -0
- package/dist/style.css +44 -111
- package/package.json +1 -1
- package/dist/components/Library/ArticleEditor/Blocks/ImagePreview.svelte +0 -71
- package/dist/components/Library/ArticleEditor/Blocks/ImagePreview.svelte.d.ts +0 -8
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends string | number">
|
|
2
|
-
import { tick } from 'svelte';
|
|
2
|
+
import { tick, untrack } from 'svelte';
|
|
3
|
+
import ScrollView, {
|
|
4
|
+
type ScrollGeometry,
|
|
5
|
+
type ScrollViewHandle
|
|
6
|
+
} from '../ScrollView';
|
|
3
7
|
import type { WheelOption } from './types';
|
|
4
8
|
|
|
5
9
|
type Props = {
|
|
@@ -10,17 +14,49 @@
|
|
|
10
14
|
|
|
11
15
|
let { options, value = $bindable<T>(), onChange }: Props = $props();
|
|
12
16
|
|
|
13
|
-
let viewport = $state<
|
|
17
|
+
let viewport = $state<ScrollViewHandle | null>(null);
|
|
14
18
|
let optionRefs = $state<(HTMLButtonElement | null)[]>([]);
|
|
15
19
|
let scrollTimeout = $state<ReturnType<typeof setTimeout> | null>(null);
|
|
16
|
-
let scrollingLockTimeout = $state<ReturnType<typeof setTimeout> | null>(null);
|
|
17
20
|
let isUserScrolling = $state(false);
|
|
18
21
|
let scrollAnimationFrame = $state<number | null>(null);
|
|
19
|
-
let
|
|
22
|
+
let spacerSize = $state(0);
|
|
23
|
+
let optionHeight = $state(0);
|
|
24
|
+
let scrollOffsetY = $state(0);
|
|
25
|
+
let optionPointer: { id: number; x: number; y: number; moved: boolean } | null = null;
|
|
20
26
|
|
|
21
27
|
const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
|
|
22
28
|
|
|
23
|
-
const
|
|
29
|
+
const resolveOptionHeight = (nextViewport = viewport) => {
|
|
30
|
+
const measuredOptionHeight = optionRefs.find((element) => element !== null)?.clientHeight;
|
|
31
|
+
const cssOptionHeight =
|
|
32
|
+
typeof document === 'undefined'
|
|
33
|
+
? 0
|
|
34
|
+
: parseFloat(
|
|
35
|
+
getComputedStyle(nextViewport?.element ?? document.documentElement).getPropertyValue(
|
|
36
|
+
'--wheel-picker-option-height'
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return measuredOptionHeight && measuredOptionHeight > 0
|
|
41
|
+
? measuredOptionHeight
|
|
42
|
+
: Number.isFinite(cssOptionHeight)
|
|
43
|
+
? cssOptionHeight
|
|
44
|
+
: 0;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const measureSpacerSize = (nextViewport = viewport) => {
|
|
48
|
+
if (!nextViewport) return;
|
|
49
|
+
const nextOptionHeight = resolveOptionHeight(nextViewport);
|
|
50
|
+
const nextSpacerSize = Math.max(0, (nextViewport.clientHeight - nextOptionHeight) / 2);
|
|
51
|
+
if (Math.abs(optionHeight - nextOptionHeight) > 0.5) {
|
|
52
|
+
optionHeight = nextOptionHeight;
|
|
53
|
+
}
|
|
54
|
+
if (Math.abs(spacerSize - nextSpacerSize) > 0.5) {
|
|
55
|
+
spacerSize = nextSpacerSize;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const animateScrollTo = (nextViewport: ScrollViewHandle, targetTop: number, duration = 220) => {
|
|
24
60
|
if (scrollAnimationFrame) cancelAnimationFrame(scrollAnimationFrame);
|
|
25
61
|
|
|
26
62
|
const startTop = nextViewport.scrollTop;
|
|
@@ -47,7 +83,7 @@
|
|
|
47
83
|
};
|
|
48
84
|
|
|
49
85
|
const scrollSelectedIntoView = async (
|
|
50
|
-
nextViewport:
|
|
86
|
+
nextViewport: ScrollViewHandle | null,
|
|
51
87
|
element: HTMLButtonElement | null
|
|
52
88
|
) => {
|
|
53
89
|
if (!nextViewport || !element) return;
|
|
@@ -63,7 +99,7 @@
|
|
|
63
99
|
};
|
|
64
100
|
|
|
65
101
|
const getCenteredIndex = (
|
|
66
|
-
nextViewport:
|
|
102
|
+
nextViewport: ScrollViewHandle | null,
|
|
67
103
|
elements: Array<HTMLButtonElement | null>
|
|
68
104
|
) => {
|
|
69
105
|
if (!nextViewport) return -1;
|
|
@@ -87,7 +123,7 @@
|
|
|
87
123
|
};
|
|
88
124
|
|
|
89
125
|
const getCenterDistance = (
|
|
90
|
-
nextViewport:
|
|
126
|
+
nextViewport: ScrollViewHandle | null,
|
|
91
127
|
element: HTMLButtonElement | null
|
|
92
128
|
) => {
|
|
93
129
|
if (!nextViewport || !element) return Number.POSITIVE_INFINITY;
|
|
@@ -98,30 +134,6 @@
|
|
|
98
134
|
return Math.abs(elementCenter - viewportCenter);
|
|
99
135
|
};
|
|
100
136
|
|
|
101
|
-
const updateVisualDepth = () => {
|
|
102
|
-
if (!viewport) return;
|
|
103
|
-
const viewportRect = viewport.getBoundingClientRect();
|
|
104
|
-
const viewportCenter = viewportRect.top + viewportRect.height / 2;
|
|
105
|
-
const maxDistance = Math.max(viewportRect.height / 2, 1);
|
|
106
|
-
|
|
107
|
-
for (const element of optionRefs) {
|
|
108
|
-
if (!element) continue;
|
|
109
|
-
const rect = element.getBoundingClientRect();
|
|
110
|
-
const center = rect.top + rect.height / 2;
|
|
111
|
-
const ratio = Math.min(1, Math.abs(center - viewportCenter) / maxDistance);
|
|
112
|
-
const emphasis = Math.pow(Math.cos(ratio * (Math.PI / 2)), 2);
|
|
113
|
-
element.style.setProperty('--wheel-column-emphasis', emphasis.toFixed(3));
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const scheduleVisualDepthUpdate = () => {
|
|
118
|
-
if (visualUpdateFrame) cancelAnimationFrame(visualUpdateFrame);
|
|
119
|
-
visualUpdateFrame = requestAnimationFrame(() => {
|
|
120
|
-
visualUpdateFrame = null;
|
|
121
|
-
updateVisualDepth();
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
|
-
|
|
125
137
|
const applyValue = (nextValue: T) => {
|
|
126
138
|
if (value === nextValue) return;
|
|
127
139
|
value = nextValue;
|
|
@@ -129,13 +141,39 @@
|
|
|
129
141
|
};
|
|
130
142
|
|
|
131
143
|
const selectOption = (option: WheelOption<T>, index: number) => {
|
|
144
|
+
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
145
|
+
isUserScrolling = false;
|
|
132
146
|
applyValue(option.value);
|
|
133
147
|
void scrollSelectedIntoView(viewport, optionRefs[index] ?? null);
|
|
134
|
-
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleOptionPointerdown = (event: PointerEvent) => {
|
|
151
|
+
optionPointer = {
|
|
152
|
+
id: event.pointerId,
|
|
153
|
+
x: event.clientX,
|
|
154
|
+
y: event.clientY,
|
|
155
|
+
moved: false
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const handleOptionPointermove = (event: PointerEvent) => {
|
|
160
|
+
if (!optionPointer || optionPointer.id !== event.pointerId) return;
|
|
161
|
+
const distance = Math.hypot(event.clientX - optionPointer.x, event.clientY - optionPointer.y);
|
|
162
|
+
if (distance > 6) optionPointer.moved = true;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const handleOptionClick = (option: WheelOption<T>, index: number) => {
|
|
166
|
+
if (optionPointer?.moved) {
|
|
167
|
+
optionPointer = null;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
optionPointer = null;
|
|
171
|
+
selectOption(option, index);
|
|
135
172
|
};
|
|
136
173
|
|
|
137
174
|
const syncToCurrentValue = () => {
|
|
138
175
|
if (isUserScrolling || !viewport) return;
|
|
176
|
+
measureSpacerSize(viewport);
|
|
139
177
|
const index = options.findIndex((option) => option.value === value);
|
|
140
178
|
if (index < 0) return;
|
|
141
179
|
const element = optionRefs[index] ?? null;
|
|
@@ -143,67 +181,70 @@
|
|
|
143
181
|
if (getCenterDistance(viewport, element) > 1) {
|
|
144
182
|
void scrollSelectedIntoView(viewport, element);
|
|
145
183
|
}
|
|
146
|
-
scheduleVisualDepthUpdate();
|
|
147
184
|
};
|
|
148
185
|
|
|
149
|
-
const
|
|
150
|
-
|
|
186
|
+
const settleScroll = () => {
|
|
187
|
+
isUserScrolling = false;
|
|
188
|
+
const centeredIndex = getCenteredIndex(viewport, optionRefs);
|
|
189
|
+
if (centeredIndex < 0) return;
|
|
190
|
+
const centeredOption = options[centeredIndex];
|
|
191
|
+
const centeredElement = optionRefs[centeredIndex] ?? null;
|
|
192
|
+
if (!centeredOption || !centeredElement) return;
|
|
193
|
+
|
|
194
|
+
const centerDistance = getCenterDistance(viewport, centeredElement);
|
|
195
|
+
if (centerDistance > 1) {
|
|
196
|
+
void scrollSelectedIntoView(viewport, centeredElement);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
applyValue(centeredOption.value);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const handleScroll = (geometry: ScrollGeometry) => {
|
|
203
|
+
scrollOffsetY = geometry.offset.y;
|
|
204
|
+
measureSpacerSize();
|
|
151
205
|
isUserScrolling = true;
|
|
152
|
-
if (scrollingLockTimeout) clearTimeout(scrollingLockTimeout);
|
|
153
|
-
scrollingLockTimeout = setTimeout(() => {
|
|
154
|
-
isUserScrolling = false;
|
|
155
|
-
}, 180);
|
|
156
206
|
|
|
157
207
|
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
158
|
-
scrollTimeout = setTimeout(
|
|
159
|
-
const centeredIndex = getCenteredIndex(viewport, optionRefs);
|
|
160
|
-
if (centeredIndex < 0) return;
|
|
161
|
-
const centeredOption = options[centeredIndex];
|
|
162
|
-
const centeredElement = optionRefs[centeredIndex] ?? null;
|
|
163
|
-
if (!centeredOption || !centeredElement) return;
|
|
164
|
-
|
|
165
|
-
const centerDistance = getCenterDistance(viewport, centeredElement);
|
|
166
|
-
if (centerDistance > 1) {
|
|
167
|
-
void scrollSelectedIntoView(viewport, centeredElement);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
applyValue(centeredOption.value);
|
|
171
|
-
scheduleVisualDepthUpdate();
|
|
172
|
-
}, 140);
|
|
208
|
+
scrollTimeout = setTimeout(settleScroll, 240);
|
|
173
209
|
};
|
|
174
210
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
211
|
+
$effect(() => {
|
|
212
|
+
const nextViewport = viewport;
|
|
213
|
+
const nextValue = value;
|
|
214
|
+
const nextOptions = options;
|
|
215
|
+
if (!nextViewport) return;
|
|
216
|
+
|
|
217
|
+
void tick().then(async () => {
|
|
218
|
+
if (viewport !== nextViewport || value !== nextValue || options !== nextOptions) return;
|
|
219
|
+
untrack(() => {
|
|
220
|
+
measureSpacerSize(nextViewport);
|
|
221
|
+
});
|
|
222
|
+
await tick();
|
|
223
|
+
if (viewport !== nextViewport || value !== nextValue || options !== nextOptions) return;
|
|
224
|
+
untrack(() => {
|
|
225
|
+
syncToCurrentValue();
|
|
226
|
+
});
|
|
180
227
|
});
|
|
228
|
+
});
|
|
181
229
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
scheduleVisualDepthUpdate();
|
|
187
|
-
});
|
|
188
|
-
},
|
|
189
|
-
destroy() {
|
|
190
|
-
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
191
|
-
if (scrollingLockTimeout) clearTimeout(scrollingLockTimeout);
|
|
192
|
-
if (scrollAnimationFrame) cancelAnimationFrame(scrollAnimationFrame);
|
|
193
|
-
if (visualUpdateFrame) cancelAnimationFrame(visualUpdateFrame);
|
|
194
|
-
viewport = null;
|
|
195
|
-
}
|
|
230
|
+
$effect(() => {
|
|
231
|
+
return () => {
|
|
232
|
+
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
233
|
+
if (scrollAnimationFrame) cancelAnimationFrame(scrollAnimationFrame);
|
|
196
234
|
};
|
|
197
|
-
};
|
|
235
|
+
});
|
|
198
236
|
</script>
|
|
199
237
|
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
bind:
|
|
203
|
-
|
|
204
|
-
|
|
238
|
+
<ScrollView
|
|
239
|
+
axis="vertical"
|
|
240
|
+
bind:viewport
|
|
241
|
+
scrollGradient={false}
|
|
242
|
+
showIndicators={false}
|
|
243
|
+
contentStyles={{ paddingX: 0, paddingY: 0 }}
|
|
244
|
+
onScroll={handleScroll}
|
|
205
245
|
>
|
|
206
246
|
<div class="wheel-column-options vstack">
|
|
247
|
+
<div class="wheel-column-spacer" style:height={`${spacerSize}px`} aria-hidden="true"></div>
|
|
207
248
|
{#each options as option, index (option.value)}
|
|
208
249
|
<button
|
|
209
250
|
bind:this={optionRefs[index]}
|
|
@@ -211,47 +252,58 @@
|
|
|
211
252
|
class="wheel-column-option"
|
|
212
253
|
class:wheel-column-option-selected={option.value === value}
|
|
213
254
|
aria-pressed={option.value === value}
|
|
214
|
-
|
|
255
|
+
onpointerdown={handleOptionPointerdown}
|
|
256
|
+
onpointermove={handleOptionPointermove}
|
|
257
|
+
onpointercancel={() => {
|
|
258
|
+
optionPointer = null;
|
|
259
|
+
}}
|
|
260
|
+
onclick={() => handleOptionClick(option, index)}
|
|
215
261
|
>
|
|
216
262
|
{option.label}
|
|
217
263
|
</button>
|
|
218
264
|
{/each}
|
|
265
|
+
<div class="wheel-column-spacer" style:height={`${spacerSize}px`} aria-hidden="true"></div>
|
|
266
|
+
</div>
|
|
267
|
+
</ScrollView>
|
|
268
|
+
|
|
269
|
+
<div
|
|
270
|
+
class="wheel-column-active-layer"
|
|
271
|
+
style:top={`${spacerSize}px`}
|
|
272
|
+
style:height={`${optionHeight}px`}
|
|
273
|
+
aria-hidden="true"
|
|
274
|
+
>
|
|
275
|
+
<div
|
|
276
|
+
class="wheel-column-active-options"
|
|
277
|
+
style:transform={`translateY(${-scrollOffsetY - spacerSize}px)`}
|
|
278
|
+
>
|
|
279
|
+
<div class="wheel-column-spacer" style:height={`${spacerSize}px`}></div>
|
|
280
|
+
{#each options as option (option.value)}
|
|
281
|
+
<div class="wheel-column-active-option">{option.label}</div>
|
|
282
|
+
{/each}
|
|
283
|
+
<div class="wheel-column-spacer" style:height={`${spacerSize}px`}></div>
|
|
219
284
|
</div>
|
|
220
285
|
</div>
|
|
221
286
|
|
|
222
287
|
<style>
|
|
223
|
-
.wheel-column
|
|
224
|
-
height: 100%;
|
|
225
|
-
display: flex;
|
|
226
|
-
flex-direction: column;
|
|
227
|
-
min-height: 0;
|
|
288
|
+
:global(.wheel-picker-column) {
|
|
228
289
|
position: relative;
|
|
229
|
-
overflow
|
|
230
|
-
overflow-x: hidden;
|
|
231
|
-
overscroll-behavior-y: contain;
|
|
232
|
-
scrollbar-width: none;
|
|
233
|
-
-ms-overflow-style: none;
|
|
234
|
-
z-index: 1;
|
|
290
|
+
overflow: hidden;
|
|
235
291
|
}
|
|
236
292
|
|
|
237
|
-
.wheel-column-
|
|
238
|
-
|
|
293
|
+
:global(.wheel-picker-column > .scroll-view) {
|
|
294
|
+
z-index: 1;
|
|
239
295
|
}
|
|
240
296
|
|
|
241
|
-
.wheel-column-
|
|
242
|
-
|
|
243
|
-
content: '';
|
|
244
|
-
display: block;
|
|
245
|
-
flex: 0 0 calc(50% - (var(--wheel-picker-option-height) / 2));
|
|
297
|
+
.wheel-column-options {
|
|
298
|
+
gap: 0;
|
|
246
299
|
}
|
|
247
300
|
|
|
248
|
-
.wheel-column-
|
|
301
|
+
.wheel-column-spacer {
|
|
249
302
|
flex: 0 0 auto;
|
|
250
|
-
|
|
303
|
+
min-height: 0;
|
|
251
304
|
}
|
|
252
305
|
|
|
253
306
|
.wheel-column-option {
|
|
254
|
-
--wheel-column-emphasis: 0;
|
|
255
307
|
width: 100%;
|
|
256
308
|
height: var(--wheel-picker-option-height);
|
|
257
309
|
border: none;
|
|
@@ -260,37 +312,42 @@
|
|
|
260
312
|
display: flex;
|
|
261
313
|
align-items: center;
|
|
262
314
|
justify-content: center;
|
|
263
|
-
padding:
|
|
315
|
+
padding: calc(var(--sveltely-padding-y) * 0.67 * var(--wheel-picker-scale))
|
|
316
|
+
calc(var(--sveltely-padding-x) * 0.67 * var(--wheel-picker-scale));
|
|
264
317
|
font-size: calc(var(--wheel-picker-font-size) * 0.875);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
text-
|
|
268
|
-
|
|
269
|
-
position: relative;
|
|
270
|
-
z-index: 1;
|
|
271
|
-
opacity: calc(0.3 + (var(--wheel-column-emphasis) * 0.7));
|
|
272
|
-
transform: scale(calc(0.84 + (var(--wheel-column-emphasis) * 0.16)));
|
|
273
|
-
transform-origin: center;
|
|
318
|
+
font-variant-numeric: tabular-nums;
|
|
319
|
+
line-height: 1.2;
|
|
320
|
+
color: var(--sveltely-text-secondary-color);
|
|
321
|
+
font-weight: 400;
|
|
274
322
|
transition:
|
|
275
|
-
color
|
|
276
|
-
|
|
277
|
-
opacity 160ms,
|
|
278
|
-
transform 160ms;
|
|
323
|
+
color 120ms,
|
|
324
|
+
font-weight 120ms;
|
|
279
325
|
}
|
|
280
326
|
|
|
281
|
-
.wheel-column-
|
|
282
|
-
|
|
327
|
+
.wheel-column-active-layer {
|
|
328
|
+
position: absolute;
|
|
329
|
+
inset-inline: 0;
|
|
330
|
+
z-index: 2;
|
|
331
|
+
overflow: hidden;
|
|
332
|
+
pointer-events: none;
|
|
283
333
|
}
|
|
284
334
|
|
|
285
|
-
.wheel-column-
|
|
286
|
-
|
|
287
|
-
outline-offset: 2px;
|
|
335
|
+
.wheel-column-active-options {
|
|
336
|
+
will-change: transform;
|
|
288
337
|
}
|
|
289
338
|
|
|
290
|
-
.wheel-column-option
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
339
|
+
.wheel-column-active-option {
|
|
340
|
+
display: flex;
|
|
341
|
+
width: 100%;
|
|
342
|
+
height: var(--wheel-picker-option-height);
|
|
343
|
+
align-items: center;
|
|
344
|
+
justify-content: center;
|
|
345
|
+
padding: calc(var(--sveltely-padding-y) * 0.67 * var(--wheel-picker-scale))
|
|
346
|
+
calc(var(--sveltely-padding-x) * 0.67 * var(--wheel-picker-scale));
|
|
347
|
+
font-size: calc(var(--wheel-picker-font-size) * 0.875);
|
|
348
|
+
font-variant-numeric: tabular-nums;
|
|
349
|
+
line-height: 1.2;
|
|
350
|
+
color: var(--sveltely-text-primary-color);
|
|
351
|
+
font-weight: 600;
|
|
295
352
|
}
|
|
296
353
|
</style>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import WheelColumn from './WheelColumn.svelte';
|
|
3
3
|
import { extractStyleProps, surfaceStyle, type StyleProps } from '../../../style/surface';
|
|
4
|
-
import type {
|
|
4
|
+
import type { AnyWheelColumn } from './types';
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
|
-
columns:
|
|
7
|
+
columns: AnyWheelColumn[];
|
|
8
8
|
height?: number | string;
|
|
9
9
|
} & StyleProps &
|
|
10
10
|
Record<string, unknown>;
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
height: var(--wheel-picker-option-height);
|
|
96
96
|
transform: translateY(-50%);
|
|
97
97
|
border-radius: var(--sveltely-border-radius);
|
|
98
|
-
background: color-mix(in oklab, var(--sveltely-inactive-color) 85%, white);
|
|
98
|
+
background: color-mix(in oklab, var(--sveltely-control-inactive-color) 85%, white);
|
|
99
99
|
pointer-events: none;
|
|
100
100
|
z-index: 0;
|
|
101
101
|
}
|
|
@@ -105,6 +105,6 @@
|
|
|
105
105
|
font-size: calc(var(--wheel-picker-font-size) * 0.75);
|
|
106
106
|
line-height: 1;
|
|
107
107
|
font-weight: 500;
|
|
108
|
-
color: var(--sveltely-secondary-color);
|
|
108
|
+
color: var(--sveltely-text-secondary-color);
|
|
109
109
|
}
|
|
110
110
|
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type StyleProps } from '../../../style/surface';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AnyWheelColumn } from './types';
|
|
3
3
|
type Props = {
|
|
4
|
-
columns:
|
|
4
|
+
columns: AnyWheelColumn[];
|
|
5
5
|
height?: number | string;
|
|
6
6
|
} & StyleProps & Record<string, unknown>;
|
|
7
7
|
declare const WheelPicker: import("svelte").Component<Props, {}, "">;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './WheelPicker.svelte';
|
|
2
|
-
export type { WheelColumn, WheelOption } from './types';
|
|
2
|
+
export type { AnyWheelColumn, WheelColumn, WheelOption } from './types';
|
|
@@ -8,3 +8,9 @@ export type WheelColumn<TValue extends string | number = string> = {
|
|
|
8
8
|
options: WheelOption<TValue>[];
|
|
9
9
|
onChange?: (value: TValue) => void;
|
|
10
10
|
};
|
|
11
|
+
export type AnyWheelColumn = {
|
|
12
|
+
label?: string;
|
|
13
|
+
value: string | number;
|
|
14
|
+
options: WheelOption<string | number>[];
|
|
15
|
+
onChange?: (value: string | number) => void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Divider from '../Library/Divider';
|
|
3
|
+
import HStack from '../Library/HStack';
|
|
4
|
+
import Label from '../Library/Label';
|
|
5
|
+
import VStack from '../Library/VStack';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
borderColor?: string;
|
|
9
|
+
textPrimaryColor?: string;
|
|
10
|
+
textSecondaryColor?: string;
|
|
11
|
+
textTertiaryColor?: string;
|
|
12
|
+
backgroundColor?: string;
|
|
13
|
+
controlActiveColor?: string;
|
|
14
|
+
controlInactiveColor?: string;
|
|
15
|
+
controlBackgroundColor?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
borderColor = $bindable('#e4e4e7'),
|
|
20
|
+
textPrimaryColor = $bindable('#18181b'),
|
|
21
|
+
textSecondaryColor = $bindable('#71717a'),
|
|
22
|
+
textTertiaryColor = $bindable('#a1a1aa'),
|
|
23
|
+
backgroundColor = $bindable('#ffffff'),
|
|
24
|
+
controlActiveColor = $bindable('#18181b'),
|
|
25
|
+
controlInactiveColor = $bindable('#f4f4f5'),
|
|
26
|
+
controlBackgroundColor = $bindable('#fafafa')
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<VStack gap={5}>
|
|
31
|
+
<Label label="Text colors" color="var(--sveltely-text-tertiary-color)" fontSize={7.5} />
|
|
32
|
+
<Label
|
|
33
|
+
label="Text primary"
|
|
34
|
+
orientation="leading"
|
|
35
|
+
width="100%"
|
|
36
|
+
align="center"
|
|
37
|
+
justify="between"
|
|
38
|
+
gap={5}
|
|
39
|
+
>
|
|
40
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
41
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{textPrimaryColor}</span>
|
|
42
|
+
<input
|
|
43
|
+
bind:value={textPrimaryColor}
|
|
44
|
+
type="color"
|
|
45
|
+
aria-label="Text primary"
|
|
46
|
+
class="color-input"
|
|
47
|
+
/>
|
|
48
|
+
</HStack>
|
|
49
|
+
</Label>
|
|
50
|
+
<Label
|
|
51
|
+
label="Text secondary"
|
|
52
|
+
orientation="leading"
|
|
53
|
+
width="100%"
|
|
54
|
+
align="center"
|
|
55
|
+
justify="between"
|
|
56
|
+
gap={5}
|
|
57
|
+
>
|
|
58
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
59
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{textSecondaryColor}</span>
|
|
60
|
+
<input
|
|
61
|
+
bind:value={textSecondaryColor}
|
|
62
|
+
type="color"
|
|
63
|
+
aria-label="Text secondary"
|
|
64
|
+
class="color-input"
|
|
65
|
+
/>
|
|
66
|
+
</HStack>
|
|
67
|
+
</Label>
|
|
68
|
+
<Label
|
|
69
|
+
label="Text tertiary"
|
|
70
|
+
orientation="leading"
|
|
71
|
+
width="100%"
|
|
72
|
+
align="center"
|
|
73
|
+
justify="between"
|
|
74
|
+
gap={5}
|
|
75
|
+
>
|
|
76
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
77
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{textTertiaryColor}</span>
|
|
78
|
+
<input
|
|
79
|
+
bind:value={textTertiaryColor}
|
|
80
|
+
type="color"
|
|
81
|
+
aria-label="Text tertiary"
|
|
82
|
+
class="color-input"
|
|
83
|
+
/>
|
|
84
|
+
</HStack>
|
|
85
|
+
</Label>
|
|
86
|
+
<Divider />
|
|
87
|
+
<Label label="Surface colors" color="var(--sveltely-text-tertiary-color)" fontSize={7.5} />
|
|
88
|
+
<Label
|
|
89
|
+
label="Background color"
|
|
90
|
+
orientation="leading"
|
|
91
|
+
width="100%"
|
|
92
|
+
align="center"
|
|
93
|
+
justify="between"
|
|
94
|
+
gap={5}
|
|
95
|
+
>
|
|
96
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
97
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{backgroundColor}</span>
|
|
98
|
+
<input
|
|
99
|
+
bind:value={backgroundColor}
|
|
100
|
+
type="color"
|
|
101
|
+
aria-label="Background color"
|
|
102
|
+
class="color-input"
|
|
103
|
+
/>
|
|
104
|
+
</HStack>
|
|
105
|
+
</Label>
|
|
106
|
+
<Label
|
|
107
|
+
label="Border color"
|
|
108
|
+
orientation="leading"
|
|
109
|
+
width="100%"
|
|
110
|
+
align="center"
|
|
111
|
+
justify="between"
|
|
112
|
+
gap={5}
|
|
113
|
+
>
|
|
114
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
115
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{borderColor}</span>
|
|
116
|
+
<input bind:value={borderColor} type="color" aria-label="Border color" class="color-input" />
|
|
117
|
+
</HStack>
|
|
118
|
+
</Label>
|
|
119
|
+
<Divider />
|
|
120
|
+
<Label label="Control colors" color="var(--sveltely-text-tertiary-color)" fontSize={7.5} />
|
|
121
|
+
<Label
|
|
122
|
+
label="Control active"
|
|
123
|
+
orientation="leading"
|
|
124
|
+
width="100%"
|
|
125
|
+
align="center"
|
|
126
|
+
justify="between"
|
|
127
|
+
gap={5}
|
|
128
|
+
>
|
|
129
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
130
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{controlActiveColor}</span>
|
|
131
|
+
<input
|
|
132
|
+
bind:value={controlActiveColor}
|
|
133
|
+
type="color"
|
|
134
|
+
aria-label="Control active"
|
|
135
|
+
class="color-input"
|
|
136
|
+
/>
|
|
137
|
+
</HStack>
|
|
138
|
+
</Label>
|
|
139
|
+
<Label
|
|
140
|
+
label="Control background"
|
|
141
|
+
orientation="leading"
|
|
142
|
+
width="100%"
|
|
143
|
+
align="center"
|
|
144
|
+
justify="between"
|
|
145
|
+
gap={5}
|
|
146
|
+
>
|
|
147
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
148
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{controlBackgroundColor}</span>
|
|
149
|
+
<input
|
|
150
|
+
bind:value={controlBackgroundColor}
|
|
151
|
+
type="color"
|
|
152
|
+
aria-label="Control background"
|
|
153
|
+
class="color-input"
|
|
154
|
+
/>
|
|
155
|
+
</HStack>
|
|
156
|
+
</Label>
|
|
157
|
+
<Label
|
|
158
|
+
label="Control inactive"
|
|
159
|
+
orientation="leading"
|
|
160
|
+
width="100%"
|
|
161
|
+
align="center"
|
|
162
|
+
justify="between"
|
|
163
|
+
gap={5}
|
|
164
|
+
>
|
|
165
|
+
<HStack width="100%" align="center" justify="end" gap={5}>
|
|
166
|
+
<span class="text-[var(--sveltely-text-secondary-color)]">{controlInactiveColor}</span>
|
|
167
|
+
<input
|
|
168
|
+
bind:value={controlInactiveColor}
|
|
169
|
+
type="color"
|
|
170
|
+
aria-label="Control inactive"
|
|
171
|
+
class="color-input"
|
|
172
|
+
/>
|
|
173
|
+
</HStack>
|
|
174
|
+
</Label>
|
|
175
|
+
</VStack>
|
|
176
|
+
|
|
177
|
+
<style>
|
|
178
|
+
.color-input {
|
|
179
|
+
width: 2.5rem;
|
|
180
|
+
height: 2.5rem;
|
|
181
|
+
flex: 0 0 2.5rem;
|
|
182
|
+
border: 1px solid var(--sveltely-border-color);
|
|
183
|
+
border-radius: 0.375rem;
|
|
184
|
+
background: white;
|
|
185
|
+
padding: 0.1875rem;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.color-input::-webkit-color-swatch-wrapper {
|
|
189
|
+
padding: 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.color-input::-webkit-color-swatch {
|
|
193
|
+
border: 0;
|
|
194
|
+
border-radius: 0.25rem;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.color-input::-moz-color-swatch {
|
|
198
|
+
border: 0;
|
|
199
|
+
border-radius: 0.25rem;
|
|
200
|
+
}
|
|
201
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
borderColor?: string;
|
|
3
|
+
textPrimaryColor?: string;
|
|
4
|
+
textSecondaryColor?: string;
|
|
5
|
+
textTertiaryColor?: string;
|
|
6
|
+
backgroundColor?: string;
|
|
7
|
+
controlActiveColor?: string;
|
|
8
|
+
controlInactiveColor?: string;
|
|
9
|
+
controlBackgroundColor?: string;
|
|
10
|
+
};
|
|
11
|
+
declare const ColorStyleControls: import("svelte").Component<Props, {}, "backgroundColor" | "borderColor" | "textPrimaryColor" | "textSecondaryColor" | "textTertiaryColor" | "controlActiveColor" | "controlInactiveColor" | "controlBackgroundColor">;
|
|
12
|
+
type ColorStyleControls = ReturnType<typeof ColorStyleControls>;
|
|
13
|
+
export default ColorStyleControls;
|