@destyler-ui/svelte 0.0.1-beta.17 → 0.0.1-beta.20
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/README.md +7 -1
- package/dist/components/aspect-ratio/components/Root.svelte +1 -2
- package/dist/components/aspect-ratio/hooks/use-aspect-ratio.svelte.d.ts +0 -1
- package/dist/components/aspect-ratio/hooks/use-aspect-ratio.svelte.js +1 -1
- package/dist/components/calendar/anatomy.d.ts +1 -1
- package/dist/components/calendar/components/Content.d.svelte.ts +1 -1
- package/dist/components/calendar/components/Content.svelte +2 -3
- package/dist/components/calendar/components/Content.svelte.d.ts +1 -1
- package/dist/components/calendar/components/Root.svelte +14 -8
- package/dist/components/calendar/hooks/use-calendar.svelte.d.ts +1 -1
- package/dist/components/calendar/hooks/use-calendar.svelte.js +13 -3
- package/dist/components/carousel/components/Root.svelte +9 -3
- package/dist/components/checkbox/components/Group.svelte +8 -2
- package/dist/components/checkbox/components/Root.svelte +8 -2
- package/dist/components/checkbox/hooks/use-checkbox-group.svelte.d.ts +17 -7
- package/dist/components/checkbox/hooks/use-checkbox-group.svelte.js +7 -4
- package/dist/components/checkbox/hooks/use-checkbox.svelte.js +14 -2
- package/dist/components/collapse/components/Root.svelte +9 -3
- package/dist/components/collapsible/components/Root.svelte +9 -3
- package/dist/components/collapsible/hooks/split-collapsible-props.svelte.d.ts +1 -1
- package/dist/components/collapsible/hooks/use-collapsible.svelte.d.ts +1 -1
- package/dist/components/color-picker/anatomy.d.ts +1 -1
- package/dist/components/color-picker/components/ChannelInput.svelte +9 -1
- package/dist/components/color-picker/components/Root.svelte +12 -4
- package/dist/components/color-picker/hooks/split-color-picker-props.svelte.d.ts +1 -1
- package/dist/components/color-picker/hooks/use-color-picker.svelte.d.ts +1 -1
- package/dist/components/combobox/components/Content.svelte +4 -7
- package/dist/components/combobox/components/Root.svelte +12 -6
- package/dist/components/combobox/hooks/use-combobox.svelte.d.ts +1 -1
- package/dist/components/combobox/hooks/use-combobox.svelte.js +13 -1
- package/dist/components/dialog/components/Root.svelte +10 -3
- package/dist/components/dialog/hooks/use-dialog.svelte.d.ts +1 -1
- package/dist/components/dynamic/components/Root.svelte +11 -3
- package/dist/components/dynamic/hooks/use-dynamic.svelte.js +26 -13
- package/dist/components/edit/components/Root.svelte +12 -5
- package/dist/components/edit/hooks/use-edit.svelte.d.ts +1 -1
- package/dist/components/edit/hooks/use-edit.svelte.js +25 -3
- package/dist/components/floating-panel/components/Root.svelte +17 -7
- package/dist/components/floating-panel/hooks/use-floating-panel.svelte.d.ts +1 -1
- package/dist/components/floating-panel/hooks/use-floating-panel.svelte.js +0 -5
- package/dist/components/hover-card/components/Root.svelte +9 -3
- package/dist/components/hover-card/hooks/use-hover-card.svelte.d.ts +1 -1
- package/dist/components/menu/components/CheckboxItem.svelte +9 -3
- package/dist/components/menu/components/RadioItemGroup.svelte +5 -2
- package/dist/components/menu/components/Root.svelte +9 -3
- package/dist/components/menu/hooks/use-menu.svelte.d.ts +1 -1
- package/dist/components/navigation-menu/components/Root.svelte +3 -3
- package/dist/components/navigation-menu/hooks/connect-navigation-menu.d.ts +10 -0
- package/dist/components/navigation-menu/hooks/connect-navigation-menu.js +42 -0
- package/dist/components/navigation-menu/hooks/use-navigation-menu.svelte.d.ts +1 -2
- package/dist/components/navigation-menu/hooks/use-navigation-menu.svelte.js +11 -21
- package/dist/components/number-input/components/Root.svelte +8 -2
- package/dist/components/number-input/hooks/use-number-input.svelte.js +183 -2
- package/dist/components/otp-input/components/Input.svelte +6 -1
- package/dist/components/otp-input/components/Root.svelte +8 -2
- package/dist/components/pagination/components/Root.svelte +14 -5
- package/dist/components/popover/components/Root.svelte +10 -3
- package/dist/components/popover/hooks/use-popover.svelte.d.ts +1 -1
- package/dist/components/presence/components/Presence.svelte +6 -0
- package/dist/components/progress/components/Root.svelte +8 -2
- package/dist/components/progress/hooks/use-progress.svelte.js +17 -3
- package/dist/components/qr-code/components/Root.svelte +8 -2
- package/dist/components/qr-code/hooks/use-qr-code.svelte.js +14 -4
- package/dist/components/radio/components/Root.svelte +9 -3
- package/dist/components/radio/hooks/use-radio.svelte.js +10 -1
- package/dist/components/scroll-area/hooks/use-scroll-area.svelte.js +0 -28
- package/dist/components/select/components/Root.svelte +7 -3
- package/dist/components/select/hooks/use-select.svelte.d.ts +1 -1
- package/dist/components/slider/components/DraggingIndicator.svelte +3 -3
- package/dist/components/slider/components/Root.svelte +8 -2
- package/dist/components/slider/components/ThumbPropsProvider.svelte +4 -2
- package/dist/components/splitter/components/Root.svelte +9 -3
- package/dist/components/steps/components/Root.svelte +9 -3
- package/dist/components/steps/hooks/split-steps-props.svelte.d.ts +1 -1
- package/dist/components/switch/components/Root.svelte +9 -3
- package/dist/components/switch/hooks/use-switch.svelte.d.ts +12 -1
- package/dist/components/switch/hooks/use-switch.svelte.js +10 -1
- package/dist/components/tabs/components/Root.svelte +9 -3
- package/dist/components/toggle/components/Root.svelte +8 -2
- package/dist/components/toggle-group/components/Root.svelte +9 -3
- package/dist/components/tooltip/components/Root.svelte +9 -3
- package/dist/components/tooltip/hooks/use-tooltip.svelte.d.ts +1 -1
- package/dist/components/tree/components/BranchTrigger.d.svelte.ts +2 -2
- package/dist/components/tree/components/BranchTrigger.svelte +3 -3
- package/dist/components/tree/components/BranchTrigger.svelte.d.ts +2 -2
- package/dist/components/tree/components/Root.svelte +8 -3
- package/dist/components/tree/hooks/tree-split-props.d.ts +1 -1
- package/dist/providers/frame/components/Content.svelte +4 -1
- package/dist/utils/create-machine-props.d.ts +18 -7
- package/dist/utils/create-machine-props.js +22 -18
- package/dist/utils/sync-checked.d.ts +6 -0
- package/dist/utils/sync-checked.js +28 -0
- package/dist/utils/sync-input-value.d.ts +4 -0
- package/dist/utils/sync-input-value.js +27 -0
- package/dist/utils/sync-number-input.d.ts +2 -0
- package/dist/utils/sync-number-input.js +45 -0
- package/package.json +72 -68
|
@@ -3,8 +3,13 @@ import { useEnvironmentContext } from '../../../providers/environment/index.js';
|
|
|
3
3
|
import { useLocaleContext } from '../../../providers/locale/index.js';
|
|
4
4
|
import { createMachineProps } from '../../../utils/create-machine-props.js';
|
|
5
5
|
import { normalizeProps } from '../../../utils/normalize-props.js';
|
|
6
|
+
import { createInputValueSync } from '../../../utils/sync-input-value.js';
|
|
7
|
+
import { syncNumberInputElement } from '../../../utils/sync-number-input.js';
|
|
8
|
+
import { createScope } from '@destyler/dom';
|
|
6
9
|
import * as numberInput from '@destyler/number-input';
|
|
10
|
+
import { mergeProps } from '@destyler/svelte';
|
|
7
11
|
import { runIfFn } from '@destyler/utils';
|
|
12
|
+
import { onDestroy, onMount, tick, untrack } from 'svelte';
|
|
8
13
|
import { useFieldContext } from '../../field/index.js';
|
|
9
14
|
export function useNumberInput(props) {
|
|
10
15
|
const env = useEnvironmentContext();
|
|
@@ -27,11 +32,187 @@ export function useNumberInput(props) {
|
|
|
27
32
|
...resolvedProps,
|
|
28
33
|
}, { value: 'defaultValue' });
|
|
29
34
|
});
|
|
30
|
-
|
|
35
|
+
let isEditingInput = $state(false);
|
|
36
|
+
let editingInput;
|
|
37
|
+
let composingValue = $state();
|
|
38
|
+
let composingInput;
|
|
39
|
+
let compositionVersion = 0;
|
|
40
|
+
let compositionEpoch = 0;
|
|
41
|
+
let disposed = false;
|
|
42
|
+
let cancelInputSync;
|
|
43
|
+
const isComposing = () => composingValue !== undefined && !!composingInput?.isConnected;
|
|
44
|
+
const machine = untrack(() => numberInput.machine(machineProps.initial));
|
|
45
|
+
const scope = createScope({});
|
|
46
|
+
const trackCoreFormControl = machine.options.activities?.trackFormControl;
|
|
47
|
+
let refreshFormControl;
|
|
48
|
+
machine.setOptions({
|
|
49
|
+
activities: {
|
|
50
|
+
trackFormControl(context, event, meta) {
|
|
51
|
+
let trackedInput;
|
|
52
|
+
let trackedForm;
|
|
53
|
+
let cleanup;
|
|
54
|
+
const refresh = () => {
|
|
55
|
+
const inputId = context.ids?.input ?? `number-input:${context.id}:input`;
|
|
56
|
+
const input = scope.getById(context, inputId);
|
|
57
|
+
const form = input?.form;
|
|
58
|
+
if (input === trackedInput && form === trackedForm)
|
|
59
|
+
return;
|
|
60
|
+
cleanup?.();
|
|
61
|
+
trackedInput = input;
|
|
62
|
+
trackedForm = form;
|
|
63
|
+
cleanup = trackCoreFormControl?.(context, event, meta) ?? undefined;
|
|
64
|
+
};
|
|
65
|
+
refreshFormControl = refresh;
|
|
66
|
+
refresh();
|
|
67
|
+
return () => {
|
|
68
|
+
refreshFormControl = undefined;
|
|
69
|
+
cleanup?.();
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
const [state, send] = useMachine(machine, {
|
|
31
75
|
get context() {
|
|
32
76
|
return machineProps.context;
|
|
33
77
|
},
|
|
78
|
+
actions: {
|
|
79
|
+
syncInputElement(context, event) {
|
|
80
|
+
cancelInputSync?.();
|
|
81
|
+
if (isComposing())
|
|
82
|
+
return;
|
|
83
|
+
const inputId = context.ids?.input ?? `number-input:${context.id}:input`;
|
|
84
|
+
const input = scope.getById(context, inputId);
|
|
85
|
+
if (!input)
|
|
86
|
+
return;
|
|
87
|
+
const epoch = compositionEpoch;
|
|
88
|
+
const value = event.type.endsWith('CHANGE') ? context.value : context.formattedValue;
|
|
89
|
+
// Core queues its write in RAF. Composition can start after this action
|
|
90
|
+
// ran, so check ownership again at execution time, including end/blur.
|
|
91
|
+
cancelInputSync = syncNumberInputElement(input, value ?? '', () => !disposed && !isComposing()
|
|
92
|
+
&& epoch === compositionEpoch && scope.getById(context, inputId) === input);
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
onDestroy(() => {
|
|
97
|
+
disposed = true;
|
|
98
|
+
cancelInputSync?.();
|
|
99
|
+
compositionVersion++;
|
|
100
|
+
});
|
|
101
|
+
const getInputValue = () => isComposing() ? composingValue : (state.hasTag('focus') && isEditingInput && editingInput?.isConnected ? state.context.value : state.context.formattedValue);
|
|
102
|
+
const syncInputValue = createInputValueSync(() => ({ value: getInputValue() }), () => state.context.value, () => !disposed && !isComposing());
|
|
103
|
+
const api = $derived.by(() => {
|
|
104
|
+
const connected = numberInput.connect(state, send, normalizeProps);
|
|
105
|
+
return {
|
|
106
|
+
...connected,
|
|
107
|
+
getInputProps() {
|
|
108
|
+
const inputProps = connected.getInputProps();
|
|
109
|
+
// Core exposes a formatted defaultValue, but Svelte applies it as a
|
|
110
|
+
// live value. Keep the core's raw text during native editing so partial
|
|
111
|
+
// numbers such as "1." are not reformatted during accepted input.
|
|
112
|
+
return mergeProps(inputProps, {
|
|
113
|
+
value: getInputValue(),
|
|
114
|
+
oninput(event) {
|
|
115
|
+
// Composition is an edit too. Core 0.2.9 reconciles a rejected
|
|
116
|
+
// INPUT.CHANGE to raw text until blur, including IME input.
|
|
117
|
+
editingInput = event.currentTarget;
|
|
118
|
+
isEditingInput = true;
|
|
119
|
+
if (event.isComposing) {
|
|
120
|
+
if (!isComposing()) {
|
|
121
|
+
compositionVersion++;
|
|
122
|
+
compositionEpoch++;
|
|
123
|
+
}
|
|
124
|
+
composingInput = event.currentTarget;
|
|
125
|
+
composingValue = composingInput.value;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// A final input event can follow compositionend in the same turn.
|
|
129
|
+
// Its current value supersedes any pending end reconciliation.
|
|
130
|
+
compositionVersion++;
|
|
131
|
+
composingValue = undefined;
|
|
132
|
+
composingInput = undefined;
|
|
133
|
+
void syncInputValue(event);
|
|
134
|
+
},
|
|
135
|
+
oncompositionstart(event) {
|
|
136
|
+
compositionEpoch++;
|
|
137
|
+
compositionVersion++;
|
|
138
|
+
composingInput = event.currentTarget;
|
|
139
|
+
composingValue = composingInput.value;
|
|
140
|
+
},
|
|
141
|
+
async oncompositionend(event) {
|
|
142
|
+
compositionEpoch++;
|
|
143
|
+
const input = event.currentTarget;
|
|
144
|
+
if (!isComposing()) {
|
|
145
|
+
if (input.value === state.context.value) {
|
|
146
|
+
editingInput = input;
|
|
147
|
+
isEditingInput = true;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
void syncInputValue(event);
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const version = compositionVersion;
|
|
155
|
+
const value = input.value;
|
|
156
|
+
const { selectionStart, selectionEnd, selectionDirection } = input;
|
|
157
|
+
composingValue = value;
|
|
158
|
+
// Keep native text through both core and bound-parent flushes.
|
|
159
|
+
await tick();
|
|
160
|
+
if (disposed || !input.isConnected || version !== compositionVersion)
|
|
161
|
+
return;
|
|
162
|
+
if (value === state.context.value) {
|
|
163
|
+
editingInput = input;
|
|
164
|
+
isEditingInput = true;
|
|
165
|
+
}
|
|
166
|
+
composingValue = undefined;
|
|
167
|
+
composingInput = undefined;
|
|
168
|
+
await tick();
|
|
169
|
+
if (disposed || !input.isConnected || version !== compositionVersion)
|
|
170
|
+
return;
|
|
171
|
+
if (selectionStart !== null && selectionEnd !== null)
|
|
172
|
+
input.setSelectionRange(selectionStart, selectionEnd, selectionDirection ?? undefined);
|
|
173
|
+
},
|
|
174
|
+
onfocusout() {
|
|
175
|
+
compositionEpoch++;
|
|
176
|
+
compositionVersion++;
|
|
177
|
+
composingValue = undefined;
|
|
178
|
+
composingInput = undefined;
|
|
179
|
+
editingInput = undefined;
|
|
180
|
+
isEditingInput = false;
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
onMount(() => {
|
|
187
|
+
const root = env().getRootNode();
|
|
188
|
+
const getInput = () => scope.getById(state.context, String(api.getInputProps().id));
|
|
189
|
+
const onReset = async (event) => {
|
|
190
|
+
// Refresh even for a different form: a moved or removed input must stop
|
|
191
|
+
// listening to its old form before that form's reset reaches target phase.
|
|
192
|
+
// Core keeps the original seed and controlled ownership callback rules.
|
|
193
|
+
refreshFormControl?.();
|
|
194
|
+
const input = getInput();
|
|
195
|
+
if (!input || input.form !== event.target)
|
|
196
|
+
return;
|
|
197
|
+
// The browser resets the property even when core's initial value equals
|
|
198
|
+
// its current value (and thus triggers no watcher). Reconcile after the
|
|
199
|
+
// default action and parent writeback, also ending any interrupted edit.
|
|
200
|
+
await tick();
|
|
201
|
+
if (event.defaultPrevented || disposed || !input.isConnected || input !== getInput())
|
|
202
|
+
return;
|
|
203
|
+
const version = ++compositionVersion;
|
|
204
|
+
compositionEpoch++;
|
|
205
|
+
composingValue = undefined;
|
|
206
|
+
composingInput = undefined;
|
|
207
|
+
editingInput = undefined;
|
|
208
|
+
isEditingInput = false;
|
|
209
|
+
await tick();
|
|
210
|
+
if (disposed || !input.isConnected || version !== compositionVersion || input !== getInput())
|
|
211
|
+
return;
|
|
212
|
+
input.value = String(getInputValue() ?? '');
|
|
213
|
+
};
|
|
214
|
+
root.addEventListener('reset', onReset, true);
|
|
215
|
+
return () => root.removeEventListener('reset', onReset, true);
|
|
34
216
|
});
|
|
35
|
-
const api = $derived(numberInput.connect(state, send, normalizeProps));
|
|
36
217
|
return () => api;
|
|
37
218
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<script lang="ts">
|
|
10
10
|
import { mergeProps } from '@destyler/svelte'
|
|
11
|
+
import { createInputValueSync } from '../../../utils/sync-input-value'
|
|
11
12
|
import { createSplitProps } from '../../../utils/create-split-props'
|
|
12
13
|
import { UI } from '../../factory'
|
|
13
14
|
import { useOtpInputContext } from '../hooks/use-otp-input-context'
|
|
@@ -17,7 +18,11 @@
|
|
|
17
18
|
|
|
18
19
|
const [inputProps, localProps] = $derived(createSplitProps<InputProps>()(props, ['index']))
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
+
const syncInputValue = createInputValueSync(() => otpInput().getInputProps(inputProps), () => otpInput().value)
|
|
22
|
+
const mergedProps = $derived(mergeProps(otpInput().getInputProps(inputProps), localProps, {
|
|
23
|
+
oninput: syncInputValue,
|
|
24
|
+
oncompositionend: syncInputValue,
|
|
25
|
+
}))
|
|
21
26
|
</script>
|
|
22
27
|
|
|
23
28
|
<UI as="input" {...mergedProps} />
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
import { OtpInputProvider } from '../hooks/use-otp-input-context'
|
|
17
17
|
import { useOtpInput } from '../hooks/use-otp-input.svelte'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
20
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
21
|
+
let {
|
|
22
|
+
value = $bindable(),
|
|
23
|
+
value: valueProp,
|
|
24
|
+
...props
|
|
25
|
+
}: OtpInputRootProps = $props()
|
|
20
26
|
const providedId = $props.id()
|
|
21
27
|
|
|
22
28
|
const [useOtpInputProps, localProps] = $derived(
|
|
@@ -49,7 +55,7 @@
|
|
|
49
55
|
const resolvedProps = $derived<UseOtpInputProps>({
|
|
50
56
|
...useOtpInputProps,
|
|
51
57
|
id: useOtpInputProps.id ?? providedId,
|
|
52
|
-
value,
|
|
58
|
+
value: valueProp,
|
|
53
59
|
onValueChange(details) {
|
|
54
60
|
useOtpInputProps.onValueChange?.(details)
|
|
55
61
|
value = details.value
|
|
@@ -13,7 +13,15 @@
|
|
|
13
13
|
import { PaginationProvider } from '../hooks/use-pagination-context'
|
|
14
14
|
import { usePagination } from '../hooks/use-pagination.svelte'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
17
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
18
|
+
let {
|
|
19
|
+
page = $bindable(),
|
|
20
|
+
page: pageProp,
|
|
21
|
+
pageSize = $bindable(),
|
|
22
|
+
pageSize: pageSizeProp,
|
|
23
|
+
...props
|
|
24
|
+
}: PaginationRootProps = $props()
|
|
17
25
|
const providedId = $props.id()
|
|
18
26
|
|
|
19
27
|
const [paginationProps, localProps] = $derived(
|
|
@@ -26,6 +34,7 @@
|
|
|
26
34
|
'onPageSizeChange',
|
|
27
35
|
'page',
|
|
28
36
|
'pageSize',
|
|
37
|
+
'defaultPageSize',
|
|
29
38
|
'siblingCount',
|
|
30
39
|
'translations',
|
|
31
40
|
'type',
|
|
@@ -35,15 +44,15 @@
|
|
|
35
44
|
const resolvedProps = $derived<UsePaginationProps>({
|
|
36
45
|
...paginationProps,
|
|
37
46
|
id: paginationProps.id ?? providedId,
|
|
38
|
-
page,
|
|
39
|
-
pageSize,
|
|
47
|
+
page: pageProp,
|
|
48
|
+
pageSize: pageSizeProp,
|
|
40
49
|
onPageChange(details) {
|
|
41
50
|
paginationProps.onPageChange?.(details)
|
|
42
|
-
|
|
51
|
+
page = details.page
|
|
43
52
|
},
|
|
44
53
|
onPageSizeChange(details) {
|
|
45
54
|
paginationProps.onPageSizeChange?.(details)
|
|
46
|
-
|
|
55
|
+
pageSize = details.pageSize
|
|
47
56
|
},
|
|
48
57
|
})
|
|
49
58
|
|
|
@@ -16,7 +16,14 @@
|
|
|
16
16
|
import { PopoverProvider } from '../hooks/use-popover-context'
|
|
17
17
|
import { usePopover } from '../hooks/use-popover.svelte'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
20
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
21
|
+
let {
|
|
22
|
+
open = $bindable(),
|
|
23
|
+
open: openProp,
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: PopoverRootProps = $props()
|
|
20
27
|
|
|
21
28
|
const providedId = $props.id()
|
|
22
29
|
|
|
@@ -26,10 +33,10 @@
|
|
|
26
33
|
return {
|
|
27
34
|
...localProps,
|
|
28
35
|
id: localProps.id ?? providedId,
|
|
29
|
-
open,
|
|
36
|
+
open: openProp,
|
|
30
37
|
onOpenChange(details) {
|
|
31
38
|
localProps.onOpenChange?.(details)
|
|
32
|
-
|
|
39
|
+
open = details.open
|
|
33
40
|
},
|
|
34
41
|
}
|
|
35
42
|
})
|
|
@@ -2,7 +2,7 @@ import type { Accessor } from '../../../types.js';
|
|
|
2
2
|
import type { PropTypes } from '@destyler/svelte';
|
|
3
3
|
import type { MaybeFunction } from '@destyler/utils';
|
|
4
4
|
import * as popover from '@destyler/popover';
|
|
5
|
-
export interface UsePopoverProps extends Omit<popover.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UsePopoverProps extends Omit<popover.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultOpen?: popover.Context['open'];
|
|
8
8
|
}
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
import { ProgressProvider } from '../hooks/use-progress-context'
|
|
14
14
|
import { useProgress } from '../hooks/use-progress.svelte'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
17
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
18
|
+
let {
|
|
19
|
+
value = $bindable(),
|
|
20
|
+
value: valueProp,
|
|
21
|
+
...props
|
|
22
|
+
}: ProgressRootProps = $props()
|
|
17
23
|
const providedId = $props.id()
|
|
18
24
|
|
|
19
25
|
const [useProgressProps, localProps] = $derived(
|
|
@@ -32,7 +38,7 @@
|
|
|
32
38
|
const resolvedProps = $derived<UseProgressProps>({
|
|
33
39
|
...useProgressProps,
|
|
34
40
|
id: useProgressProps.id ?? providedId,
|
|
35
|
-
value,
|
|
41
|
+
value: valueProp,
|
|
36
42
|
onValueChange(details) {
|
|
37
43
|
value = details.value
|
|
38
44
|
useProgressProps.onValueChange?.(details)
|
|
@@ -10,11 +10,25 @@ export function useProgress(props) {
|
|
|
10
10
|
const locale = useLocaleContext();
|
|
11
11
|
const machineProps = $derived.by(() => {
|
|
12
12
|
const resolvedProps = runIfFn(props);
|
|
13
|
-
|
|
13
|
+
const { defaultValue, value, ...rest } = resolvedProps;
|
|
14
|
+
const base = {
|
|
14
15
|
dir: locale().dir,
|
|
15
16
|
getRootNode: env().getRootNode,
|
|
16
|
-
...
|
|
17
|
-
}
|
|
17
|
+
...rest,
|
|
18
|
+
};
|
|
19
|
+
// @destyler/progress@0.2.7 has no controllable defaultValue — seed initial only.
|
|
20
|
+
const initialValue = value !== undefined ? value : defaultValue;
|
|
21
|
+
const reactive = createMachineProps({
|
|
22
|
+
...base,
|
|
23
|
+
...(value !== undefined ? { value } : {}),
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
initial: {
|
|
27
|
+
...reactive.initial,
|
|
28
|
+
...(initialValue !== undefined ? { value: initialValue } : {}),
|
|
29
|
+
},
|
|
30
|
+
context: reactive.context,
|
|
31
|
+
};
|
|
18
32
|
});
|
|
19
33
|
const [state, send] = useMachine(() => progress.machine(machineProps.initial), {
|
|
20
34
|
get context() {
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
import { QrCodeProvider } from '../hooks/use-qr-code-context'
|
|
14
14
|
import { useQrCode } from '../hooks/use-qr-code.svelte'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
17
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
18
|
+
let {
|
|
19
|
+
value = $bindable(),
|
|
20
|
+
value: valueProp,
|
|
21
|
+
...props
|
|
22
|
+
}: QrCodeRootProps = $props()
|
|
17
23
|
const providedId = $props.id()
|
|
18
24
|
|
|
19
25
|
const [useQrCodeProps, localProps] = $derived(
|
|
@@ -30,7 +36,7 @@
|
|
|
30
36
|
const resolvedProps = $derived<UseQrCodeProps>({
|
|
31
37
|
...useQrCodeProps,
|
|
32
38
|
id: useQrCodeProps.id ?? providedId,
|
|
33
|
-
value,
|
|
39
|
+
value: valueProp,
|
|
34
40
|
onValueChange(details) {
|
|
35
41
|
value = details.value
|
|
36
42
|
useQrCodeProps.onValueChange?.(details)
|
|
@@ -9,12 +9,22 @@ export function useQrCode(props) {
|
|
|
9
9
|
const env = useEnvironmentContext();
|
|
10
10
|
const locale = useLocaleContext();
|
|
11
11
|
const machineProps = $derived.by(() => {
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const { defaultValue, value, ...rest } = runIfFn(props);
|
|
13
|
+
const reactive = createMachineProps({
|
|
14
14
|
dir: locale().dir,
|
|
15
15
|
getRootNode: env().getRootNode,
|
|
16
|
-
...
|
|
17
|
-
|
|
16
|
+
...rest,
|
|
17
|
+
...(value !== undefined ? { value } : {}),
|
|
18
|
+
});
|
|
19
|
+
// @destyler/qr-code@0.2.7 stores value directly — seed defaults only once.
|
|
20
|
+
const initialValue = value !== undefined ? value : defaultValue;
|
|
21
|
+
return {
|
|
22
|
+
initial: {
|
|
23
|
+
...reactive.initial,
|
|
24
|
+
...(initialValue !== undefined ? { value: initialValue } : {}),
|
|
25
|
+
},
|
|
26
|
+
context: reactive.context,
|
|
27
|
+
};
|
|
18
28
|
});
|
|
19
29
|
const [state, send] = useMachine(() => qrcode.machine(machineProps.initial), {
|
|
20
30
|
get context() {
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
import { RadioProvider } from '../hooks/use-radio-context'
|
|
14
14
|
import { useRadio } from '../hooks/use-radio.svelte'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
17
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
18
|
+
let {
|
|
19
|
+
value = $bindable(),
|
|
20
|
+
value: valueProp,
|
|
21
|
+
...props
|
|
22
|
+
}: RadioRootProps = $props()
|
|
17
23
|
const providedId = $props.id()
|
|
18
24
|
|
|
19
25
|
const [radioGroupProps, localProps] = $derived(
|
|
@@ -34,10 +40,10 @@
|
|
|
34
40
|
const resolvedProps = $derived<UseRadioProps>({
|
|
35
41
|
...radioGroupProps,
|
|
36
42
|
id: radioGroupProps.id ?? providedId,
|
|
37
|
-
value,
|
|
43
|
+
value: valueProp,
|
|
38
44
|
onValueChange(details) {
|
|
39
45
|
radioGroupProps.onValueChange?.(details)
|
|
40
|
-
|
|
46
|
+
value = details.value
|
|
41
47
|
},
|
|
42
48
|
})
|
|
43
49
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useMachine } from '../../../hooks/use-destyler-machine.svelte.js';
|
|
2
2
|
import { normalizeProps } from '../../../utils/normalize-props.js';
|
|
3
|
+
import { createRadioCheckedSync } from '../../../utils/sync-checked.js';
|
|
3
4
|
import * as radio from '@destyler/radio';
|
|
5
|
+
import { mergeProps } from '@destyler/svelte';
|
|
4
6
|
import { runIfFn } from '@destyler/utils';
|
|
5
7
|
import { useEnvironmentContext, useLocaleContext } from '../../../providers/index.js';
|
|
6
8
|
import { createMachineProps } from '../../../utils/create-machine-props.js';
|
|
@@ -20,6 +22,13 @@ export function useRadio(props) {
|
|
|
20
22
|
return resolvedProps.context;
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
|
-
const
|
|
25
|
+
const connected = $derived(radio.connect(state, send, normalizeProps));
|
|
26
|
+
const syncChecked = createRadioCheckedSync(value => connected.getItemState({ value }).checked);
|
|
27
|
+
const api = $derived({
|
|
28
|
+
...connected,
|
|
29
|
+
getItemHiddenInputProps(itemProps) {
|
|
30
|
+
return mergeProps(connected.getItemHiddenInputProps(itemProps), { onclick: syncChecked });
|
|
31
|
+
},
|
|
32
|
+
});
|
|
24
33
|
return () => api;
|
|
25
34
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useMachine } from '../../../hooks/use-destyler-machine.svelte.js';
|
|
2
2
|
import { normalizeProps } from '../../../utils/normalize-props.js';
|
|
3
|
-
import { resolveQueryRoot } from '../../../utils/resolve-query-root.js';
|
|
4
3
|
import * as scrollArea from '@destyler/scroll-area';
|
|
5
|
-
import { ref } from '@destyler/store';
|
|
6
4
|
import { runIfFn } from '@destyler/utils';
|
|
7
5
|
import { onMount } from 'svelte';
|
|
8
6
|
import { useEnvironmentContext, useLocaleContext } from '../../../providers/index.js';
|
|
@@ -24,32 +22,6 @@ export function useScrollArea(props) {
|
|
|
24
22
|
get context() {
|
|
25
23
|
return machineProps;
|
|
26
24
|
},
|
|
27
|
-
actions: {
|
|
28
|
-
// @destyler/scroll-area 0.2.6 stores ResizeObserver in proxied context.
|
|
29
|
-
// Marking only this native instance as raw lets the core cleanup action
|
|
30
|
-
// call disconnect() with the correct receiver.
|
|
31
|
-
setupResizeObserver(ctx) {
|
|
32
|
-
const rootNode = ctx.getRootNode?.() ?? env().getRootNode();
|
|
33
|
-
const queryRoot = resolveQueryRoot(rootNode, env().getDocument());
|
|
34
|
-
const viewportId = ctx.ids?.viewport ?? `scroll-area:${ctx.id}:viewport`;
|
|
35
|
-
const contentId = ctx.ids?.content ?? `scroll-area:${ctx.id}:content`;
|
|
36
|
-
const viewport = queryRoot.getElementById(viewportId);
|
|
37
|
-
const content = queryRoot.getElementById(contentId);
|
|
38
|
-
if (!viewport || !content)
|
|
39
|
-
return;
|
|
40
|
-
const updateDimensions = () => {
|
|
41
|
-
ctx.viewportWidth = viewport.clientWidth;
|
|
42
|
-
ctx.viewportHeight = viewport.clientHeight;
|
|
43
|
-
ctx.contentWidth = content.scrollWidth;
|
|
44
|
-
ctx.contentHeight = content.scrollHeight;
|
|
45
|
-
};
|
|
46
|
-
updateDimensions();
|
|
47
|
-
const resizeObserver = ref(new (env().getWindow().ResizeObserver)(updateDimensions));
|
|
48
|
-
resizeObserver.observe(viewport);
|
|
49
|
-
resizeObserver.observe(content);
|
|
50
|
-
ctx._resizeObserver = resizeObserver;
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
25
|
});
|
|
54
26
|
const api = $derived(scrollArea.connect(state, send, normalizeProps));
|
|
55
27
|
onMount(() => {
|
|
@@ -21,9 +21,13 @@
|
|
|
21
21
|
import { SelectProvider } from '../hooks/use-select-context'
|
|
22
22
|
import { useSelect } from '../hooks/use-select.svelte'
|
|
23
23
|
|
|
24
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
25
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
24
26
|
let {
|
|
25
27
|
value = $bindable<string[] | undefined>(),
|
|
28
|
+
value: valueProp,
|
|
26
29
|
open = $bindable<boolean | undefined>(),
|
|
30
|
+
open: openProp,
|
|
27
31
|
...props
|
|
28
32
|
}: SelectRootProps<T> = $props()
|
|
29
33
|
|
|
@@ -63,15 +67,15 @@
|
|
|
63
67
|
const machineProps = $derived.by<UseSelectProps<T>>(() => ({
|
|
64
68
|
...useSelectProps,
|
|
65
69
|
id: useSelectProps.id ?? providedId,
|
|
66
|
-
value,
|
|
70
|
+
value: valueProp,
|
|
67
71
|
onValueChange(details) {
|
|
68
72
|
value = details.value
|
|
69
73
|
useSelectProps.onValueChange?.(details)
|
|
70
74
|
},
|
|
71
|
-
open,
|
|
75
|
+
open: openProp,
|
|
72
76
|
onOpenChange(details) {
|
|
73
77
|
useSelectProps.onOpenChange?.(details)
|
|
74
|
-
|
|
78
|
+
open = details.open
|
|
75
79
|
},
|
|
76
80
|
}))
|
|
77
81
|
|
|
@@ -3,7 +3,7 @@ import type { PropTypes } from '@destyler/svelte';
|
|
|
3
3
|
import type { MaybeFunction } from '@destyler/utils';
|
|
4
4
|
import type { CollectionItem, ListCollection } from '../../collection/index.js';
|
|
5
5
|
import * as select from '@destyler/select';
|
|
6
|
-
export interface UseSelectProps<T extends CollectionItem> extends Omit<select.Context<T>, 'dir' | 'getRootNode' | 'collection' | '
|
|
6
|
+
export interface UseSelectProps<T extends CollectionItem> extends Omit<select.Context<T>, 'dir' | 'getRootNode' | 'collection' | 'id'> {
|
|
7
7
|
id: string;
|
|
8
8
|
defaultOpen?: select.Context<T>['open'];
|
|
9
9
|
defaultValue?: select.Context<T>['value'];
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
const props: SliderDraggingIndicatorProps = $props()
|
|
15
15
|
const slider = useSliderContext()
|
|
16
|
-
const
|
|
17
|
-
const mergedProps = $derived(mergeProps(slider().getDraggingIndicatorProps(
|
|
16
|
+
const thumbProps = useSliderThumbPropsContext()
|
|
17
|
+
const mergedProps = $derived(mergeProps(slider().getDraggingIndicatorProps(thumbProps), props))
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<UI as="span" {...mergedProps}>
|
|
21
21
|
{#if props.children}
|
|
22
22
|
{@render props.children()}
|
|
23
23
|
{:else}
|
|
24
|
-
{slider().getThumbValue(index)}
|
|
24
|
+
{slider().getThumbValue(thumbProps.index)}
|
|
25
25
|
{/if}
|
|
26
26
|
</UI>
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
import { SliderProvider } from '../hooks/use-slider-context'
|
|
14
14
|
import { useSlider } from '../hooks/use-slider.svelte'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
17
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
18
|
+
let {
|
|
19
|
+
value = $bindable(),
|
|
20
|
+
value: valueProp,
|
|
21
|
+
...props
|
|
22
|
+
}: SliderRootProps = $props()
|
|
17
23
|
const providedId = $props.id()
|
|
18
24
|
|
|
19
25
|
const [useSliderProps, localProps] = $derived(
|
|
@@ -47,7 +53,7 @@
|
|
|
47
53
|
const resolvedProps = $derived<UseSliderProps>({
|
|
48
54
|
...useSliderProps,
|
|
49
55
|
id: useSliderProps.id ?? providedId,
|
|
50
|
-
value,
|
|
56
|
+
value: valueProp,
|
|
51
57
|
onValueChange(details) {
|
|
52
58
|
value = details.value
|
|
53
59
|
useSliderProps.onValueChange?.(details)
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<script lang="ts">
|
|
12
|
-
import { untrack } from 'svelte'
|
|
13
12
|
import { SliderThumbPropsProvider } from '../hooks/use-slider-thumb-props-context'
|
|
14
13
|
|
|
15
14
|
const { value, children }: SliderThumbPropsProviderProps = $props()
|
|
16
|
-
SliderThumbPropsProvider(
|
|
15
|
+
SliderThumbPropsProvider({
|
|
16
|
+
get index() { return value.index },
|
|
17
|
+
get name() { return value.name },
|
|
18
|
+
})
|
|
17
19
|
</script>
|
|
18
20
|
|
|
19
21
|
{@render children?.()}
|