bits-ui 1.0.0-next.47 → 1.0.0-next.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bits/checkbox/checkbox.svelte.d.ts +3 -1
- package/dist/bits/checkbox/checkbox.svelte.js +8 -5
- package/dist/bits/checkbox/components/checkbox.svelte +20 -1
- package/dist/bits/checkbox/components/checkbox.svelte.d.ts +1 -1
- package/dist/bits/checkbox/types.d.ts +23 -4
- package/dist/bits/menu/components/menu-checkbox-item.svelte +16 -2
- package/dist/bits/menu/components/menu-checkbox-item.svelte.d.ts +1 -1
- package/dist/bits/menu/menu.svelte.d.ts +6 -1
- package/dist/bits/menu/menu.svelte.js +12 -8
- package/dist/bits/menu/types.d.ts +27 -5
- package/dist/bits/radio-group/radio-group.svelte.js +1 -1
- package/dist/bits/switch/switch.svelte.js +1 -1
- package/dist/bits/toggle-group/toggle-group.svelte.js +1 -1
- package/dist/bits/toolbar/toolbar.svelte.js +1 -1
- package/dist/internal/attrs.d.ts +1 -1
- package/dist/internal/attrs.js +3 -3
- package/package.json +1 -1
|
@@ -6,7 +6,8 @@ type CheckboxRootStateProps = WithRefProps<ReadableBoxedValues<{
|
|
|
6
6
|
name: string | undefined;
|
|
7
7
|
value: string | undefined;
|
|
8
8
|
}> & WritableBoxedValues<{
|
|
9
|
-
checked: boolean
|
|
9
|
+
checked: boolean;
|
|
10
|
+
indeterminate: boolean;
|
|
10
11
|
}>>;
|
|
11
12
|
declare class CheckboxRootState {
|
|
12
13
|
#private;
|
|
@@ -15,6 +16,7 @@ declare class CheckboxRootState {
|
|
|
15
16
|
required: CheckboxRootStateProps["required"];
|
|
16
17
|
name: CheckboxRootStateProps["name"];
|
|
17
18
|
value: CheckboxRootStateProps["value"];
|
|
19
|
+
indeterminate: CheckboxRootStateProps["indeterminate"];
|
|
18
20
|
constructor(props: CheckboxRootStateProps);
|
|
19
21
|
props: {
|
|
20
22
|
readonly id: string;
|
|
@@ -11,6 +11,7 @@ class CheckboxRootState {
|
|
|
11
11
|
required;
|
|
12
12
|
name;
|
|
13
13
|
value;
|
|
14
|
+
indeterminate;
|
|
14
15
|
constructor(props) {
|
|
15
16
|
this.checked = props.checked;
|
|
16
17
|
this.disabled = props.disabled;
|
|
@@ -19,6 +20,7 @@ class CheckboxRootState {
|
|
|
19
20
|
this.value = props.value;
|
|
20
21
|
this.#ref = props.ref;
|
|
21
22
|
this.#id = props.id;
|
|
23
|
+
this.indeterminate = props.indeterminate;
|
|
22
24
|
useRefById({
|
|
23
25
|
id: this.#id,
|
|
24
26
|
ref: this.#ref,
|
|
@@ -35,7 +37,8 @@ class CheckboxRootState {
|
|
|
35
37
|
}
|
|
36
38
|
};
|
|
37
39
|
#toggle = () => {
|
|
38
|
-
if (this.
|
|
40
|
+
if (this.indeterminate.current) {
|
|
41
|
+
this.indeterminate.current = false;
|
|
39
42
|
this.checked.current = true;
|
|
40
43
|
}
|
|
41
44
|
else {
|
|
@@ -52,10 +55,10 @@ class CheckboxRootState {
|
|
|
52
55
|
role: "checkbox",
|
|
53
56
|
type: "button",
|
|
54
57
|
disabled: this.disabled.current,
|
|
55
|
-
"aria-checked": getAriaChecked(this.checked.current),
|
|
58
|
+
"aria-checked": getAriaChecked(this.checked.current, this.indeterminate.current),
|
|
56
59
|
"aria-required": getAriaRequired(this.required.current),
|
|
57
60
|
"data-disabled": getDataDisabled(this.disabled.current),
|
|
58
|
-
"data-state": getCheckboxDataState(this.checked.current),
|
|
61
|
+
"data-state": getCheckboxDataState(this.checked.current, this.indeterminate.current),
|
|
59
62
|
[CHECKBOX_ROOT_ATTR]: "",
|
|
60
63
|
//
|
|
61
64
|
onclick: this.#onclick,
|
|
@@ -85,8 +88,8 @@ class CheckboxInputState {
|
|
|
85
88
|
//
|
|
86
89
|
// HELPERS
|
|
87
90
|
//
|
|
88
|
-
function getCheckboxDataState(checked) {
|
|
89
|
-
if (
|
|
91
|
+
function getCheckboxDataState(checked, indeterminate) {
|
|
92
|
+
if (indeterminate) {
|
|
90
93
|
return "indeterminate";
|
|
91
94
|
}
|
|
92
95
|
return checked ? "checked" : "unchecked";
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
value = "on",
|
|
17
17
|
id = useId(),
|
|
18
18
|
controlledChecked = false,
|
|
19
|
+
indeterminate = $bindable(false),
|
|
20
|
+
controlledIndeterminate = false,
|
|
21
|
+
onIndeterminateChange,
|
|
19
22
|
child,
|
|
20
23
|
...restProps
|
|
21
24
|
}: CheckboxRootProps = $props();
|
|
@@ -41,17 +44,33 @@
|
|
|
41
44
|
() => ref,
|
|
42
45
|
(v) => (ref = v)
|
|
43
46
|
),
|
|
47
|
+
indeterminate: box.with(
|
|
48
|
+
() => indeterminate,
|
|
49
|
+
(v) => {
|
|
50
|
+
if (controlledIndeterminate) {
|
|
51
|
+
onIndeterminateChange?.(v);
|
|
52
|
+
} else {
|
|
53
|
+
indeterminate = v;
|
|
54
|
+
onIndeterminateChange?.(v);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
),
|
|
44
58
|
});
|
|
45
59
|
|
|
46
60
|
const mergedProps = $derived(mergeProps({ ...restProps }, rootState.props));
|
|
47
61
|
</script>
|
|
48
62
|
|
|
49
63
|
{#if child}
|
|
50
|
-
{@render child({
|
|
64
|
+
{@render child({
|
|
65
|
+
props: mergedProps,
|
|
66
|
+
checked: rootState.checked.current,
|
|
67
|
+
indeterminate: rootState.indeterminate.current,
|
|
68
|
+
})}
|
|
51
69
|
{:else}
|
|
52
70
|
<button {...mergedProps}>
|
|
53
71
|
{@render children?.({
|
|
54
72
|
checked: rootState.checked.current,
|
|
73
|
+
indeterminate: rootState.indeterminate.current,
|
|
55
74
|
})}
|
|
56
75
|
</button>
|
|
57
76
|
{/if}
|
|
@@ -14,6 +14,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
14
14
|
}
|
|
15
15
|
declare const Checkbox: $$__sveltets_2_IsomorphicComponent<CheckboxRootProps, {
|
|
16
16
|
[evt: string]: CustomEvent<any>;
|
|
17
|
-
}, {}, {}, "checked" | "ref">;
|
|
17
|
+
}, {}, {}, "checked" | "indeterminate" | "ref">;
|
|
18
18
|
type Checkbox = InstanceType<typeof Checkbox>;
|
|
19
19
|
export default Checkbox;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { OnChangeFn, WithChild, Without } from "../../internal/types.js";
|
|
2
2
|
import type { BitsPrimitiveButtonAttributes } from "../../shared/attributes.js";
|
|
3
3
|
export type CheckboxRootSnippetProps = {
|
|
4
|
-
checked: boolean
|
|
4
|
+
checked: boolean;
|
|
5
|
+
indeterminate: boolean;
|
|
5
6
|
};
|
|
6
7
|
export type CheckboxRootPropsWithoutHTML = WithChild<{
|
|
7
8
|
/**
|
|
@@ -33,15 +34,14 @@ export type CheckboxRootPropsWithoutHTML = WithChild<{
|
|
|
33
34
|
* The checked state of the checkbox. It can be one of:
|
|
34
35
|
* - `true` for checked
|
|
35
36
|
* - `false` for unchecked
|
|
36
|
-
* - `"indeterminate"` for indeterminate
|
|
37
37
|
*
|
|
38
38
|
* @defaultValue false
|
|
39
39
|
*/
|
|
40
|
-
checked?: boolean
|
|
40
|
+
checked?: boolean;
|
|
41
41
|
/**
|
|
42
42
|
* A callback function called when the checked state changes.
|
|
43
43
|
*/
|
|
44
|
-
onCheckedChange?: OnChangeFn<boolean
|
|
44
|
+
onCheckedChange?: OnChangeFn<boolean>;
|
|
45
45
|
/**
|
|
46
46
|
* Whether or not the checkbox is controlled or not. If `true`, the checkbox will not update
|
|
47
47
|
* the checked state internally, instead it will call `onCheckedChange` when it would have
|
|
@@ -51,5 +51,24 @@ export type CheckboxRootPropsWithoutHTML = WithChild<{
|
|
|
51
51
|
* @defaultValue false
|
|
52
52
|
*/
|
|
53
53
|
controlledChecked?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the checkbox is in an indeterminate state or not.
|
|
56
|
+
*
|
|
57
|
+
* @defaultValue false
|
|
58
|
+
*/
|
|
59
|
+
indeterminate?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* A callback function called when the indeterminate state changes.
|
|
62
|
+
*/
|
|
63
|
+
onIndeterminateChange?: OnChangeFn<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the indeterminate state is controlled or not. If `true`, the checkbox will
|
|
66
|
+
* not update the indeterminate state internally, instead it will call
|
|
67
|
+
* `onIndeterminateChange` when it would have otherwise, and it is up to you to update
|
|
68
|
+
* the `indeterminate` prop that is passed to the component.
|
|
69
|
+
*
|
|
70
|
+
* @defaultValue false
|
|
71
|
+
*/
|
|
72
|
+
controlledIndeterminate?: boolean;
|
|
54
73
|
}, CheckboxRootSnippetProps>;
|
|
55
74
|
export type CheckboxRootProps = CheckboxRootPropsWithoutHTML & Without<BitsPrimitiveButtonAttributes, CheckboxRootPropsWithoutHTML>;
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
onSelect = noop,
|
|
17
17
|
controlledChecked = false,
|
|
18
18
|
closeOnSelect = true,
|
|
19
|
+
indeterminate = $bindable(false),
|
|
20
|
+
controlledIndeterminate = false,
|
|
21
|
+
onIndeterminateChange = noop,
|
|
19
22
|
...restProps
|
|
20
23
|
}: MenuCheckboxItemProps = $props();
|
|
21
24
|
|
|
@@ -39,6 +42,17 @@
|
|
|
39
42
|
(v) => (ref = v)
|
|
40
43
|
),
|
|
41
44
|
closeOnSelect: box.with(() => closeOnSelect),
|
|
45
|
+
indeterminate: box.with(
|
|
46
|
+
() => indeterminate,
|
|
47
|
+
(v) => {
|
|
48
|
+
if (controlledIndeterminate) {
|
|
49
|
+
onIndeterminateChange(v);
|
|
50
|
+
} else {
|
|
51
|
+
indeterminate = v;
|
|
52
|
+
onIndeterminateChange(v);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
),
|
|
42
56
|
});
|
|
43
57
|
|
|
44
58
|
function handleSelect(e: Event) {
|
|
@@ -51,9 +65,9 @@
|
|
|
51
65
|
</script>
|
|
52
66
|
|
|
53
67
|
{#if child}
|
|
54
|
-
{@render child({ props: mergedProps,
|
|
68
|
+
{@render child({ props: mergedProps, ...checkboxItemState.snippetProps })}
|
|
55
69
|
{:else}
|
|
56
70
|
<div {...mergedProps}>
|
|
57
|
-
{@render children?.(
|
|
71
|
+
{@render children?.(checkboxItemState.snippetProps)}
|
|
58
72
|
</div>
|
|
59
73
|
{/if}
|
|
@@ -14,6 +14,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
14
14
|
}
|
|
15
15
|
declare const MenuCheckboxItem: $$__sveltets_2_IsomorphicComponent<MenuCheckboxItemProps, {
|
|
16
16
|
[evt: string]: CustomEvent<any>;
|
|
17
|
-
}, {}, {}, "checked" | "ref">;
|
|
17
|
+
}, {}, {}, "checked" | "indeterminate" | "ref">;
|
|
18
18
|
type MenuCheckboxItem = InstanceType<typeof MenuCheckboxItem>;
|
|
19
19
|
export default MenuCheckboxItem;
|
|
@@ -167,12 +167,17 @@ declare class MenuSubTriggerState {
|
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
type MenuCheckboxItemStateProps = WritableBoxedValues<{
|
|
170
|
-
checked: boolean
|
|
170
|
+
checked: boolean;
|
|
171
|
+
indeterminate: boolean;
|
|
171
172
|
}>;
|
|
172
173
|
declare class MenuCheckboxItemState {
|
|
173
174
|
#private;
|
|
174
175
|
constructor(props: MenuCheckboxItemStateProps, item: MenuItemState);
|
|
175
176
|
toggleChecked: () => void;
|
|
177
|
+
snippetProps: {
|
|
178
|
+
checked: boolean;
|
|
179
|
+
indeterminate: boolean;
|
|
180
|
+
};
|
|
176
181
|
props: {
|
|
177
182
|
readonly [x: string]: string | -1 | ((e: PointerEvent) => void) | undefined;
|
|
178
183
|
readonly role: "menuitemcheckbox";
|
|
@@ -511,25 +511,29 @@ class MenuSubTriggerState {
|
|
|
511
511
|
class MenuCheckboxItemState {
|
|
512
512
|
#item;
|
|
513
513
|
#checked;
|
|
514
|
+
#indeterminate;
|
|
514
515
|
constructor(props, item) {
|
|
515
516
|
this.#item = item;
|
|
516
517
|
this.#checked = props.checked;
|
|
518
|
+
this.#indeterminate = props.indeterminate;
|
|
517
519
|
}
|
|
518
520
|
toggleChecked = () => {
|
|
519
|
-
if (this.#
|
|
520
|
-
this.#
|
|
521
|
-
}
|
|
522
|
-
else if (this.#checked.current === false) {
|
|
521
|
+
if (this.#indeterminate.current) {
|
|
522
|
+
this.#indeterminate.current = false;
|
|
523
523
|
this.#checked.current = true;
|
|
524
524
|
}
|
|
525
|
-
else
|
|
526
|
-
this.#checked.current =
|
|
525
|
+
else {
|
|
526
|
+
this.#checked.current = !this.#checked.current;
|
|
527
527
|
}
|
|
528
528
|
};
|
|
529
|
+
snippetProps = $derived.by(() => ({
|
|
530
|
+
checked: this.#checked.current,
|
|
531
|
+
indeterminate: this.#indeterminate.current,
|
|
532
|
+
}));
|
|
529
533
|
props = $derived.by(() => ({
|
|
530
534
|
...this.#item.props,
|
|
531
535
|
role: "menuitemcheckbox",
|
|
532
|
-
"aria-checked": getAriaChecked(this.#checked.current),
|
|
536
|
+
"aria-checked": getAriaChecked(this.#checked.current, this.#indeterminate.current),
|
|
533
537
|
"data-state": getCheckedState(this.#checked.current),
|
|
534
538
|
[this.#item.root.getAttr("checkbox-item")]: "",
|
|
535
539
|
}));
|
|
@@ -660,7 +664,7 @@ class MenuRadioItemState {
|
|
|
660
664
|
[this.#group.root.getAttr("radio-item")]: "",
|
|
661
665
|
...this.#item.props,
|
|
662
666
|
role: "menuitemradio",
|
|
663
|
-
"aria-checked": getAriaChecked(this.isChecked),
|
|
667
|
+
"aria-checked": getAriaChecked(this.isChecked, false),
|
|
664
668
|
"data-state": getCheckedState(this.isChecked),
|
|
665
669
|
}));
|
|
666
670
|
}
|
|
@@ -80,19 +80,22 @@ export type MenuItemPropsWithoutHTML<U extends Record<PropertyKey, unknown> = {
|
|
|
80
80
|
}, U>;
|
|
81
81
|
export type MenuItemProps = MenuItemPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, MenuItemPropsWithoutHTML>;
|
|
82
82
|
export type MenuCheckboxItemSnippetProps = {
|
|
83
|
-
checked: boolean
|
|
83
|
+
checked: boolean;
|
|
84
|
+
indeterminate: boolean;
|
|
84
85
|
};
|
|
85
86
|
export type MenuCheckboxItemPropsWithoutHTML = MenuItemPropsWithoutHTML<MenuCheckboxItemSnippetProps> & {
|
|
86
87
|
/**
|
|
87
|
-
* The checked state of the checkbox
|
|
88
|
+
* The checked state of the checkbox. It can be one of:
|
|
89
|
+
* - `true` for checked
|
|
90
|
+
* - `false` for unchecked
|
|
88
91
|
*
|
|
89
|
-
*
|
|
92
|
+
* @defaultValue false
|
|
90
93
|
*/
|
|
91
|
-
checked?: boolean
|
|
94
|
+
checked?: boolean;
|
|
92
95
|
/**
|
|
93
96
|
* A callback that is fired when the checked state changes.
|
|
94
97
|
*/
|
|
95
|
-
onCheckedChange?: OnChangeFn<boolean
|
|
98
|
+
onCheckedChange?: OnChangeFn<boolean>;
|
|
96
99
|
/**
|
|
97
100
|
* Whether or not the checked state is controlled or not. If `true`, the component will not
|
|
98
101
|
* update the checked state internally, instead it will call `onCheckedChange` when it
|
|
@@ -102,6 +105,25 @@ export type MenuCheckboxItemPropsWithoutHTML = MenuItemPropsWithoutHTML<MenuChec
|
|
|
102
105
|
* @defaultValue false
|
|
103
106
|
*/
|
|
104
107
|
controlledChecked?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Whether the checkbox is in an indeterminate state or not.
|
|
110
|
+
*
|
|
111
|
+
* @defaultValue false
|
|
112
|
+
*/
|
|
113
|
+
indeterminate?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* A callback function called when the indeterminate state changes.
|
|
116
|
+
*/
|
|
117
|
+
onIndeterminateChange?: OnChangeFn<boolean>;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the indeterminate state is controlled or not. If `true`, the checkbox will
|
|
120
|
+
* not update the indeterminate state internally, instead it will call
|
|
121
|
+
* `onIndeterminateChange` when it would have otherwise, and it is up to you to update
|
|
122
|
+
* the `indeterminate` prop that is passed to the component.
|
|
123
|
+
*
|
|
124
|
+
* @defaultValue false
|
|
125
|
+
*/
|
|
126
|
+
controlledIndeterminate?: boolean;
|
|
105
127
|
/**
|
|
106
128
|
* Whether or not the menu item should close when selected.
|
|
107
129
|
*
|
|
@@ -102,7 +102,7 @@ class RadioGroupItemState {
|
|
|
102
102
|
"data-orientation": this.#root.orientation.current,
|
|
103
103
|
"data-disabled": getDataDisabled(this.#isDisabled),
|
|
104
104
|
"data-state": this.#isChecked ? "checked" : "unchecked",
|
|
105
|
-
"aria-checked": getAriaChecked(this.#isChecked),
|
|
105
|
+
"aria-checked": getAriaChecked(this.#isChecked, false),
|
|
106
106
|
[RADIO_GROUP_ITEM_ATTR]: "",
|
|
107
107
|
type: "button",
|
|
108
108
|
role: "radio",
|
|
@@ -49,7 +49,7 @@ class SwitchRootState {
|
|
|
49
49
|
id: this.#id.current,
|
|
50
50
|
role: "switch",
|
|
51
51
|
disabled: getDisabled(this.disabled.current),
|
|
52
|
-
"aria-checked": getAriaChecked(this.checked.current),
|
|
52
|
+
"aria-checked": getAriaChecked(this.checked.current, false),
|
|
53
53
|
"aria-required": getAriaRequired(this.required.current),
|
|
54
54
|
[ROOT_ATTR]: "",
|
|
55
55
|
//
|
|
@@ -131,7 +131,7 @@ class ToggleGroupItemState {
|
|
|
131
131
|
};
|
|
132
132
|
isPressed = $derived.by(() => this.#root.includesItem(this.#value.current));
|
|
133
133
|
#ariaChecked = $derived.by(() => {
|
|
134
|
-
return this.#root.isMulti ? undefined : getAriaChecked(this.isPressed);
|
|
134
|
+
return this.#root.isMulti ? undefined : getAriaChecked(this.isPressed, false);
|
|
135
135
|
});
|
|
136
136
|
#ariaPressed = $derived.by(() => {
|
|
137
137
|
return this.#root.isMulti ? getAriaPressed(this.isPressed) : undefined;
|
|
@@ -150,7 +150,7 @@ class ToolbarGroupItemState {
|
|
|
150
150
|
};
|
|
151
151
|
isPressed = $derived.by(() => this.#group.includesItem(this.#value.current));
|
|
152
152
|
#ariaChecked = $derived.by(() => {
|
|
153
|
-
return this.#group.isMulti ? undefined : getAriaChecked(this.isPressed);
|
|
153
|
+
return this.#group.isMulti ? undefined : getAriaChecked(this.isPressed, false);
|
|
154
154
|
});
|
|
155
155
|
#ariaPressed = $derived.by(() => {
|
|
156
156
|
return this.#group.isMulti ? getAriaPressed(this.isPressed) : undefined;
|
package/dist/internal/attrs.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare function getAriaExpanded(condition: boolean): "true" | "false";
|
|
|
6
6
|
export declare function getDataDisabled(condition: boolean): "" | undefined;
|
|
7
7
|
export declare function getAriaRequired(condition: boolean): "true" | "false";
|
|
8
8
|
export declare function getAriaSelected(condition: boolean): "true" | "false";
|
|
9
|
-
export declare function getAriaChecked(
|
|
9
|
+
export declare function getAriaChecked(checked: boolean, indeterminate: boolean): "true" | "false" | "mixed";
|
|
10
10
|
export declare function getAriaOrientation(orientation: "horizontal" | "vertical"): "horizontal" | "vertical";
|
|
11
11
|
export declare function getAriaHidden(condition: boolean): "true" | undefined;
|
|
12
12
|
export declare function getAriaInvalid(condition: boolean): "true" | undefined;
|
package/dist/internal/attrs.js
CHANGED
|
@@ -22,11 +22,11 @@ export function getAriaRequired(condition) {
|
|
|
22
22
|
export function getAriaSelected(condition) {
|
|
23
23
|
return condition ? "true" : "false";
|
|
24
24
|
}
|
|
25
|
-
export function getAriaChecked(
|
|
26
|
-
if (
|
|
25
|
+
export function getAriaChecked(checked, indeterminate) {
|
|
26
|
+
if (indeterminate) {
|
|
27
27
|
return "mixed";
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return checked ? "true" : "false";
|
|
30
30
|
}
|
|
31
31
|
export function getAriaOrientation(orientation) {
|
|
32
32
|
return orientation;
|