@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.
Files changed (97) hide show
  1. package/README.md +7 -1
  2. package/dist/components/aspect-ratio/components/Root.svelte +1 -2
  3. package/dist/components/aspect-ratio/hooks/use-aspect-ratio.svelte.d.ts +0 -1
  4. package/dist/components/aspect-ratio/hooks/use-aspect-ratio.svelte.js +1 -1
  5. package/dist/components/calendar/anatomy.d.ts +1 -1
  6. package/dist/components/calendar/components/Content.d.svelte.ts +1 -1
  7. package/dist/components/calendar/components/Content.svelte +2 -3
  8. package/dist/components/calendar/components/Content.svelte.d.ts +1 -1
  9. package/dist/components/calendar/components/Root.svelte +14 -8
  10. package/dist/components/calendar/hooks/use-calendar.svelte.d.ts +1 -1
  11. package/dist/components/calendar/hooks/use-calendar.svelte.js +13 -3
  12. package/dist/components/carousel/components/Root.svelte +9 -3
  13. package/dist/components/checkbox/components/Group.svelte +8 -2
  14. package/dist/components/checkbox/components/Root.svelte +8 -2
  15. package/dist/components/checkbox/hooks/use-checkbox-group.svelte.d.ts +17 -7
  16. package/dist/components/checkbox/hooks/use-checkbox-group.svelte.js +7 -4
  17. package/dist/components/checkbox/hooks/use-checkbox.svelte.js +14 -2
  18. package/dist/components/collapse/components/Root.svelte +9 -3
  19. package/dist/components/collapsible/components/Root.svelte +9 -3
  20. package/dist/components/collapsible/hooks/split-collapsible-props.svelte.d.ts +1 -1
  21. package/dist/components/collapsible/hooks/use-collapsible.svelte.d.ts +1 -1
  22. package/dist/components/color-picker/anatomy.d.ts +1 -1
  23. package/dist/components/color-picker/components/ChannelInput.svelte +9 -1
  24. package/dist/components/color-picker/components/Root.svelte +12 -4
  25. package/dist/components/color-picker/hooks/split-color-picker-props.svelte.d.ts +1 -1
  26. package/dist/components/color-picker/hooks/use-color-picker.svelte.d.ts +1 -1
  27. package/dist/components/combobox/components/Content.svelte +4 -7
  28. package/dist/components/combobox/components/Root.svelte +12 -6
  29. package/dist/components/combobox/hooks/use-combobox.svelte.d.ts +1 -1
  30. package/dist/components/combobox/hooks/use-combobox.svelte.js +13 -1
  31. package/dist/components/dialog/components/Root.svelte +10 -3
  32. package/dist/components/dialog/hooks/use-dialog.svelte.d.ts +1 -1
  33. package/dist/components/dynamic/components/Root.svelte +11 -3
  34. package/dist/components/dynamic/hooks/use-dynamic.svelte.js +26 -13
  35. package/dist/components/edit/components/Root.svelte +12 -5
  36. package/dist/components/edit/hooks/use-edit.svelte.d.ts +1 -1
  37. package/dist/components/edit/hooks/use-edit.svelte.js +25 -3
  38. package/dist/components/floating-panel/components/Root.svelte +17 -7
  39. package/dist/components/floating-panel/hooks/use-floating-panel.svelte.d.ts +1 -1
  40. package/dist/components/floating-panel/hooks/use-floating-panel.svelte.js +0 -5
  41. package/dist/components/hover-card/components/Root.svelte +9 -3
  42. package/dist/components/hover-card/hooks/use-hover-card.svelte.d.ts +1 -1
  43. package/dist/components/menu/components/CheckboxItem.svelte +9 -3
  44. package/dist/components/menu/components/RadioItemGroup.svelte +5 -2
  45. package/dist/components/menu/components/Root.svelte +9 -3
  46. package/dist/components/menu/hooks/use-menu.svelte.d.ts +1 -1
  47. package/dist/components/navigation-menu/components/Root.svelte +3 -3
  48. package/dist/components/navigation-menu/hooks/connect-navigation-menu.d.ts +10 -0
  49. package/dist/components/navigation-menu/hooks/connect-navigation-menu.js +42 -0
  50. package/dist/components/navigation-menu/hooks/use-navigation-menu.svelte.d.ts +1 -2
  51. package/dist/components/navigation-menu/hooks/use-navigation-menu.svelte.js +11 -21
  52. package/dist/components/number-input/components/Root.svelte +8 -2
  53. package/dist/components/number-input/hooks/use-number-input.svelte.js +183 -2
  54. package/dist/components/otp-input/components/Input.svelte +6 -1
  55. package/dist/components/otp-input/components/Root.svelte +8 -2
  56. package/dist/components/pagination/components/Root.svelte +14 -5
  57. package/dist/components/popover/components/Root.svelte +10 -3
  58. package/dist/components/popover/hooks/use-popover.svelte.d.ts +1 -1
  59. package/dist/components/presence/components/Presence.svelte +6 -0
  60. package/dist/components/progress/components/Root.svelte +8 -2
  61. package/dist/components/progress/hooks/use-progress.svelte.js +17 -3
  62. package/dist/components/qr-code/components/Root.svelte +8 -2
  63. package/dist/components/qr-code/hooks/use-qr-code.svelte.js +14 -4
  64. package/dist/components/radio/components/Root.svelte +9 -3
  65. package/dist/components/radio/hooks/use-radio.svelte.js +10 -1
  66. package/dist/components/scroll-area/hooks/use-scroll-area.svelte.js +0 -28
  67. package/dist/components/select/components/Root.svelte +7 -3
  68. package/dist/components/select/hooks/use-select.svelte.d.ts +1 -1
  69. package/dist/components/slider/components/DraggingIndicator.svelte +3 -3
  70. package/dist/components/slider/components/Root.svelte +8 -2
  71. package/dist/components/slider/components/ThumbPropsProvider.svelte +4 -2
  72. package/dist/components/splitter/components/Root.svelte +9 -3
  73. package/dist/components/steps/components/Root.svelte +9 -3
  74. package/dist/components/steps/hooks/split-steps-props.svelte.d.ts +1 -1
  75. package/dist/components/switch/components/Root.svelte +9 -3
  76. package/dist/components/switch/hooks/use-switch.svelte.d.ts +12 -1
  77. package/dist/components/switch/hooks/use-switch.svelte.js +10 -1
  78. package/dist/components/tabs/components/Root.svelte +9 -3
  79. package/dist/components/toggle/components/Root.svelte +8 -2
  80. package/dist/components/toggle-group/components/Root.svelte +9 -3
  81. package/dist/components/tooltip/components/Root.svelte +9 -3
  82. package/dist/components/tooltip/hooks/use-tooltip.svelte.d.ts +1 -1
  83. package/dist/components/tree/components/BranchTrigger.d.svelte.ts +2 -2
  84. package/dist/components/tree/components/BranchTrigger.svelte +3 -3
  85. package/dist/components/tree/components/BranchTrigger.svelte.d.ts +2 -2
  86. package/dist/components/tree/components/Root.svelte +8 -3
  87. package/dist/components/tree/hooks/tree-split-props.d.ts +1 -1
  88. package/dist/providers/frame/components/Content.svelte +4 -1
  89. package/dist/utils/create-machine-props.d.ts +18 -7
  90. package/dist/utils/create-machine-props.js +22 -18
  91. package/dist/utils/sync-checked.d.ts +6 -0
  92. package/dist/utils/sync-checked.js +28 -0
  93. package/dist/utils/sync-input-value.d.ts +4 -0
  94. package/dist/utils/sync-input-value.js +27 -0
  95. package/dist/utils/sync-number-input.d.ts +2 -0
  96. package/dist/utils/sync-number-input.js +45 -0
  97. package/package.json +72 -68
package/README.md CHANGED
@@ -52,4 +52,10 @@ import { Checkbox as CheckboxFromSubpath } from '@destyler-ui/svelte/checkbox'
52
52
 
53
53
  Runtime helpers are exported from the root package and dedicated subpaths, including `ClientOnly`, `EnvironmentProvider`, `FocusTrap`, `Format`, `Frame`, `Highlight`, and `LocaleProvider`.
54
54
 
55
- See the [Destyler UI documentation](https://ui.destyler.dev/overview/getting-started/) for component examples, API tables, and provider guides.
55
+ See the [Destyler UI documentation](https://ui.destyler.org/overview/getting-started/) for component examples, API tables, and provider guides.
56
+
57
+ ## Tree branch triggers
58
+
59
+ `Tree.BranchTrigger` now renders a `div` with `role="button"`, matching the other frameworks. Inside `Tree.BranchControl`, it handles pointer expansion while the branch control owns keyboard navigation and the tree's roving tab stop.
60
+
61
+ Its public props and event `currentTarget` types now describe `HTMLDivElement`. Consumers that previously relied on the native button default or button-only attributes must use explicit `asChild` composition and adapt the snippet props to their chosen element's types. Caller overrides are preserved; adding a focusable child or `tabindex` remains the caller's accessibility responsibility and can introduce extra tab stops or nested interactive controls.
@@ -13,14 +13,13 @@
13
13
  import { AspectRatioProvider } from '../hooks/use-aspect-ratio-context'
14
14
  import { useAspectRatio } from '../hooks/use-aspect-ratio.svelte'
15
15
 
16
- let { defaultRatio, ...props }: AspectRatioRootProps = $props()
16
+ let { ...props }: AspectRatioRootProps = $props()
17
17
  const providedId = $props.id()
18
18
 
19
19
  const [machineProps, localProps] = $derived(aspectRatioMachine.splitProps(props))
20
20
  const resolvedProps = $derived<UseAspectRatioProps>({
21
21
  ...machineProps,
22
22
  id: machineProps.id ?? providedId,
23
- defaultRatio,
24
23
  })
25
24
  const aspectRatio = useAspectRatio(() => resolvedProps)
26
25
  const mergedProps = $derived(mergeProps(aspectRatio().getRootProps(), localProps))
@@ -4,7 +4,6 @@ import type { MaybeFunction } from '@destyler/utils';
4
4
  import * as aspectRatio from '@destyler/aspect-ratio';
5
5
  export interface UseAspectRatioProps extends Omit<aspectRatio.Context, 'getRootNode' | 'id'> {
6
6
  id: string;
7
- defaultRatio?: aspectRatio.Context['ratio'];
8
7
  }
9
8
  export interface UseAspectRatioReturn extends Accessor<aspectRatio.Api<PropTypes>> {
10
9
  }
@@ -11,7 +11,7 @@ export function useAspectRatio(props) {
11
11
  return createMachineProps({
12
12
  getRootNode: env().getRootNode,
13
13
  ...resolved,
14
- }, { ratio: 'defaultRatio' });
14
+ });
15
15
  });
16
16
  const [state, send] = useMachine(() => aspectRatio.machine(machineProps.initial), {
17
17
  get context() {
@@ -1 +1 @@
1
- export declare const calendarAnatomy: import("@destyler/anatomy").AnatomyInstance<"input" | "label" | "table" | "view" | "root" | "content" | "tableHeader" | "tableBody" | "tableRow" | "prevTrigger" | "nextTrigger" | "viewTrigger" | "clearTrigger" | "control" | "trigger" | "monthSelect" | "yearSelect" | "positioner" | "rangeText" | "tableCell" | "tableCellTrigger" | "tableHead" | "viewControl" | "presetTrigger">;
1
+ export declare const calendarAnatomy: import("@destyler/anatomy").AnatomyInstance<"input" | "label" | "table" | "view" | "root" | "content" | "clearTrigger" | "control" | "monthSelect" | "nextTrigger" | "positioner" | "prevTrigger" | "rangeText" | "tableBody" | "tableCell" | "tableCellTrigger" | "tableHead" | "tableHeader" | "tableRow" | "trigger" | "viewTrigger" | "viewControl" | "yearSelect" | "presetTrigger">;
@@ -3,6 +3,6 @@ export interface CalendarContentBaseProps extends PolymorphicProps<'div'>, RefAt
3
3
  }
4
4
  export interface CalendarContentProps extends Assign<HTMLProps<'div'>, CalendarContentBaseProps> {
5
5
  }
6
- declare const Content: import("svelte").Component<CalendarContentProps, {}, "">;
6
+ declare const Content: import("svelte").Component<CalendarContentProps, {}, "ref">;
7
7
  type Content = ReturnType<typeof Content>;
8
8
  export default Content;
@@ -12,7 +12,7 @@
12
12
  import { useCalendarContext } from '../hooks/use-calendar-context.js'
13
13
  import { usePresenceContext } from '../../presence/index.js'
14
14
 
15
- let { ref, ...props }: CalendarContentProps = $props()
15
+ let { ref = $bindable(), ...props }: CalendarContentProps = $props()
16
16
 
17
17
  const calendar = useCalendarContext()
18
18
  const presence = usePresenceContext()
@@ -20,10 +20,9 @@
20
20
 
21
21
  function setNode(node: HTMLElement) {
22
22
  untrack(() => presence().setNode(node))
23
- ref = node
24
23
  }
25
24
  </script>
26
25
 
27
26
  {#if !presence().unmounted}
28
- <UI as="div" {...mergedProps} {@attach setNode} />
27
+ <UI as="div" {...mergedProps} bind:ref={() => ref ?? null, (node) => ref = node} {@attach setNode} />
29
28
  {/if}
@@ -3,6 +3,6 @@ export interface CalendarContentBaseProps extends PolymorphicProps<'div'>, RefAt
3
3
  }
4
4
  export interface CalendarContentProps extends Assign<HTMLProps<'div'>, CalendarContentBaseProps> {
5
5
  }
6
- declare const Content: import("svelte").Component<CalendarContentProps, {}, "">;
6
+ declare const Content: import("svelte").Component<CalendarContentProps, {}, "ref">;
7
7
  type Content = ReturnType<typeof Content>;
8
8
  export default Content;
@@ -18,11 +18,17 @@
18
18
  import { useCalendar } from '../hooks/use-calendar.svelte.js'
19
19
  import { CalendarProvider } from '../hooks/use-calendar-context.js'
20
20
 
21
+ // Read the parent prop independently from the writable binding. Local writes
22
+ // notify bind: consumers without overriding ordinary controlled props.
21
23
  let {
22
24
  value = $bindable(),
25
+ value: valueProp,
23
26
  focusedValue = $bindable(),
27
+ focusedValue: focusedValueProp,
24
28
  open = $bindable(),
29
+ open: openProp,
25
30
  view = $bindable(),
31
+ view: viewProp,
26
32
  ...props
27
33
  }: CalendarRootProps = $props()
28
34
  const providedId = $props.id()
@@ -69,25 +75,25 @@
69
75
  const resolvedProps = $derived<UseCalendarProps>({
70
76
  ...useCalendarProps,
71
77
  id: useCalendarProps.id ?? providedId,
72
- value,
78
+ value: valueProp,
73
79
  onValueChange(details) {
74
80
  useCalendarProps.onValueChange?.(details)
75
- if (value !== undefined) value = details.value
81
+ value = details.value
76
82
  },
77
- focusedValue,
83
+ focusedValue: focusedValueProp,
78
84
  onFocusChange(details) {
79
85
  useCalendarProps.onFocusChange?.(details)
80
- if (focusedValue !== undefined) focusedValue = details.focusedValue
86
+ focusedValue = details.focusedValue
81
87
  },
82
- open,
88
+ open: openProp,
83
89
  onOpenChange(details) {
84
90
  useCalendarProps.onOpenChange?.(details)
85
- if (open !== undefined) open = details.open
91
+ open = details.open
86
92
  },
87
- view,
93
+ view: viewProp,
88
94
  onViewChange(details) {
89
95
  useCalendarProps.onViewChange?.(details)
90
- if (view !== undefined) view = details.view
96
+ view = details.view
91
97
  },
92
98
  })
93
99
 
@@ -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 calendar from '@destyler/calendar';
5
- export interface UseCalendarProps extends Omit<calendar.Context, 'dir' | 'getRootNode' | 'open.controlled' | 'id'> {
5
+ export interface UseCalendarProps extends Omit<calendar.Context, 'dir' | 'getRootNode' | 'id'> {
6
6
  id: string;
7
7
  defaultOpen?: calendar.Context['open'];
8
8
  defaultValue?: calendar.Context['value'];
@@ -8,13 +8,23 @@ export function useCalendar(props) {
8
8
  const env = useEnvironmentContext();
9
9
  const locale = useLocaleContext();
10
10
  const machineProps = $derived.by(() => {
11
- const resolvedProps = runIfFn(props);
12
- return createMachineProps({
11
+ const { defaultView, view, ...resolvedProps } = runIfFn(props);
12
+ const reactive = createMachineProps({
13
13
  dir: locale().dir,
14
14
  locale: locale().locale,
15
15
  getRootNode: env().getRootNode,
16
16
  ...resolvedProps,
17
- }, { open: 'defaultOpen', value: 'defaultValue', view: 'defaultView' }, ['open']);
17
+ ...(view !== undefined ? { view } : {}),
18
+ }, { open: 'defaultOpen', value: 'defaultValue' }, ['open']);
19
+ // Core has no defaultView. Only the machine's initial context gets this seed.
20
+ const initialView = view !== undefined ? view : defaultView;
21
+ return {
22
+ initial: {
23
+ ...reactive.initial,
24
+ ...(initialView !== undefined ? { view: initialView } : {}),
25
+ },
26
+ context: reactive.context,
27
+ };
18
28
  });
19
29
  const [state, send] = useMachine(() => calendar.machine(machineProps.initial), {
20
30
  get context() {
@@ -13,7 +13,13 @@
13
13
  import { CarouselProvider } from '../hooks/use-carousel-context'
14
14
  import { createSplitProps } from '../../../utils/create-split-props'
15
15
 
16
- let { page = $bindable(), ...props }: CarouselRootProps = $props()
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
+ ...props
22
+ }: CarouselRootProps = $props()
17
23
  const providedId = $props.id()
18
24
 
19
25
  const [useCarouselProps, localProps] = $derived(
@@ -43,10 +49,10 @@
43
49
  const resolvedProps = $derived<UseCarouselProps>({
44
50
  ...useCarouselProps,
45
51
  id: useCarouselProps.id ?? providedId,
46
- page,
52
+ page: pageProp,
47
53
  onPageChange(details) {
48
54
  useCarouselProps.onPageChange?.(details)
49
- if (page !== undefined) page = details.page
55
+ page = details.page
50
56
  },
51
57
  })
52
58
 
@@ -13,13 +13,19 @@
13
13
  import { splitCheckboxGroupProps } from '../hooks/split-checkbox-group-props.svelte'
14
14
  import { useCheckboxGroup } from '../hooks/use-checkbox-group.svelte'
15
15
 
16
- let { value = $bindable(), ...props }: CheckboxGroupProps = $props()
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
+ }: CheckboxGroupProps = $props()
17
23
 
18
24
  const [checkboxGroupProps, localProps] = $derived(splitCheckboxGroupProps(props))
19
25
 
20
26
  const resolvedProps = $derived<UseCheckboxGroupProps>({
21
27
  ...checkboxGroupProps,
22
- value,
28
+ value: valueProp,
23
29
  onValueChange(newValue) {
24
30
  checkboxGroupProps.onValueChange?.(newValue)
25
31
  value = newValue
@@ -13,7 +13,13 @@
13
13
  import { splitCheckboxProps } from '../hooks/split-checkbox-props.svelte'
14
14
  import { useCheckbox } from '../hooks/use-checkbox.svelte'
15
15
 
16
- let { checked = $bindable(), ...props }: CheckboxRootProps = $props()
16
+ // Read the parent prop independently from the writable binding. Local writes
17
+ // notify bind: consumers without overriding ordinary controlled props.
18
+ let {
19
+ checked = $bindable(),
20
+ checked: checkedProp,
21
+ ...props
22
+ }: CheckboxRootProps = $props()
17
23
  const providedId = $props.id()
18
24
 
19
25
  const [useCheckboxProps, localProps] = $derived(splitCheckboxProps(props))
@@ -21,7 +27,7 @@
21
27
  const resolvedProps = $derived<UseCheckboxProps>({
22
28
  ...useCheckboxProps,
23
29
  id: useCheckboxProps.id ?? providedId,
24
- checked,
30
+ checked: checkedProp,
25
31
  onCheckedChange(details) {
26
32
  useCheckboxProps.onCheckedChange?.(details)
27
33
  checked = details.checked
@@ -44,12 +44,22 @@ export declare function useCheckboxGroup(props?: MaybeFunction<UseCheckboxGroupP
44
44
  setValue: (newValue: string[]) => void;
45
45
  addValue: (val: string) => void;
46
46
  toggleValue: (val: string) => void;
47
- getItemProps: (itemProps: CheckboxGroupItemProps) => {
48
- checked: boolean | undefined;
49
- onCheckedChange(): void;
50
- name: string | undefined;
51
- disabled: boolean;
52
- readOnly: boolean;
53
- invalid: boolean;
47
+ getItemProps: {
48
+ (itemProps: CheckboxGroupItemProps, inheritedProps: Pick<UseCheckboxGroupProps, "disabled" | "readOnly" | "invalid">): ReturnType<(itemProps: CheckboxGroupItemProps, inheritedProps?: Pick<UseCheckboxGroupProps, "disabled" | "readOnly" | "invalid">) => {
49
+ checked: boolean | undefined;
50
+ onCheckedChange(): void;
51
+ name: string | undefined;
52
+ disabled: boolean;
53
+ readOnly: boolean;
54
+ invalid: boolean;
55
+ }>;
56
+ (itemProps: CheckboxGroupItemProps): ReturnType<(itemProps: CheckboxGroupItemProps, inheritedProps?: Pick<UseCheckboxGroupProps, "disabled" | "readOnly" | "invalid">) => {
57
+ checked: boolean | undefined;
58
+ onCheckedChange(): void;
59
+ name: string | undefined;
60
+ disabled: boolean;
61
+ readOnly: boolean;
62
+ invalid: boolean;
63
+ }>;
54
64
  };
55
65
  };
@@ -29,7 +29,7 @@ export function useCheckboxGroup(props = {}) {
29
29
  const toggleValue = (val) => {
30
30
  isChecked(val) ? removeValue(val) : addValue(val);
31
31
  };
32
- const getItemProps = (itemProps) => {
32
+ const getResolvedItemProps = (itemProps, inheritedProps = {}) => {
33
33
  return {
34
34
  checked: itemProps.value != null ? isChecked(itemProps.value) : undefined,
35
35
  onCheckedChange() {
@@ -38,11 +38,14 @@ export function useCheckboxGroup(props = {}) {
38
38
  }
39
39
  },
40
40
  name: resolvedProps.name,
41
- disabled: !!resolvedProps.disabled,
42
- readOnly: !!resolvedProps.readOnly,
43
- invalid: !!resolvedProps.invalid,
41
+ disabled: !!(resolvedProps.disabled ?? inheritedProps.disabled ?? false),
42
+ readOnly: !!(resolvedProps.readOnly ?? inheritedProps.readOnly ?? false),
43
+ invalid: !!(resolvedProps.invalid ?? inheritedProps.invalid ?? false),
44
44
  };
45
45
  };
46
+ function getItemProps(itemProps, inheritedProps = {}) {
47
+ return getResolvedItemProps(itemProps, typeof inheritedProps === 'object' && inheritedProps !== null ? inheritedProps : {});
48
+ }
46
49
  const api = $derived({
47
50
  isChecked,
48
51
  value,
@@ -3,6 +3,7 @@ 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 { createCheckedSync } from '../../../utils/sync-checked.js';
6
7
  import * as checkbox from '@destyler/checkbox';
7
8
  import { mergeProps } from '@destyler/svelte';
8
9
  import { runIfFn } from '@destyler/utils';
@@ -15,7 +16,11 @@ export function useCheckbox(props) {
15
16
  const field = useFieldContext();
16
17
  const machineProps = $derived.by(() => {
17
18
  const resolvedProps = runIfFn(props);
18
- const localProps = mergeProps(checkboxGroup?.()?.getItemProps({ value: resolvedProps.value }) ?? {}, resolvedProps);
19
+ const localProps = mergeProps(checkboxGroup?.()?.getItemProps({ value: resolvedProps.value }, {
20
+ disabled: field?.()?.disabled,
21
+ readOnly: field?.()?.readOnly,
22
+ invalid: field?.()?.invalid,
23
+ }) ?? {}, resolvedProps);
19
24
  return createMachineProps({
20
25
  ids: {
21
26
  label: field?.()?.ids.label,
@@ -35,6 +40,13 @@ export function useCheckbox(props) {
35
40
  return machineProps.context;
36
41
  },
37
42
  });
38
- const api = $derived(checkbox.connect(state, send, normalizeProps));
43
+ const connected = $derived(checkbox.connect(state, send, normalizeProps));
44
+ const syncChecked = createCheckedSync(() => connected);
45
+ const api = $derived({
46
+ ...connected,
47
+ getHiddenInputProps() {
48
+ return mergeProps(connected.getHiddenInputProps(), { onclick: syncChecked });
49
+ },
50
+ });
39
51
  return () => api;
40
52
  }
@@ -21,7 +21,13 @@
21
21
  import { CollapseProvider } from '../hooks/use-collapse-context'
22
22
  import { useCollapse } from '../hooks/use-collapse.svelte'
23
23
 
24
- let { value = $bindable(), ...props }: CollapseRootProps = $props()
24
+ // Read the parent prop independently from the writable binding. Local writes
25
+ // notify bind: consumers without overriding ordinary controlled props.
26
+ let {
27
+ value = $bindable(),
28
+ value: valueProp,
29
+ ...props
30
+ }: CollapseRootProps = $props()
25
31
  const providedId = $props.id()
26
32
 
27
33
  const [renderStrategyProps, collapseProps] = $derived(splitRenderStrategyProps(props))
@@ -43,10 +49,10 @@
43
49
  const resolvedProps = $derived<UseCollapseProps>({
44
50
  ...useCollapseProps,
45
51
  id: useCollapseProps.id ?? providedId,
46
- value,
52
+ value: valueProp,
47
53
  onValueChange(details) {
48
54
  useCollapseProps.onValueChange?.(details)
49
- if (value !== undefined) value = details.value
55
+ value = details.value
50
56
  },
51
57
  })
52
58
 
@@ -13,7 +13,13 @@
13
13
  import { splitCollapsibleProps } from '../hooks/split-collapsible-props.svelte'
14
14
  import { useCollapsible } from '../hooks/use-collapsible.svelte'
15
15
 
16
- let { open = $bindable(), ...props }: CollapsibleRootProps = $props()
16
+ // Read the parent prop independently from the writable binding. Local writes
17
+ // notify bind: consumers without overriding ordinary controlled props.
18
+ let {
19
+ open = $bindable(),
20
+ open: openProp,
21
+ ...props
22
+ }: CollapsibleRootProps = $props()
17
23
  const providedId = $props.id()
18
24
 
19
25
  const [useCollapsibleProps, localProps] = $derived(splitCollapsibleProps(props))
@@ -21,10 +27,10 @@
21
27
  const resolvedProps = $derived<UseCollapsibleProps>({
22
28
  ...useCollapsibleProps,
23
29
  id: useCollapsibleProps.id ?? providedId,
24
- open,
30
+ open: openProp,
25
31
  onOpenChange(details) {
26
32
  useCollapsibleProps.onOpenChange?.(details)
27
- if (open !== undefined) open = details.open
33
+ open = details.open
28
34
  },
29
35
  })
30
36
 
@@ -1,5 +1,5 @@
1
1
  import type { Optional } from '../../../types.js';
2
2
  import type { UseCollapsibleProps } from './use-collapsible.svelte.js';
3
3
  type CollapsibleMachineProps = Optional<UseCollapsibleProps, 'id'>;
4
- export declare function splitCollapsibleProps<T extends CollapsibleMachineProps>(props: T): [CollapsibleMachineProps, Omit<T, "id" | "ids" | "disabled" | "lazyMount" | "unmountOnExit" | "onExitComplete" | "open" | "onOpenChange" | "defaultOpen">];
4
+ export declare function splitCollapsibleProps<T extends CollapsibleMachineProps>(props: T): [CollapsibleMachineProps, Omit<T, "open" | "defaultOpen" | "id" | "ids" | "disabled" | "lazyMount" | "unmountOnExit" | "onExitComplete" | "onOpenChange">];
5
5
  export {};
@@ -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 collapsible from '@destyler/collapsible';
5
- export interface UseCollapsibleProps extends Omit<collapsible.Context, 'dir' | 'getRootNode' | 'open.controlled' | 'id'> {
5
+ export interface UseCollapsibleProps extends Omit<collapsible.Context, 'dir' | 'getRootNode' | 'id'> {
6
6
  id: string;
7
7
  defaultOpen?: collapsible.Context['open'];
8
8
  /**
@@ -1 +1 @@
1
- export declare const colorPickerAnatomy: import("@destyler/anatomy").AnatomyInstance<"area" | "label" | "view" | "root" | "content" | "control" | "trigger" | "positioner" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
1
+ export declare const colorPickerAnatomy: import("@destyler/anatomy").AnatomyInstance<"area" | "label" | "view" | "root" | "content" | "control" | "positioner" | "trigger" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
@@ -9,6 +9,7 @@
9
9
  <script lang="ts">
10
10
  import { createSplitProps } from '../../../utils/create-split-props'
11
11
  import { mergeProps } from '@destyler/svelte'
12
+ import { createInputValueSync } from '../../../utils/sync-input-value'
12
13
  import { UI } from '../../factory'
13
14
  import { useColorPickerContext } from '../hooks/use-color-picker-context'
14
15
 
@@ -17,7 +18,14 @@
17
18
  const [channelProps, localProps] = $derived(createSplitProps<ChannelInputProps>()(props, ['channel', 'orientation']))
18
19
 
19
20
  const colorPicker = useColorPickerContext()
20
- const mergedProps = $derived(mergeProps(colorPicker().getChannelInputProps(channelProps), localProps))
21
+ const syncInputValue = createInputValueSync(() => colorPicker().getChannelInputProps(channelProps), () => colorPicker().value)
22
+ const mergedProps = $derived(mergeProps(colorPicker().getChannelInputProps(channelProps), localProps, {
23
+ onfocusout: syncInputValue,
24
+ onkeydown(event: KeyboardEvent) {
25
+ if (event.key === 'Enter' && !event.isComposing)
26
+ void syncInputValue(event)
27
+ },
28
+ }))
21
29
  </script>
22
30
 
23
31
  <UI as="input" {...mergedProps} />
@@ -19,7 +19,15 @@
19
19
  import { ColorPickerProvider } from '../hooks/use-color-picker-context'
20
20
  import { useColorPicker } from '../hooks/use-color-picker.svelte'
21
21
 
22
- let { value = $bindable<Color>(), open = $bindable<boolean>(), ...props }: ColorPickerRootProps = $props()
22
+ // Read the parent prop independently from the writable binding. Local writes
23
+ // notify bind: consumers without overriding ordinary controlled props.
24
+ let {
25
+ value = $bindable<Color>(),
26
+ value: valueProp,
27
+ open = $bindable<boolean>(),
28
+ open: openProp,
29
+ ...props
30
+ }: ColorPickerRootProps = $props()
23
31
  const providedId = $props.id()
24
32
 
25
33
  const [presenceProps, colorPickerProps] = $derived(splitPresenceProps(props))
@@ -28,15 +36,15 @@
28
36
  const machineProps = $derived<UseColorPickerProps>({
29
37
  ...useColorPickerProps,
30
38
  id: useColorPickerProps.id ?? providedId,
31
- value,
32
- open,
39
+ value: valueProp,
40
+ open: openProp,
33
41
  onValueChange(details) {
34
42
  useColorPickerProps.onValueChange?.(details)
35
43
  value = details.value
36
44
  },
37
45
  onOpenChange(details) {
38
46
  useColorPickerProps.onOpenChange?.(details)
39
- if (open !== undefined) open = details.open
47
+ open = details.open
40
48
  },
41
49
  })
42
50
 
@@ -1,5 +1,5 @@
1
1
  import type { Optional } from '../../../types.js';
2
2
  import type { UseColorPickerProps } from './use-color-picker.svelte.js';
3
3
  type ColorPickerMachineProps = Optional<UseColorPickerProps, 'id'>;
4
- export declare function splitColorPickerProps<T extends ColorPickerMachineProps>(props: T): [ColorPickerMachineProps, Omit<T, "value" | "defaultValue" | "name" | "id" | "ids" | "disabled" | "open" | "required" | "readOnly" | "closeOnSelect" | "onValueChange" | "onOpenChange" | "format" | "positioning" | "defaultOpen" | "invalid" | "onValueChangeEnd" | "initialFocusEl" | "onFormatChange" | "openAutoFocus" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside">];
4
+ export declare function splitColorPickerProps<T extends ColorPickerMachineProps>(props: T): [ColorPickerMachineProps, Omit<T, "value" | "defaultValue" | "name" | "open" | "defaultOpen" | "id" | "ids" | "disabled" | "required" | "readOnly" | "closeOnSelect" | "onValueChange" | "onOpenChange" | "format" | "positioning" | "invalid" | "onValueChangeEnd" | "initialFocusEl" | "onFormatChange" | "openAutoFocus" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside">];
5
5
  export {};
@@ -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 colorPicker from '@destyler/color-picker';
5
- export interface UseColorPickerProps extends Omit<colorPicker.Context, 'dir' | 'getRootNode' | 'open.controlled' | 'id'> {
5
+ export interface UseColorPickerProps extends Omit<colorPicker.Context, 'dir' | 'getRootNode' | 'id'> {
6
6
  id: string;
7
7
  defaultOpen?: colorPicker.Context['open'];
8
8
  defaultValue?: colorPicker.Context['value'];
@@ -12,20 +12,17 @@
12
12
  import { useComboboxContext } from '../hooks/use-combobox-context'
13
13
  import { usePresenceContext } from '../../presence'
14
14
 
15
- let { ref = $bindable<Element | null>(), ...props }: ComboboxContentProps = $props()
15
+ let { ref = $bindable(), ...props }: ComboboxContentProps = $props()
16
16
 
17
17
  const combobox = useComboboxContext()
18
18
  const presence = usePresenceContext()
19
19
  const mergedProps = $derived(mergeProps(combobox().getContentProps(), presence().getPresenceProps(), props))
20
20
 
21
- function setNode(node: HTMLDivElement) {
22
- untrack(() => {
23
- presence().setNode(node)
24
- ref = node
25
- })
21
+ function setNode(node: HTMLElement) {
22
+ untrack(() => presence().setNode(node))
26
23
  }
27
24
  </script>
28
25
 
29
26
  {#if !presence().unmounted}
30
- <UI as="div" {...mergedProps} {@attach setNode} />
27
+ <UI as="div" {...mergedProps} bind:ref={() => ref ?? null, (node) => ref = node} {@attach setNode} />
31
28
  {/if}
@@ -20,10 +20,15 @@
20
20
  import { ComboboxProvider } from '../hooks/use-combobox-context'
21
21
  import { useCombobox } from '../hooks/use-combobox.svelte'
22
22
 
23
+ // Read the parent prop independently from the writable binding. Local writes
24
+ // notify bind: consumers without overriding ordinary controlled props.
23
25
  let {
24
26
  open = $bindable<boolean>(),
27
+ open: openProp,
25
28
  value = $bindable<string[]>(),
29
+ value: valueProp,
26
30
  inputValue = $bindable<string>(),
31
+ inputValue: inputValueProp,
27
32
  ...props
28
33
  }: ComboboxRootProps<T> = $props()
29
34
 
@@ -37,6 +42,7 @@
37
42
  'composite',
38
43
  'defaultOpen',
39
44
  'defaultValue',
45
+ 'defaultInputValue',
40
46
  'disabled',
41
47
  'disableLayer',
42
48
  'form',
@@ -77,20 +83,20 @@
77
83
  const machineProps = $derived.by<UseComboboxProps<T>>(() => ({
78
84
  ...useComboboxProps,
79
85
  id: useComboboxProps.id ?? id,
80
- open,
81
- value,
82
- inputValue,
86
+ open: openProp,
87
+ value: valueProp,
88
+ inputValue: inputValueProp,
83
89
  onOpenChange(details) {
84
90
  useComboboxProps.onOpenChange?.(details)
85
- if (open != null) open = details.open
91
+ open = details.open
86
92
  },
87
93
  onValueChange(details) {
88
94
  useComboboxProps.onValueChange?.(details)
89
- if (value != null) value = details.value
95
+ value = details.value
90
96
  },
91
97
  onInputValueChange(details) {
92
98
  useComboboxProps.onInputValueChange?.(details)
93
- if (inputValue != null) inputValue = details.inputValue
99
+ inputValue = details.inputValue
94
100
  },
95
101
  }))
96
102
 
@@ -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 combobox from '@destyler/combobox';
6
- export interface UseComboboxProps<T extends CollectionItem> extends Omit<combobox.Context<T>, 'dir' | 'getRootNode' | 'collection' | 'open.controlled' | 'id'> {
6
+ export interface UseComboboxProps<T extends CollectionItem> extends Omit<combobox.Context<T>, 'dir' | 'getRootNode' | 'collection' | 'id'> {
7
7
  id: string;
8
8
  defaultOpen?: combobox.Context<T>['open'];
9
9
  defaultValue?: combobox.Context<T>['value'];
@@ -3,7 +3,9 @@ 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 combobox from '@destyler/combobox';
8
+ import { mergeProps } from '@destyler/svelte';
7
9
  import { runIfFn } from '@destyler/utils';
8
10
  import { useFieldContext } from '../../field/index.js';
9
11
  export function useCombobox(props) {
@@ -33,6 +35,16 @@ export function useCombobox(props) {
33
35
  return machineProps.context;
34
36
  },
35
37
  });
36
- const api = $derived(combobox.connect(state, send, normalizeProps));
38
+ const connected = $derived(combobox.connect(state, send, normalizeProps));
39
+ const syncInputValue = createInputValueSync(() => connected.getInputProps(), () => connected.inputValue);
40
+ const api = $derived({
41
+ ...connected,
42
+ getInputProps() {
43
+ return mergeProps(connected.getInputProps(), {
44
+ oninput: syncInputValue,
45
+ oncompositionend: syncInputValue,
46
+ });
47
+ },
48
+ });
37
49
  return () => api;
38
50
  }