@destyler-ui/svelte 0.0.1-beta.17 → 0.0.1-beta.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/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
|
@@ -17,7 +17,14 @@
|
|
|
17
17
|
import { DialogProvider } from '../hooks/use-dialog-context'
|
|
18
18
|
import { useDialog } from '../hooks/use-dialog.svelte'
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
21
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
22
|
+
let {
|
|
23
|
+
open = $bindable(),
|
|
24
|
+
open: openProp,
|
|
25
|
+
children,
|
|
26
|
+
...props
|
|
27
|
+
}: DialogRootProps = $props()
|
|
21
28
|
|
|
22
29
|
const providedId = $props.id()
|
|
23
30
|
|
|
@@ -28,10 +35,10 @@
|
|
|
28
35
|
return {
|
|
29
36
|
...localProps,
|
|
30
37
|
id: localProps.id ?? providedId,
|
|
31
|
-
open,
|
|
38
|
+
open: openProp,
|
|
32
39
|
onOpenChange(details) {
|
|
33
40
|
localProps.onOpenChange?.(details)
|
|
34
|
-
|
|
41
|
+
open = details.open
|
|
35
42
|
},
|
|
36
43
|
}
|
|
37
44
|
})
|
|
@@ -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 dialog from '@destyler/dialog';
|
|
5
|
-
export interface UseDialogProps extends Omit<dialog.Context, 'getRootNode' | 'dir' | '
|
|
5
|
+
export interface UseDialogProps extends Omit<dialog.Context, 'getRootNode' | 'dir' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultOpen?: dialog.Context['open'];
|
|
8
8
|
}
|
|
@@ -13,7 +13,15 @@
|
|
|
13
13
|
import { DynamicProvider } from '../hooks/use-dynamic-context'
|
|
14
14
|
import { useDynamic } from '../hooks/use-dynamic.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<string[]>(),
|
|
20
|
+
value: valueProp,
|
|
21
|
+
inputValue = $bindable<string>(),
|
|
22
|
+
inputValue: inputValueProp,
|
|
23
|
+
...props
|
|
24
|
+
}: DynamicRootProps = $props()
|
|
17
25
|
|
|
18
26
|
const [useDynamicProps, localProps] = $derived(
|
|
19
27
|
createSplitProps<Optional<UseDynamicProps, 'id'>>()(props, [
|
|
@@ -54,8 +62,8 @@
|
|
|
54
62
|
return {
|
|
55
63
|
...useDynamicProps,
|
|
56
64
|
id: useDynamicProps.id ?? providedId,
|
|
57
|
-
value,
|
|
58
|
-
inputValue,
|
|
65
|
+
value: valueProp,
|
|
66
|
+
inputValue: inputValueProp,
|
|
59
67
|
onValueChange: (details) => {
|
|
60
68
|
useDynamicProps.onValueChange?.(details)
|
|
61
69
|
value = details.value
|
|
@@ -13,19 +13,32 @@ export function useDynamic(inProps) {
|
|
|
13
13
|
const env = useEnvironmentContext();
|
|
14
14
|
const locale = useLocaleContext();
|
|
15
15
|
const field = useFieldContext();
|
|
16
|
-
const machineProps = $derived.by(() =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
const machineProps = $derived.by(() => {
|
|
17
|
+
const { defaultValue, value, ...rest } = props;
|
|
18
|
+
const reactive = createMachineProps({
|
|
19
|
+
ids: {
|
|
20
|
+
label: field?.().ids.label,
|
|
21
|
+
hiddenInput: field?.().ids.control,
|
|
22
|
+
},
|
|
23
|
+
dir: locale().dir,
|
|
24
|
+
disabled: field?.().disabled,
|
|
25
|
+
invalid: field?.().invalid,
|
|
26
|
+
readOnly: field?.().readOnly,
|
|
27
|
+
required: field?.().required,
|
|
28
|
+
getRootNode: env().getRootNode,
|
|
29
|
+
...rest,
|
|
30
|
+
...(value !== undefined ? { value } : {}),
|
|
31
|
+
});
|
|
32
|
+
// @destyler/dynamic@0.2.7 stores value directly — seed defaults only once.
|
|
33
|
+
const initialValue = value !== undefined ? value : defaultValue;
|
|
34
|
+
return {
|
|
35
|
+
initial: {
|
|
36
|
+
...reactive.initial,
|
|
37
|
+
...(initialValue !== undefined ? { value: initialValue } : {}),
|
|
38
|
+
},
|
|
39
|
+
context: reactive.context,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
29
42
|
const [state, send] = useMachine(() => dynamic.machine(machineProps.initial), {
|
|
30
43
|
get context() {
|
|
31
44
|
return machineProps.context;
|
|
@@ -13,7 +13,15 @@
|
|
|
13
13
|
import { EditProvider } from '../hooks/use-edit-context'
|
|
14
14
|
import { useEdit } from '../hooks/use-edit.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
|
+
edit = $bindable(),
|
|
22
|
+
edit: editProp,
|
|
23
|
+
...props
|
|
24
|
+
}: EditRootProps = $props()
|
|
17
25
|
|
|
18
26
|
const providedId = $props.id()
|
|
19
27
|
|
|
@@ -23,16 +31,15 @@
|
|
|
23
31
|
return {
|
|
24
32
|
...useEditProps,
|
|
25
33
|
id: useEditProps.id ?? providedId,
|
|
26
|
-
value,
|
|
27
|
-
edit,
|
|
34
|
+
value: valueProp,
|
|
35
|
+
edit: editProp,
|
|
28
36
|
onValueChange(details) {
|
|
29
37
|
useEditProps.onValueChange?.(details)
|
|
30
38
|
value = details.value
|
|
31
39
|
},
|
|
32
40
|
onEditChange(details) {
|
|
33
41
|
useEditProps.onEditChange?.(details)
|
|
34
|
-
|
|
35
|
-
edit = details.edit
|
|
42
|
+
edit = details.edit
|
|
36
43
|
},
|
|
37
44
|
}
|
|
38
45
|
})
|
|
@@ -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 edit from '@destyler/edit';
|
|
5
|
-
export interface UseEditProps extends Omit<edit.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UseEditProps extends Omit<edit.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultEdit?: edit.Context['edit'];
|
|
8
8
|
defaultValue?: edit.Context['value'];
|
|
@@ -3,15 +3,21 @@ 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';
|
|
6
7
|
import * as edit from '@destyler/edit';
|
|
8
|
+
import { mergeProps } from '@destyler/svelte';
|
|
7
9
|
import { runIfFn } from '@destyler/utils';
|
|
10
|
+
import { untrack } from 'svelte';
|
|
8
11
|
import { useFieldContext } from '../../field/index.js';
|
|
9
12
|
export function useEdit(props) {
|
|
10
13
|
const env = useEnvironmentContext();
|
|
11
14
|
const locale = useLocaleContext();
|
|
12
15
|
const field = useFieldContext();
|
|
16
|
+
// Core has no defaultEdit. The UI owns this state and writes edit requests back
|
|
17
|
+
// to core, while an explicit live edit prop remains owned by the caller.
|
|
18
|
+
let localEdit = $state(untrack(() => runIfFn(props).defaultEdit ?? false));
|
|
13
19
|
const machineProps = $derived.by(() => {
|
|
14
|
-
const resolvedProps = runIfFn(props)
|
|
20
|
+
const { defaultEdit: _defaultEdit, edit: liveEdit, onEditChange, ...resolvedProps } = runIfFn(props);
|
|
15
21
|
return createMachineProps({
|
|
16
22
|
getRootNode: env().getRootNode,
|
|
17
23
|
dir: locale().dir,
|
|
@@ -24,13 +30,29 @@ export function useEdit(props) {
|
|
|
24
30
|
readOnly: field?.()?.readOnly,
|
|
25
31
|
required: field?.()?.required,
|
|
26
32
|
...resolvedProps,
|
|
27
|
-
|
|
33
|
+
edit: liveEdit !== undefined ? liveEdit : localEdit,
|
|
34
|
+
onEditChange(details) {
|
|
35
|
+
if (liveEdit === undefined)
|
|
36
|
+
localEdit = details.edit;
|
|
37
|
+
onEditChange?.(details);
|
|
38
|
+
},
|
|
39
|
+
}, { value: 'defaultValue' });
|
|
28
40
|
});
|
|
29
41
|
const [state, send] = useMachine(() => edit.machine(machineProps.initial), {
|
|
30
42
|
get context() {
|
|
31
43
|
return machineProps.context;
|
|
32
44
|
},
|
|
33
45
|
});
|
|
34
|
-
const
|
|
46
|
+
const connected = $derived(edit.connect(state, send, normalizeProps));
|
|
47
|
+
const syncInputValue = createInputValueSync(() => connected.getInputProps(), () => connected.value);
|
|
48
|
+
const api = $derived({
|
|
49
|
+
...connected,
|
|
50
|
+
getInputProps() {
|
|
51
|
+
return mergeProps(connected.getInputProps(), {
|
|
52
|
+
oninput: syncInputValue,
|
|
53
|
+
oncompositionend: syncInputValue,
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
});
|
|
35
57
|
return () => api;
|
|
36
58
|
}
|
|
@@ -18,7 +18,17 @@
|
|
|
18
18
|
import { FloatingPanelProvider } from '../hooks/use-floating-panel-context.js'
|
|
19
19
|
import { useFloatingPanel } from '../hooks/use-floating-panel.svelte.js'
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
22
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
23
|
+
let {
|
|
24
|
+
open = $bindable(),
|
|
25
|
+
open: openProp,
|
|
26
|
+
position = $bindable(),
|
|
27
|
+
position: positionProp,
|
|
28
|
+
size = $bindable(),
|
|
29
|
+
size: sizeProp,
|
|
30
|
+
...props
|
|
31
|
+
}: FloatingPanelRootProps = $props()
|
|
22
32
|
const providedId = $props.id()
|
|
23
33
|
|
|
24
34
|
const [presenceProps, otherProps] = $derived(splitPresenceProps(props))
|
|
@@ -53,20 +63,20 @@
|
|
|
53
63
|
const resolvedProps = $derived<UseFloatingPanelProps>({
|
|
54
64
|
...floatingPanelProps,
|
|
55
65
|
id: floatingPanelProps.id ?? providedId,
|
|
56
|
-
open,
|
|
66
|
+
open: openProp,
|
|
57
67
|
onOpenChange(details) {
|
|
58
68
|
floatingPanelProps.onOpenChange?.(details)
|
|
59
|
-
|
|
69
|
+
open = details.open
|
|
60
70
|
},
|
|
61
|
-
position,
|
|
71
|
+
position: positionProp,
|
|
62
72
|
onPositionChange(details) {
|
|
63
73
|
floatingPanelProps.onPositionChange?.(details)
|
|
64
|
-
|
|
74
|
+
position = details.position
|
|
65
75
|
},
|
|
66
|
-
size,
|
|
76
|
+
size: sizeProp,
|
|
67
77
|
onSizeChange(details) {
|
|
68
78
|
floatingPanelProps.onSizeChange?.(details)
|
|
69
|
-
|
|
79
|
+
size = details.size
|
|
70
80
|
},
|
|
71
81
|
})
|
|
72
82
|
|
|
@@ -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 floatingPanel from '@destyler/floating-panel';
|
|
5
|
-
export interface UseFloatingPanelProps extends Omit<floatingPanel.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UseFloatingPanelProps extends Omit<floatingPanel.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultOpen?: floatingPanel.Context['open'];
|
|
8
8
|
}
|
|
@@ -21,10 +21,5 @@ export function useFloatingPanel(props) {
|
|
|
21
21
|
},
|
|
22
22
|
});
|
|
23
23
|
const api = $derived(floatingPanel.connect(state, send, normalizeProps));
|
|
24
|
-
$effect(() => {
|
|
25
|
-
const open = runIfFn(props).open;
|
|
26
|
-
if (open !== undefined && open !== api.open)
|
|
27
|
-
api.setOpen(open);
|
|
28
|
-
});
|
|
29
24
|
return () => api;
|
|
30
25
|
}
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
import { HoverCardProvider } from '../hooks/use-hover-card-context'
|
|
17
17
|
import { useHoverCard } from '../hooks/use-hover-card.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<boolean>(),
|
|
23
|
+
open: openProp,
|
|
24
|
+
...props
|
|
25
|
+
}: HoverCardRootProps = $props()
|
|
20
26
|
const providedId = $props.id()
|
|
21
27
|
|
|
22
28
|
const [presenceProps, localProps] = $derived(splitPresenceProps(props))
|
|
@@ -24,10 +30,10 @@
|
|
|
24
30
|
const resolvedProps = $derived<UseHoverCardProps>({
|
|
25
31
|
...localProps,
|
|
26
32
|
id: localProps.id ?? providedId,
|
|
27
|
-
open,
|
|
33
|
+
open: openProp,
|
|
28
34
|
onOpenChange(details) {
|
|
29
35
|
localProps.onOpenChange?.(details)
|
|
30
|
-
|
|
36
|
+
open = details.open
|
|
31
37
|
},
|
|
32
38
|
})
|
|
33
39
|
|
|
@@ -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 hoverCard from '@destyler/hover-card';
|
|
5
|
-
export interface UseHoverCardProps extends Omit<hoverCard.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UseHoverCardProps extends Omit<hoverCard.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultOpen?: hoverCard.Context['open'];
|
|
8
8
|
}
|
|
@@ -17,7 +17,13 @@
|
|
|
17
17
|
import { MenuItemProvider } from '../hooks/use-menu-item-context'
|
|
18
18
|
import { MenuItemPropsProvider } from '../hooks/use-menu-option-item-props-context'
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
21
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
22
|
+
let {
|
|
23
|
+
checked = $bindable<boolean>(),
|
|
24
|
+
checked: checkedProp,
|
|
25
|
+
...props
|
|
26
|
+
}: MenuCheckboxItemProps = $props()
|
|
21
27
|
|
|
22
28
|
const [partialOptionItemProps, localProps] = $derived(
|
|
23
29
|
createSplitProps<CheckboxMachineProps>()(props, [
|
|
@@ -32,9 +38,9 @@
|
|
|
32
38
|
const optionItemProps = $derived<OptionItemProps>({
|
|
33
39
|
...partialOptionItemProps,
|
|
34
40
|
type: 'checkbox',
|
|
35
|
-
checked,
|
|
41
|
+
checked: checkedProp,
|
|
36
42
|
onCheckedChange(nextChecked) {
|
|
37
|
-
|
|
43
|
+
checked = nextChecked
|
|
38
44
|
partialOptionItemProps.onCheckedChange?.(nextChecked)
|
|
39
45
|
},
|
|
40
46
|
})
|
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
import { useRequiredMenuContext } from '../hooks/use-menu-context'
|
|
15
15
|
import { MenuItemGroupProvider, type ValueChangeDetails } from '../hooks/use-menu-item-group-context'
|
|
16
16
|
|
|
17
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
18
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
17
19
|
let {
|
|
18
20
|
id: providedId,
|
|
19
21
|
value = $bindable<string>(),
|
|
22
|
+
value: valueProp,
|
|
20
23
|
onValueChange,
|
|
21
24
|
...localProps
|
|
22
25
|
}: MenuRadioItemGroupProps = $props()
|
|
@@ -25,9 +28,9 @@
|
|
|
25
28
|
const menu = useRequiredMenuContext()
|
|
26
29
|
const itemGroupProps = $derived({
|
|
27
30
|
id: providedId ?? generatedId,
|
|
28
|
-
value,
|
|
31
|
+
value: valueProp,
|
|
29
32
|
onValueChange(details: ValueChangeDetails) {
|
|
30
|
-
|
|
33
|
+
value = details.value
|
|
31
34
|
onValueChange?.(details)
|
|
32
35
|
},
|
|
33
36
|
})
|
|
@@ -19,7 +19,13 @@
|
|
|
19
19
|
import { MenuTriggerItemProvider } from '../hooks/use-menu-trigger-item-context'
|
|
20
20
|
import { useMenu } from '../hooks/use-menu.svelte'
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
23
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
24
|
+
let {
|
|
25
|
+
open = $bindable<boolean>(),
|
|
26
|
+
open: openProp,
|
|
27
|
+
...props
|
|
28
|
+
}: MenuRootProps = $props()
|
|
23
29
|
const providedId = $props.id()
|
|
24
30
|
|
|
25
31
|
const [presenceProps, menuProps] = $derived(splitPresenceProps(props))
|
|
@@ -54,10 +60,10 @@
|
|
|
54
60
|
const resolvedProps = $derived<UseMenuProps>({
|
|
55
61
|
...useMenuProps,
|
|
56
62
|
id: useMenuProps.id ?? providedId,
|
|
57
|
-
open,
|
|
63
|
+
open: openProp,
|
|
58
64
|
onOpenChange(details) {
|
|
59
65
|
useMenuProps.onOpenChange?.(details)
|
|
60
|
-
|
|
66
|
+
open = details.open
|
|
61
67
|
},
|
|
62
68
|
})
|
|
63
69
|
|
|
@@ -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 menu from '@destyler/menu';
|
|
5
|
-
export interface UseMenuProps extends Omit<menu.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UseMenuProps extends Omit<menu.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
7
|
defaultOpen?: menu.Context['open'];
|
|
8
8
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { PresenceProvider, splitPresenceProps, usePresence } from '../../presence'
|
|
17
17
|
import { createSplitProps } from '../../../utils/create-split-props'
|
|
18
18
|
|
|
19
|
-
let { ref = $bindable(null), value = $bindable(), ...props }: NavigationMenuRootProps = $props()
|
|
19
|
+
let { ref = $bindable(null), value: valueProp, value = $bindable(), ...props }: NavigationMenuRootProps = $props()
|
|
20
20
|
|
|
21
21
|
const providedId = $props.id()
|
|
22
22
|
const splitRootProps = createSplitProps<Optional<UseNavigationMenuProps, 'id'>>()
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
const machineProps = $derived<UseNavigationMenuProps>({
|
|
42
42
|
...useNavigationMenuProps,
|
|
43
43
|
id: useNavigationMenuProps.id ?? providedId,
|
|
44
|
-
value,
|
|
44
|
+
value: valueProp,
|
|
45
45
|
onValueChange(details) {
|
|
46
46
|
useNavigationMenuProps.onValueChange?.(details)
|
|
47
|
-
|
|
47
|
+
value = details.value
|
|
48
48
|
},
|
|
49
49
|
})
|
|
50
50
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PropTypes } from '@destyler/svelte';
|
|
2
|
+
import * as navigationMenu from '@destyler/navigation-menu';
|
|
3
|
+
type ConnectParameters = Parameters<typeof navigationMenu.connect<PropTypes>>;
|
|
4
|
+
/**
|
|
5
|
+
* Core 0.2.7 reads the trigger DOM to calculate content motion during render.
|
|
6
|
+
* Before mount (including hydration), return the same static content contract
|
|
7
|
+
* without a layout query. Keep the real core API for all mounted behavior.
|
|
8
|
+
*/
|
|
9
|
+
export declare function connectNavigationMenu(state: ConnectParameters[0], send: ConnectParameters[1], mounted: boolean): navigationMenu.Api<PropTypes>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { normalizeProps } from '../../../utils/normalize-props.js';
|
|
2
|
+
import * as navigationMenu from '@destyler/navigation-menu';
|
|
3
|
+
/**
|
|
4
|
+
* Core 0.2.7 reads the trigger DOM to calculate content motion during render.
|
|
5
|
+
* Before mount (including hydration), return the same static content contract
|
|
6
|
+
* without a layout query. Keep the real core API for all mounted behavior.
|
|
7
|
+
*/
|
|
8
|
+
export function connectNavigationMenu(state, send, mounted) {
|
|
9
|
+
const api = navigationMenu.connect(state, send, normalizeProps);
|
|
10
|
+
if (mounted)
|
|
11
|
+
return api;
|
|
12
|
+
const getContentState = props => ({
|
|
13
|
+
open: api.value === props.value,
|
|
14
|
+
motion: undefined,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
...api,
|
|
18
|
+
getContentState,
|
|
19
|
+
getContentProps(props) {
|
|
20
|
+
const { value } = props;
|
|
21
|
+
const { open } = getContentState(props);
|
|
22
|
+
return normalizeProps.element({
|
|
23
|
+
...navigationMenu.anatomy.build().content.attrs,
|
|
24
|
+
'id': state.context.ids?.content?.(value) ?? `nav-menu:${state.context.id}:content:${value}`,
|
|
25
|
+
'dir': state.context.dir,
|
|
26
|
+
'hidden': !open,
|
|
27
|
+
'data-state': open ? 'open' : 'closed',
|
|
28
|
+
'data-motion': undefined,
|
|
29
|
+
'data-value': value,
|
|
30
|
+
'data-orientation': state.context.orientation,
|
|
31
|
+
onPointerEnter(event) {
|
|
32
|
+
if (event.pointerType === 'mouse')
|
|
33
|
+
send({ type: 'CONTENT_ENTER', value });
|
|
34
|
+
},
|
|
35
|
+
onPointerLeave(event) {
|
|
36
|
+
if (event.pointerType === 'mouse')
|
|
37
|
+
send({ type: 'CONTENT_LEAVE', value });
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -2,9 +2,8 @@ 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 navigationMenu from '@destyler/navigation-menu';
|
|
5
|
-
export interface UseNavigationMenuProps extends Omit<navigationMenu.Context, 'dir' | 'getRootNode' | '
|
|
5
|
+
export interface UseNavigationMenuProps extends Omit<navigationMenu.Context, 'dir' | 'getRootNode' | 'id'> {
|
|
6
6
|
id: string;
|
|
7
|
-
defaultValue?: string;
|
|
8
7
|
}
|
|
9
8
|
export interface UseNavigationMenuReturn extends Accessor<navigationMenu.Api<PropTypes>> {
|
|
10
9
|
}
|
|
@@ -1,42 +1,32 @@
|
|
|
1
1
|
import { useMachine } from '../../../hooks/use-destyler-machine.svelte.js';
|
|
2
2
|
import { useEnvironmentContext } from '../../../providers/environment/index.js';
|
|
3
3
|
import { useLocaleContext } from '../../../providers/locale/index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createMachineProps } from '../../../utils/create-machine-props.js';
|
|
5
5
|
import * as navigationMenu from '@destyler/navigation-menu';
|
|
6
6
|
import { runIfFn } from '@destyler/utils';
|
|
7
|
+
import { connectNavigationMenu } from './connect-navigation-menu.js';
|
|
7
8
|
export function useNavigationMenu(props) {
|
|
9
|
+
let mounted = $state(false);
|
|
10
|
+
$effect(() => {
|
|
11
|
+
mounted = true;
|
|
12
|
+
});
|
|
8
13
|
const env = useEnvironmentContext();
|
|
9
14
|
const locale = useLocaleContext();
|
|
10
15
|
const machineProps = $derived.by(() => {
|
|
11
16
|
const resolvedProps = runIfFn(props) || {};
|
|
12
|
-
|
|
17
|
+
return createMachineProps({
|
|
13
18
|
dir: locale().dir,
|
|
14
19
|
getRootNode: env().getRootNode,
|
|
15
20
|
...resolvedProps,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const initialDefaultValue = controlled ? (resolvedProps.value ?? undefined) : resolvedProps.defaultValue;
|
|
20
|
-
return {
|
|
21
|
-
initial: {
|
|
22
|
-
...baseProps,
|
|
23
|
-
'defaultValue': initialDefaultValue,
|
|
24
|
-
'value': initialValue,
|
|
25
|
-
'value.controlled': controlled,
|
|
26
|
-
},
|
|
27
|
-
context: {
|
|
28
|
-
...baseProps,
|
|
29
|
-
'defaultValue': initialDefaultValue,
|
|
30
|
-
'value': resolvedProps.value,
|
|
31
|
-
'value.controlled': controlled,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
21
|
+
// null explicitly closes the menu; only undefined permits the default seed.
|
|
22
|
+
defaultValue: resolvedProps.value !== undefined ? undefined : resolvedProps.defaultValue,
|
|
23
|
+
});
|
|
34
24
|
});
|
|
35
25
|
const [state, send] = useMachine(() => navigationMenu.machine(machineProps.initial), {
|
|
36
26
|
get context() {
|
|
37
27
|
return machineProps.context;
|
|
38
28
|
},
|
|
39
29
|
});
|
|
40
|
-
const api = $derived(
|
|
30
|
+
const api = $derived(connectNavigationMenu(state, send, mounted));
|
|
41
31
|
return () => api;
|
|
42
32
|
}
|
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
import { splitNumberInputProps } from '../hooks/split-number-input-props.svelte'
|
|
16
16
|
import { useNumberInput } from '../hooks/use-number-input.svelte'
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
// Read the parent prop independently from the writable binding. Local writes
|
|
19
|
+
// notify bind: consumers without overriding ordinary controlled props.
|
|
20
|
+
let {
|
|
21
|
+
value = $bindable(),
|
|
22
|
+
value: valueProp,
|
|
23
|
+
...props
|
|
24
|
+
}: NumberInputRootProps = $props()
|
|
19
25
|
const providedId = $props.id()
|
|
20
26
|
|
|
21
27
|
const [useNumberInputProps, localProps] = $derived(splitNumberInputProps(props))
|
|
@@ -23,7 +29,7 @@
|
|
|
23
29
|
const resolvedProps = $derived<UseNumberInputProps>({
|
|
24
30
|
...useNumberInputProps,
|
|
25
31
|
id: useNumberInputProps.id ?? providedId,
|
|
26
|
-
value,
|
|
32
|
+
value: valueProp,
|
|
27
33
|
onValueChange(details) {
|
|
28
34
|
useNumberInputProps.onValueChange?.(details)
|
|
29
35
|
value = details.value
|