bits-ui 1.2.1 → 1.3.1
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/button/components/button.svelte +1 -0
- package/dist/bits/index.d.ts +1 -0
- package/dist/bits/index.js +1 -0
- package/dist/bits/meter/components/meter.svelte +38 -0
- package/dist/bits/meter/components/meter.svelte.d.ts +4 -0
- package/dist/bits/meter/exports.d.ts +2 -0
- package/dist/bits/meter/exports.js +1 -0
- package/dist/bits/meter/index.d.ts +1 -0
- package/dist/bits/meter/index.js +1 -0
- package/dist/bits/meter/meter.svelte.d.ts +24 -0
- package/dist/bits/meter/meter.svelte.js +23 -0
- package/dist/bits/meter/types.d.ts +23 -0
- package/dist/bits/meter/types.js +1 -0
- package/dist/bits/radio-group/radio-group.svelte.js +8 -1
- package/dist/bits/select/components/select-content.svelte +0 -1
- package/dist/bits/select/select.svelte.d.ts +1 -4
- package/dist/bits/select/select.svelte.js +22 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/bits/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export { DropdownMenu } from "./dropdown-menu/index.js";
|
|
|
18
18
|
export { Label } from "./label/index.js";
|
|
19
19
|
export { LinkPreview } from "./link-preview/index.js";
|
|
20
20
|
export { Menubar } from "./menubar/index.js";
|
|
21
|
+
export { Meter } from "./meter/index.js";
|
|
21
22
|
export { NavigationMenu } from "./navigation-menu/index.js";
|
|
22
23
|
export { Pagination } from "./pagination/index.js";
|
|
23
24
|
export { PinInput } from "./pin-input/index.js";
|
package/dist/bits/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export { DropdownMenu } from "./dropdown-menu/index.js";
|
|
|
18
18
|
export { Label } from "./label/index.js";
|
|
19
19
|
export { LinkPreview } from "./link-preview/index.js";
|
|
20
20
|
export { Menubar } from "./menubar/index.js";
|
|
21
|
+
export { Meter } from "./meter/index.js";
|
|
21
22
|
export { NavigationMenu } from "./navigation-menu/index.js";
|
|
22
23
|
export { Pagination } from "./pagination/index.js";
|
|
23
24
|
export { PinInput } from "./pin-input/index.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { box, mergeProps } from "svelte-toolbelt";
|
|
3
|
+
import type { MeterRootProps } from "../types.js";
|
|
4
|
+
import { useMeterRootState } from "../meter.svelte.js";
|
|
5
|
+
import { useId } from "../../../internal/use-id.js";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
child,
|
|
9
|
+
children,
|
|
10
|
+
value = 0,
|
|
11
|
+
max = 100,
|
|
12
|
+
min = 0,
|
|
13
|
+
id = useId(),
|
|
14
|
+
ref = $bindable(null),
|
|
15
|
+
...restProps
|
|
16
|
+
}: MeterRootProps = $props();
|
|
17
|
+
|
|
18
|
+
const rootState = useMeterRootState({
|
|
19
|
+
value: box.with(() => value),
|
|
20
|
+
max: box.with(() => max),
|
|
21
|
+
min: box.with(() => min),
|
|
22
|
+
id: box.with(() => id),
|
|
23
|
+
ref: box.with(
|
|
24
|
+
() => ref,
|
|
25
|
+
(v) => (ref = v)
|
|
26
|
+
),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const mergedProps = $derived(mergeProps(restProps, rootState.props));
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
{#if child}
|
|
33
|
+
{@render child({ props: mergedProps })}
|
|
34
|
+
{:else}
|
|
35
|
+
<div {...mergedProps}>
|
|
36
|
+
{@render children?.()}
|
|
37
|
+
</div>
|
|
38
|
+
{/if}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Root } from "./components/meter.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Meter from "./exports.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Meter from "./exports.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReadableBoxedValues } from "../../internal/box.svelte.js";
|
|
2
|
+
import type { WithRefProps } from "../../internal/types.js";
|
|
3
|
+
type MeterRootStateProps = WithRefProps<ReadableBoxedValues<{
|
|
4
|
+
value: number;
|
|
5
|
+
max: number;
|
|
6
|
+
min: number;
|
|
7
|
+
}>>;
|
|
8
|
+
declare class MeterRootState {
|
|
9
|
+
readonly opts: MeterRootStateProps;
|
|
10
|
+
constructor(opts: MeterRootStateProps);
|
|
11
|
+
props: {
|
|
12
|
+
readonly role: "meter";
|
|
13
|
+
readonly value: number;
|
|
14
|
+
readonly "aria-valuemin": number;
|
|
15
|
+
readonly "aria-valuemax": number;
|
|
16
|
+
readonly "aria-valuenow": number;
|
|
17
|
+
readonly "data-value": number;
|
|
18
|
+
readonly "data-max": number;
|
|
19
|
+
readonly "data-min": number;
|
|
20
|
+
readonly "data-meter-root": "";
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function useMeterRootState(props: MeterRootStateProps): MeterRootState;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useRefById } from "svelte-toolbelt";
|
|
2
|
+
const METER_ROOT_ATTR = "data-meter-root";
|
|
3
|
+
class MeterRootState {
|
|
4
|
+
opts;
|
|
5
|
+
constructor(opts) {
|
|
6
|
+
this.opts = opts;
|
|
7
|
+
useRefById(opts);
|
|
8
|
+
}
|
|
9
|
+
props = $derived.by(() => ({
|
|
10
|
+
role: "meter",
|
|
11
|
+
value: this.opts.value.current,
|
|
12
|
+
"aria-valuemin": this.opts.min.current,
|
|
13
|
+
"aria-valuemax": this.opts.max.current,
|
|
14
|
+
"aria-valuenow": this.opts.value.current,
|
|
15
|
+
"data-value": this.opts.value.current,
|
|
16
|
+
"data-max": this.opts.max.current,
|
|
17
|
+
"data-min": this.opts.min.current,
|
|
18
|
+
[METER_ROOT_ATTR]: "",
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
export function useMeterRootState(props) {
|
|
22
|
+
return new MeterRootState(props);
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WithChild, Without } from "../../internal/types.js";
|
|
2
|
+
import type { BitsPrimitiveDivAttributes } from "../../shared/attributes.js";
|
|
3
|
+
export type MeterRootPropsWithoutHTML = WithChild<{
|
|
4
|
+
/**
|
|
5
|
+
* The current value of the meter.
|
|
6
|
+
*
|
|
7
|
+
* @default 0
|
|
8
|
+
*/
|
|
9
|
+
value?: number;
|
|
10
|
+
/**
|
|
11
|
+
* The maximum value of the meter.
|
|
12
|
+
*
|
|
13
|
+
* @default 100
|
|
14
|
+
*/
|
|
15
|
+
max?: number;
|
|
16
|
+
/**
|
|
17
|
+
* The minimum value of the meter.
|
|
18
|
+
*
|
|
19
|
+
* @default 0
|
|
20
|
+
*/
|
|
21
|
+
min?: number;
|
|
22
|
+
}>;
|
|
23
|
+
export type MeterRootProps = MeterRootPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, MeterRootPropsWithoutHTML>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -50,6 +50,13 @@ class RadioGroupItemState {
|
|
|
50
50
|
id: this.opts.id,
|
|
51
51
|
ref: this.opts.ref,
|
|
52
52
|
});
|
|
53
|
+
if (this.opts.value.current === this.root.opts.value.current) {
|
|
54
|
+
this.root.rovingFocusGroup.setCurrentTabStopId(this.opts.id.current);
|
|
55
|
+
this.#tabIndex = 0;
|
|
56
|
+
}
|
|
57
|
+
else if (!this.root.opts.value.current) {
|
|
58
|
+
this.#tabIndex = 0;
|
|
59
|
+
}
|
|
53
60
|
$effect(() => {
|
|
54
61
|
this.#tabIndex = this.root.rovingFocusGroup.getTabIndex(this.opts.ref.current);
|
|
55
62
|
});
|
|
@@ -77,7 +84,7 @@ class RadioGroupItemState {
|
|
|
77
84
|
}
|
|
78
85
|
this.root.rovingFocusGroup.handleKeydown(this.opts.ref.current, e, true);
|
|
79
86
|
}
|
|
80
|
-
#tabIndex = $state(
|
|
87
|
+
#tabIndex = $state(-1);
|
|
81
88
|
snippetProps = $derived.by(() => ({ checked: this.#isChecked }));
|
|
82
89
|
props = $derived.by(() => ({
|
|
83
90
|
id: this.opts.id.current,
|
|
@@ -131,10 +131,6 @@ declare class SelectTriggerState {
|
|
|
131
131
|
constructor(opts: SelectTriggerStateProps, root: SelectRootState);
|
|
132
132
|
onkeydown(e: BitsKeyboardEvent): void;
|
|
133
133
|
onclick(e: BitsMouseEvent): void;
|
|
134
|
-
/**
|
|
135
|
-
* `pointerdown` fires before the `focus` event, so we can prevent the default
|
|
136
|
-
* behavior of focusing the button and keep focus on the input.
|
|
137
|
-
*/
|
|
138
134
|
onpointerdown(e: BitsPointerEvent): void;
|
|
139
135
|
onpointerup(e: BitsPointerEvent): void;
|
|
140
136
|
props: {
|
|
@@ -339,6 +335,7 @@ declare class SelectScrollDownButtonState {
|
|
|
339
335
|
content: SelectContentState;
|
|
340
336
|
root: SelectBaseRootState;
|
|
341
337
|
canScrollDown: boolean;
|
|
338
|
+
scrollIntoViewTimer: ReturnType<typeof globalThis.setTimeout> | null;
|
|
342
339
|
constructor(state: SelectScrollButtonImplState);
|
|
343
340
|
/**
|
|
344
341
|
* @param manual - if true, it means the function was invoked manually outside of an event
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Previous, watch } from "runed";
|
|
2
|
-
import { afterTick, onDestroyEffect, srOnlyStyles, styleToString, useRefById, } from "svelte-toolbelt";
|
|
2
|
+
import { afterSleep, afterTick, onDestroyEffect, srOnlyStyles, styleToString, useRefById, } from "svelte-toolbelt";
|
|
3
3
|
import { on } from "svelte/events";
|
|
4
4
|
import { backward, forward, next, prev } from "../../internal/arrays.js";
|
|
5
5
|
import { getAriaExpanded, getAriaHidden, getDataDisabled, getDataOpenClosed, getDisabled, getRequired, } from "../../internal/attrs.js";
|
|
@@ -163,6 +163,11 @@ class SelectMultipleRootState extends SelectBaseRootState {
|
|
|
163
163
|
constructor(opts) {
|
|
164
164
|
super(opts);
|
|
165
165
|
this.opts = opts;
|
|
166
|
+
$effect(() => {
|
|
167
|
+
if (!this.opts.open.current && this.highlightedNode) {
|
|
168
|
+
this.setHighlightedNode(null);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
166
171
|
watch(() => this.opts.open.current, () => {
|
|
167
172
|
if (!this.opts.open.current)
|
|
168
173
|
return;
|
|
@@ -484,6 +489,7 @@ class SelectTriggerState {
|
|
|
484
489
|
}
|
|
485
490
|
if (!this.root.isMulti && !isCurrentSelectedValue) {
|
|
486
491
|
this.root.handleClose();
|
|
492
|
+
return;
|
|
487
493
|
}
|
|
488
494
|
}
|
|
489
495
|
if (e.key === kbd.ARROW_UP && e.altKey) {
|
|
@@ -546,10 +552,6 @@ class SelectTriggerState {
|
|
|
546
552
|
const currTarget = e.currentTarget;
|
|
547
553
|
currTarget.focus();
|
|
548
554
|
}
|
|
549
|
-
/**
|
|
550
|
-
* `pointerdown` fires before the `focus` event, so we can prevent the default
|
|
551
|
-
* behavior of focusing the button and keep focus on the input.
|
|
552
|
-
*/
|
|
553
555
|
onpointerdown(e) {
|
|
554
556
|
if (this.root.opts.disabled.current)
|
|
555
557
|
return;
|
|
@@ -566,7 +568,6 @@ class SelectTriggerState {
|
|
|
566
568
|
if (e.button === 0 && e.ctrlKey === false) {
|
|
567
569
|
if (this.root.opts.open.current === false) {
|
|
568
570
|
this.#handlePointerOpen(e);
|
|
569
|
-
e.preventDefault();
|
|
570
571
|
}
|
|
571
572
|
else {
|
|
572
573
|
this.root.handleClose();
|
|
@@ -908,15 +909,13 @@ class SelectScrollButtonImplState {
|
|
|
908
909
|
...opts,
|
|
909
910
|
deps: () => this.mounted,
|
|
910
911
|
});
|
|
911
|
-
watch(() => this.mounted, () => {
|
|
912
|
+
watch([() => this.mounted], () => {
|
|
912
913
|
if (!this.mounted) {
|
|
913
914
|
this.isUserScrolling = false;
|
|
914
915
|
return;
|
|
915
916
|
}
|
|
916
917
|
if (this.isUserScrolling)
|
|
917
918
|
return;
|
|
918
|
-
const activeItem = this.root.highlightedNode;
|
|
919
|
-
activeItem?.scrollIntoView({ block: "nearest" });
|
|
920
919
|
});
|
|
921
920
|
$effect(() => {
|
|
922
921
|
if (this.mounted)
|
|
@@ -973,24 +972,30 @@ class SelectScrollDownButtonState {
|
|
|
973
972
|
content;
|
|
974
973
|
root;
|
|
975
974
|
canScrollDown = $state(false);
|
|
975
|
+
scrollIntoViewTimer = null;
|
|
976
976
|
constructor(state) {
|
|
977
977
|
this.state = state;
|
|
978
978
|
this.content = state.content;
|
|
979
979
|
this.root = state.root;
|
|
980
980
|
this.state.onAutoScroll = this.handleAutoScroll;
|
|
981
|
-
watch([
|
|
982
|
-
(
|
|
983
|
-
() => this.content.isPositioned,
|
|
984
|
-
() => this.root.opts.open.current,
|
|
985
|
-
], () => {
|
|
986
|
-
if (!this.content.viewportNode ||
|
|
987
|
-
!this.content.isPositioned ||
|
|
988
|
-
!this.root.opts.open.current) {
|
|
981
|
+
watch([() => this.content.viewportNode, () => this.content.isPositioned], () => {
|
|
982
|
+
if (!this.content.viewportNode || !this.content.isPositioned) {
|
|
989
983
|
return;
|
|
990
984
|
}
|
|
991
985
|
this.handleScroll(true);
|
|
992
986
|
return on(this.content.viewportNode, "scroll", () => this.handleScroll());
|
|
993
987
|
});
|
|
988
|
+
watch(() => this.state.mounted, () => {
|
|
989
|
+
if (!this.state.mounted)
|
|
990
|
+
return;
|
|
991
|
+
if (this.scrollIntoViewTimer) {
|
|
992
|
+
clearTimeout(this.scrollIntoViewTimer);
|
|
993
|
+
}
|
|
994
|
+
this.scrollIntoViewTimer = afterSleep(5, () => {
|
|
995
|
+
const activeItem = this.root.highlightedNode;
|
|
996
|
+
activeItem?.scrollIntoView({ block: "nearest" });
|
|
997
|
+
});
|
|
998
|
+
});
|
|
994
999
|
}
|
|
995
1000
|
/**
|
|
996
1001
|
* @param manual - if true, it means the function was invoked manually outside of an event
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Accordion, AlertDialog, AspectRatio, Avatar, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, ScrollArea, Select, Separator, Slider, Switch, Tabs, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, } from "./bits/index.js";
|
|
1
|
+
export { Accordion, AlertDialog, AspectRatio, Avatar, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, ScrollArea, Select, Separator, Slider, Switch, Tabs, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, } from "./bits/index.js";
|
|
2
2
|
export * from "./shared/index.js";
|
|
3
3
|
export type * from "./shared/index.js";
|
|
4
4
|
export * from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Accordion, AlertDialog, AspectRatio, Avatar, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, ScrollArea, Select, Separator, Slider, Switch, Tabs, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, } from "./bits/index.js";
|
|
1
|
+
export { Accordion, AlertDialog, AspectRatio, Avatar, Button, Calendar, Checkbox, Collapsible, Combobox, Command, ContextMenu, DateField, DatePicker, DateRangeField, DateRangePicker, Dialog, DropdownMenu, Label, LinkPreview, Menubar, Meter, NavigationMenu, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, ScrollArea, Select, Separator, Slider, Switch, Tabs, Toggle, ToggleGroup, Toolbar, Tooltip, Portal, IsUsingKeyboard, computeCommandScore, } from "./bits/index.js";
|
|
2
2
|
export * from "./shared/index.js";
|
|
3
3
|
export * from "./types.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export type * from "./bits/label/types.js";
|
|
|
19
19
|
export type * from "./bits/link-preview/types.js";
|
|
20
20
|
export type * from "./bits/select/types.js";
|
|
21
21
|
export type * from "./bits/menubar/types.js";
|
|
22
|
+
export type * from "./bits/meter/types.js";
|
|
22
23
|
export type * from "./bits/navigation-menu/types.js";
|
|
23
24
|
export type * from "./bits/pagination/types.js";
|
|
24
25
|
export type * from "./bits/pin-input/types.js";
|