bits-ui 2.2.1 → 2.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.
Files changed (98) hide show
  1. package/dist/bits/accordion/accordion.svelte.d.ts +0 -5
  2. package/dist/bits/accordion/accordion.svelte.js +11 -14
  3. package/dist/bits/aspect-ratio/aspect-ratio.svelte.d.ts +0 -1
  4. package/dist/bits/aspect-ratio/aspect-ratio.svelte.js +6 -2
  5. package/dist/bits/avatar/avatar.svelte.d.ts +0 -3
  6. package/dist/bits/avatar/avatar.svelte.js +8 -6
  7. package/dist/bits/calendar/calendar.svelte.d.ts +2 -2
  8. package/dist/bits/calendar/calendar.svelte.js +4 -4
  9. package/dist/bits/checkbox/checkbox.svelte.d.ts +0 -3
  10. package/dist/bits/checkbox/checkbox.svelte.js +14 -14
  11. package/dist/bits/collapsible/collapsible.svelte.d.ts +0 -3
  12. package/dist/bits/collapsible/collapsible.svelte.js +8 -7
  13. package/dist/bits/command/command.svelte.d.ts +0 -12
  14. package/dist/bits/command/command.svelte.js +35 -31
  15. package/dist/bits/date-field/date-field.svelte.d.ts +2 -4
  16. package/dist/bits/date-field/date-field.svelte.js +8 -6
  17. package/dist/bits/date-picker/components/date-picker-trigger.svelte +2 -2
  18. package/dist/bits/date-range-field/date-range-field.svelte.d.ts +1 -3
  19. package/dist/bits/date-range-field/date-range-field.svelte.js +7 -5
  20. package/dist/bits/date-range-picker/components/date-range-picker-trigger.svelte +2 -2
  21. package/dist/bits/dialog/dialog.svelte.d.ts +2 -12
  22. package/dist/bits/dialog/dialog.svelte.js +16 -24
  23. package/dist/bits/index.d.ts +1 -0
  24. package/dist/bits/index.js +1 -0
  25. package/dist/bits/label/label.svelte.d.ts +0 -1
  26. package/dist/bits/label/label.svelte.js +6 -2
  27. package/dist/bits/link-preview/link-preview.svelte.d.ts +0 -2
  28. package/dist/bits/link-preview/link-preview.svelte.js +7 -5
  29. package/dist/bits/menu/components/menu-sub-content-static.svelte +1 -1
  30. package/dist/bits/menu/components/menu-sub-content.svelte +1 -1
  31. package/dist/bits/menu/menu.svelte.d.ts +2 -1
  32. package/dist/bits/menu/menu.svelte.js +39 -21
  33. package/dist/bits/menubar/menubar.svelte.d.ts +1 -7
  34. package/dist/bits/menubar/menubar.svelte.js +12 -14
  35. package/dist/bits/meter/meter.svelte.d.ts +0 -1
  36. package/dist/bits/meter/meter.svelte.js +6 -2
  37. package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +2 -11
  38. package/dist/bits/navigation-menu/navigation-menu.svelte.js +30 -25
  39. package/dist/bits/pagination/pagination.svelte.d.ts +0 -4
  40. package/dist/bits/pagination/pagination.svelte.js +9 -10
  41. package/dist/bits/pin-input/pin-input.svelte.d.ts +0 -2
  42. package/dist/bits/pin-input/pin-input.svelte.js +7 -5
  43. package/dist/bits/popover/popover.svelte.d.ts +0 -3
  44. package/dist/bits/popover/popover.svelte.js +9 -5
  45. package/dist/bits/progress/progress.svelte.d.ts +0 -1
  46. package/dist/bits/progress/progress.svelte.js +6 -2
  47. package/dist/bits/radio-group/radio-group.svelte.d.ts +7 -9
  48. package/dist/bits/radio-group/radio-group.svelte.js +9 -10
  49. package/dist/bits/range-calendar/range-calendar.svelte.d.ts +38 -38
  50. package/dist/bits/range-calendar/range-calendar.svelte.js +79 -79
  51. package/dist/bits/rating-group/components/rating-group-input.svelte +10 -0
  52. package/dist/bits/rating-group/components/rating-group-input.svelte.d.ts +18 -0
  53. package/dist/bits/rating-group/components/rating-group-item.svelte +38 -0
  54. package/dist/bits/rating-group/components/rating-group-item.svelte.d.ts +4 -0
  55. package/dist/bits/rating-group/components/rating-group.svelte +80 -0
  56. package/dist/bits/rating-group/components/rating-group.svelte.d.ts +4 -0
  57. package/dist/bits/rating-group/exports.d.ts +3 -0
  58. package/dist/bits/rating-group/exports.js +2 -0
  59. package/dist/bits/rating-group/index.d.ts +1 -0
  60. package/dist/bits/rating-group/index.js +1 -0
  61. package/dist/bits/rating-group/rating-group.svelte.d.ts +112 -0
  62. package/dist/bits/rating-group/rating-group.svelte.js +317 -0
  63. package/dist/bits/rating-group/types.d.ts +111 -0
  64. package/dist/bits/rating-group/types.js +1 -0
  65. package/dist/bits/scroll-area/scroll-area.svelte.d.ts +15 -19
  66. package/dist/bits/scroll-area/scroll-area.svelte.js +10 -10
  67. package/dist/bits/select/select.svelte.d.ts +28 -30
  68. package/dist/bits/select/select.svelte.js +36 -48
  69. package/dist/bits/separator/separator.svelte.d.ts +1 -2
  70. package/dist/bits/separator/separator.svelte.js +6 -3
  71. package/dist/bits/slider/slider.svelte.d.ts +17 -24
  72. package/dist/bits/slider/slider.svelte.js +15 -17
  73. package/dist/bits/switch/switch.svelte.d.ts +6 -8
  74. package/dist/bits/switch/switch.svelte.js +7 -5
  75. package/dist/bits/tabs/tabs.svelte.d.ts +5 -9
  76. package/dist/bits/tabs/tabs.svelte.js +11 -11
  77. package/dist/bits/time-field/time-field.svelte.d.ts +1 -3
  78. package/dist/bits/time-field/time-field.svelte.js +7 -5
  79. package/dist/bits/time-range-field/time-range-field.svelte.d.ts +1 -3
  80. package/dist/bits/time-range-field/time-range-field.svelte.js +7 -5
  81. package/dist/bits/toggle/toggle.svelte.d.ts +3 -3
  82. package/dist/bits/toggle/toggle.svelte.js +6 -3
  83. package/dist/bits/toggle-group/toggle-group.svelte.d.ts +1 -2
  84. package/dist/bits/toggle-group/toggle-group.svelte.js +8 -6
  85. package/dist/bits/toolbar/toolbar.svelte.d.ts +11 -18
  86. package/dist/bits/toolbar/toolbar.svelte.js +14 -17
  87. package/dist/bits/tooltip/tooltip.svelte.d.ts +13 -14
  88. package/dist/bits/tooltip/tooltip.svelte.js +7 -5
  89. package/dist/index.d.ts +1 -1
  90. package/dist/index.js +1 -1
  91. package/dist/internal/attrs.d.ts +14 -0
  92. package/dist/internal/attrs.js +18 -0
  93. package/dist/internal/date-time/calendar-helpers.svelte.d.ts +1 -0
  94. package/dist/internal/date-time/calendar-helpers.svelte.js +18 -1
  95. package/dist/internal/use-arrow-navigation.d.ts +2 -2
  96. package/dist/internal/use-arrow-navigation.js +1 -1
  97. package/dist/types.d.ts +1 -0
  98. package/package.json +1 -1
@@ -48,7 +48,6 @@ declare abstract class AccordionBaseState {
48
48
  readonly id: string;
49
49
  readonly "data-orientation": "horizontal" | "vertical";
50
50
  readonly "data-disabled": "" | undefined;
51
- readonly "data-accordion-root": "";
52
51
  };
53
52
  }
54
53
  export declare class AccordionSingleState extends AccordionBaseState {
@@ -77,7 +76,6 @@ export declare class AccordionItemState {
77
76
  readonly "data-state": "open" | "closed";
78
77
  readonly "data-disabled": "" | undefined;
79
78
  readonly "data-orientation": "horizontal" | "vertical";
80
- readonly "data-accordion-item": "";
81
79
  };
82
80
  }
83
81
  declare class AccordionTriggerState {
@@ -95,7 +93,6 @@ declare class AccordionTriggerState {
95
93
  readonly "data-disabled": "" | undefined;
96
94
  readonly "data-state": "open" | "closed";
97
95
  readonly "data-orientation": "horizontal" | "vertical";
98
- readonly "data-accordion-trigger": "";
99
96
  readonly tabindex: 0;
100
97
  readonly onclick: (e: BitsMouseEvent) => void;
101
98
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
@@ -115,7 +112,6 @@ declare class AccordionContentState {
115
112
  readonly "data-state": "open" | "closed";
116
113
  readonly "data-disabled": "" | undefined;
117
114
  readonly "data-orientation": "horizontal" | "vertical";
118
- readonly "data-accordion-content": "";
119
115
  readonly style: {
120
116
  readonly "--bits-accordion-content-height": `${number}px`;
121
117
  readonly "--bits-accordion-content-width": `${number}px`;
@@ -133,7 +129,6 @@ declare class AccordionHeaderState {
133
129
  readonly "data-heading-level": 1 | 2 | 3 | 4 | 6 | 5;
134
130
  readonly "data-state": "open" | "closed";
135
131
  readonly "data-orientation": "horizontal" | "vertical";
136
- readonly "data-accordion-header": "";
137
132
  };
138
133
  }
139
134
  export declare function useAccordionRoot(props: InitAccordionProps): AccordionState;
@@ -3,14 +3,11 @@ import { Context, watch } from "runed";
3
3
  import { getAriaDisabled, getAriaExpanded, getDataDisabled, getDataOpenClosed, getDataOrientation, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
5
  import { useRovingFocus, } from "../../internal/use-roving-focus.svelte.js";
6
- // Constants
7
- const ACCORDION_ATTRS = {
8
- ROOT: "data-accordion-root",
9
- TRIGGER: "data-accordion-trigger",
10
- CONTENT: "data-accordion-content",
11
- ITEM: "data-accordion-item",
12
- HEADER: "data-accordion-header",
13
- };
6
+ import { createBitsAttrs } from "../../internal/attrs.js";
7
+ const accordionAttrs = createBitsAttrs({
8
+ component: "accordion",
9
+ parts: ["root", "trigger", "content", "item", "header"],
10
+ });
14
11
  // Base class
15
12
  class AccordionBaseState {
16
13
  opts;
@@ -19,7 +16,7 @@ class AccordionBaseState {
19
16
  this.opts = opts;
20
17
  this.rovingFocusGroup = useRovingFocus({
21
18
  rootNode: this.opts.ref,
22
- candidateAttr: ACCORDION_ATTRS.TRIGGER,
19
+ candidateAttr: accordionAttrs.trigger,
23
20
  loop: this.opts.loop,
24
21
  orientation: this.opts.orientation,
25
22
  });
@@ -28,7 +25,7 @@ class AccordionBaseState {
28
25
  id: this.opts.id.current,
29
26
  "data-orientation": getDataOrientation(this.opts.orientation.current),
30
27
  "data-disabled": getDataDisabled(this.opts.disabled.current),
31
- [ACCORDION_ATTRS.ROOT]: "",
28
+ [accordionAttrs.root]: "",
32
29
  ...attachRef(this.opts.ref),
33
30
  }));
34
31
  }
@@ -78,7 +75,7 @@ export class AccordionItemState {
78
75
  "data-state": getDataOpenClosed(this.isActive),
79
76
  "data-disabled": getDataDisabled(this.isDisabled),
80
77
  "data-orientation": getDataOrientation(this.root.opts.orientation.current),
81
- [ACCORDION_ATTRS.ITEM]: "",
78
+ [accordionAttrs.item]: "",
82
79
  ...attachRef(this.opts.ref),
83
80
  }));
84
81
  }
@@ -120,7 +117,7 @@ class AccordionTriggerState {
120
117
  "data-disabled": getDataDisabled(this.#isDisabled),
121
118
  "data-state": getDataOpenClosed(this.itemState.isActive),
122
119
  "data-orientation": getDataOrientation(this.#root.opts.orientation.current),
123
- [ACCORDION_ATTRS.TRIGGER]: "",
120
+ [accordionAttrs.trigger]: "",
124
121
  tabindex: 0,
125
122
  onclick: this.onclick,
126
123
  onkeydown: this.onkeydown,
@@ -179,7 +176,7 @@ class AccordionContentState {
179
176
  "data-state": getDataOpenClosed(this.item.isActive),
180
177
  "data-disabled": getDataDisabled(this.item.isDisabled),
181
178
  "data-orientation": getDataOrientation(this.item.root.opts.orientation.current),
182
- [ACCORDION_ATTRS.CONTENT]: "",
179
+ [accordionAttrs.content]: "",
183
180
  style: {
184
181
  "--bits-accordion-content-height": `${this.#dimensions.height}px`,
185
182
  "--bits-accordion-content-width": `${this.#dimensions.width}px`,
@@ -202,7 +199,7 @@ class AccordionHeaderState {
202
199
  "data-heading-level": this.opts.level.current,
203
200
  "data-state": getDataOpenClosed(this.item.isActive),
204
201
  "data-orientation": getDataOrientation(this.item.root.opts.orientation.current),
205
- [ACCORDION_ATTRS.HEADER]: "",
202
+ [accordionAttrs.header]: "",
206
203
  ...attachRef(this.opts.ref),
207
204
  }));
208
205
  }
@@ -22,7 +22,6 @@ declare class AspectRatioRootState {
22
22
  readonly bottom: 0;
23
23
  readonly left: 0;
24
24
  };
25
- readonly "data-aspect-ratio-root": "";
26
25
  };
27
26
  }
28
27
  export declare function useAspectRatioRoot(props: AspectRatioRootStateProps): AspectRatioRootState;
@@ -1,5 +1,9 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
- const ASPECT_RATIO_ROOT_ATTR = "data-aspect-ratio-root";
2
+ import { createBitsAttrs } from "../../internal/attrs.js";
3
+ const aspectRatioAttrs = createBitsAttrs({
4
+ component: "aspect-ratio",
5
+ parts: ["root"],
6
+ });
3
7
  class AspectRatioRootState {
4
8
  opts;
5
9
  constructor(opts) {
@@ -21,7 +25,7 @@ class AspectRatioRootState {
21
25
  bottom: 0,
22
26
  left: 0,
23
27
  },
24
- [ASPECT_RATIO_ROOT_ATTR]: "",
28
+ [aspectRatioAttrs.root]: "",
25
29
  ...attachRef(this.opts.ref),
26
30
  }));
27
31
  }
@@ -20,7 +20,6 @@ declare class AvatarRootState {
20
20
  loadImage(src: string, crossorigin?: CrossOrigin, referrerPolicy?: ReferrerPolicy): (() => void) | undefined;
21
21
  props: {
22
22
  readonly id: string;
23
- readonly "data-avatar-root": "";
24
23
  readonly "data-status": AvatarImageLoadingStatus;
25
24
  };
26
25
  }
@@ -42,7 +41,6 @@ declare class AvatarImageState {
42
41
  readonly display: "none" | "block";
43
42
  };
44
43
  readonly "data-status": AvatarImageLoadingStatus;
45
- readonly "data-avatar-image": "";
46
44
  readonly src: AvatarImageSrc;
47
45
  readonly crossorigin: "" | "anonymous" | "use-credentials" | null | undefined;
48
46
  readonly referrerpolicy: globalThis.ReferrerPolicy | null | undefined;
@@ -64,7 +62,6 @@ declare class AvatarFallbackState {
64
62
  display: string;
65
63
  } | undefined;
66
64
  readonly "data-status": AvatarImageLoadingStatus;
67
- readonly "data-avatar-fallback": "";
68
65
  };
69
66
  }
70
67
  export declare function useAvatarRoot(props: AvatarRootStateProps): AvatarRootState;
@@ -1,9 +1,11 @@
1
1
  import { untrack } from "svelte";
2
2
  import { DOMContext, attachRef } from "svelte-toolbelt";
3
3
  import { Context } from "runed";
4
- const AVATAR_ROOT_ATTR = "data-avatar-root";
5
- const AVATAR_IMAGE_ATTR = "data-avatar-image";
6
- const AVATAR_FALLBACK_ATTR = "data-avatar-fallback";
4
+ import { createBitsAttrs } from "../../internal/attrs.js";
5
+ const avatarAttrs = createBitsAttrs({
6
+ component: "avatar",
7
+ parts: ["root", "image", "fallback"],
8
+ });
7
9
  class AvatarRootState {
8
10
  opts;
9
11
  domContext;
@@ -37,7 +39,7 @@ class AvatarRootState {
37
39
  }
38
40
  props = $derived.by(() => ({
39
41
  id: this.opts.id.current,
40
- [AVATAR_ROOT_ATTR]: "",
42
+ [avatarAttrs.root]: "",
41
43
  "data-status": this.opts.loadingStatus.current,
42
44
  ...attachRef(this.opts.ref),
43
45
  }));
@@ -64,7 +66,7 @@ class AvatarImageState {
64
66
  display: this.root.opts.loadingStatus.current === "loaded" ? "block" : "none",
65
67
  },
66
68
  "data-status": this.root.opts.loadingStatus.current,
67
- [AVATAR_IMAGE_ATTR]: "",
69
+ [avatarAttrs.image]: "",
68
70
  src: this.opts.src.current,
69
71
  crossorigin: this.opts.crossOrigin.current,
70
72
  referrerpolicy: this.opts.referrerPolicy.current,
@@ -82,7 +84,7 @@ class AvatarFallbackState {
82
84
  props = $derived.by(() => ({
83
85
  style: this.style,
84
86
  "data-status": this.root.opts.loadingStatus.current,
85
- [AVATAR_FALLBACK_ATTR]: "",
87
+ [avatarAttrs.fallback]: "",
86
88
  ...attachRef(this.opts.ref),
87
89
  }));
88
90
  }
@@ -7,7 +7,7 @@ import type { BitsKeyboardEvent, BitsMouseEvent, WithRefProps } from "../../inte
7
7
  import type { DateMatcher, Month } from "../../shared/index.js";
8
8
  import { type Announcer } from "../../internal/date-time/announcer.js";
9
9
  import { type Formatter } from "../../internal/date-time/formatter.js";
10
- import { type CalendarParts } from "../../internal/date-time/calendar-helpers.svelte.js";
10
+ import { calendarAttrs } from "../../internal/date-time/calendar-helpers.svelte.js";
11
11
  import type { WeekStartsOn } from "../../shared/date/types.js";
12
12
  type CalendarRootStateProps = WithRefProps<WritableBoxedValues<{
13
13
  value: DateValue | undefined | DateValue[];
@@ -86,7 +86,7 @@ export declare class CalendarRootState {
86
86
  months: Month<DateValue>[];
87
87
  weekdays: string[];
88
88
  };
89
- getBitsAttr(part: CalendarParts): string;
89
+ getBitsAttr: (typeof calendarAttrs)["getAttr"];
90
90
  props: {
91
91
  readonly onkeydown: (event: BitsKeyboardEvent) => void;
92
92
  readonly id: string;
@@ -7,7 +7,7 @@ import { getAriaDisabled, getAriaHidden, getAriaReadonly, getAriaSelected, getDa
7
7
  import { useId } from "../../internal/use-id.js";
8
8
  import { getAnnouncer } from "../../internal/date-time/announcer.js";
9
9
  import { createFormatter } from "../../internal/date-time/formatter.js";
10
- import { createAccessibleHeading, createMonths, getCalendarElementProps, getCalendarHeadingValue, getDateWithPreviousTime, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
10
+ import { calendarAttrs, createAccessibleHeading, createMonths, getCalendarElementProps, getCalendarHeadingValue, getDateWithPreviousTime, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
11
11
  import { getDateValueType, isBefore, toDate } from "../../internal/date-time/utils.js";
12
12
  export class CalendarRootState {
13
13
  opts;
@@ -364,9 +364,9 @@ export class CalendarRootState {
364
364
  months: this.months,
365
365
  weekdays: this.weekdays,
366
366
  }));
367
- getBitsAttr(part) {
368
- return `data-bits-calendar-${part}`;
369
- }
367
+ getBitsAttr = (part) => {
368
+ return calendarAttrs.getAttr(part);
369
+ };
370
370
  props = $derived.by(() => ({
371
371
  ...getCalendarElementProps({
372
372
  fullCalendarLabel: this.fullCalendarLabel,
@@ -21,7 +21,6 @@ declare class CheckboxGroupState {
21
21
  readonly role: "group";
22
22
  readonly "aria-labelledby": string | undefined;
23
23
  readonly "data-disabled": "" | undefined;
24
- readonly "data-checkbox-group": "";
25
24
  };
26
25
  }
27
26
  type CheckboxGroupLabelStateProps = WithRefProps;
@@ -32,7 +31,6 @@ declare class CheckboxGroupLabelState {
32
31
  props: {
33
32
  readonly id: string;
34
33
  readonly "data-disabled": "" | undefined;
35
- readonly "data-checkbox-group-label": "";
36
34
  };
37
35
  }
38
36
  type CheckboxRootStateProps = WithRefProps<ReadableBoxedValues<{
@@ -68,7 +66,6 @@ declare class CheckboxRootState {
68
66
  readonly "aria-required": "true" | "false";
69
67
  readonly "data-disabled": "" | undefined;
70
68
  readonly "data-state": "checked" | "indeterminate" | "unchecked";
71
- readonly "data-checkbox-root": "";
72
69
  readonly onclick: (_: BitsMouseEvent) => void;
73
70
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
74
71
  };
@@ -1,10 +1,11 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
2
  import { Context, watch } from "runed";
3
- import { getAriaChecked, getAriaRequired, getDataDisabled } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, getAriaChecked, getAriaRequired, getDataDisabled, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
- const CHECKBOX_ROOT_ATTR = "data-checkbox-root";
6
- const CHECKBOX_GROUP_ATTR = "data-checkbox-group";
7
- const CHECKBOX_GROUP_LABEL_ATTR = "data-checkbox-group-label";
5
+ const checkboxAttrs = createBitsAttrs({
6
+ component: "checkbox",
7
+ parts: ["root", "group", "group-label", "input"],
8
+ });
8
9
  class CheckboxGroupState {
9
10
  opts;
10
11
  labelId = $state(undefined);
@@ -35,7 +36,7 @@ class CheckboxGroupState {
35
36
  role: "group",
36
37
  "aria-labelledby": this.labelId,
37
38
  "data-disabled": getDataDisabled(this.opts.disabled.current),
38
- [CHECKBOX_GROUP_ATTR]: "",
39
+ [checkboxAttrs.group]: "",
39
40
  ...attachRef(this.opts.ref),
40
41
  }));
41
42
  }
@@ -49,7 +50,7 @@ class CheckboxGroupLabelState {
49
50
  props = $derived.by(() => ({
50
51
  id: this.opts.id.current,
51
52
  "data-disabled": getDataDisabled(this.group.opts.disabled.current),
52
- [CHECKBOX_GROUP_LABEL_ATTR]: "",
53
+ [checkboxAttrs["group-label"]]: "",
53
54
  ...attachRef(this.opts.ref, (v) => (this.group.labelId = v?.id)),
54
55
  }));
55
56
  }
@@ -134,7 +135,7 @@ class CheckboxRootState {
134
135
  "aria-required": getAriaRequired(this.trueRequired),
135
136
  "data-disabled": getDataDisabled(this.trueDisabled),
136
137
  "data-state": getCheckboxDataState(this.opts.checked.current, this.opts.indeterminate.current),
137
- [CHECKBOX_ROOT_ATTR]: "",
138
+ [checkboxAttrs.root]: "",
138
139
  //
139
140
  onclick: this.onclick,
140
141
  onkeydown: this.onkeydown,
@@ -147,14 +148,13 @@ class CheckboxRootState {
147
148
  class CheckboxInputState {
148
149
  root;
149
150
  trueChecked = $derived.by(() => {
150
- if (this.root.group) {
151
- if (this.root.opts.value.current !== undefined &&
152
- this.root.group.opts.value.current.includes(this.root.opts.value.current)) {
153
- return true;
154
- }
155
- return false;
151
+ if (!this.root.group)
152
+ return this.root.opts.checked.current;
153
+ if (this.root.opts.value.current !== undefined &&
154
+ this.root.group.opts.value.current.includes(this.root.opts.value.current)) {
155
+ return true;
156
156
  }
157
- return this.root.opts.checked.current;
157
+ return false;
158
158
  });
159
159
  shouldRender = $derived.by(() => Boolean(this.root.trueName));
160
160
  constructor(root) {
@@ -15,7 +15,6 @@ declare class CollapsibleRootState {
15
15
  readonly id: string;
16
16
  readonly "data-state": "open" | "closed";
17
17
  readonly "data-disabled": "" | undefined;
18
- readonly "data-collapsible-root": "";
19
18
  };
20
19
  }
21
20
  type CollapsibleContentStateProps = WithRefProps & ReadableBoxedValues<{
@@ -38,7 +37,6 @@ declare class CollapsibleContentState {
38
37
  };
39
38
  readonly "data-state": "open" | "closed";
40
39
  readonly "data-disabled": "" | undefined;
41
- readonly "data-collapsible-content": "";
42
40
  };
43
41
  }
44
42
  type CollapsibleTriggerStateProps = WithRefProps & ReadableBoxedValues<{
@@ -59,7 +57,6 @@ declare class CollapsibleTriggerState {
59
57
  readonly "aria-expanded": "true" | "false";
60
58
  readonly "data-state": "open" | "closed";
61
59
  readonly "data-disabled": "" | undefined;
62
- readonly "data-collapsible-trigger": "";
63
60
  readonly onclick: (e: BitsMouseEvent) => void;
64
61
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
65
62
  };
@@ -1,10 +1,11 @@
1
1
  import { afterTick, attachRef } from "svelte-toolbelt";
2
2
  import { Context, watch } from "runed";
3
- import { getAriaExpanded, getDataDisabled, getDataOpenClosed } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, getAriaExpanded, getDataDisabled, getDataOpenClosed, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
- const COLLAPSIBLE_ROOT_ATTR = "data-collapsible-root";
6
- const COLLAPSIBLE_CONTENT_ATTR = "data-collapsible-content";
7
- const COLLAPSIBLE_TRIGGER_ATTR = "data-collapsible-trigger";
5
+ const collapsibleAttrs = createBitsAttrs({
6
+ component: "collapsible",
7
+ parts: ["root", "content", "trigger"],
8
+ });
8
9
  class CollapsibleRootState {
9
10
  opts;
10
11
  contentNode = $state(null);
@@ -19,7 +20,7 @@ class CollapsibleRootState {
19
20
  id: this.opts.id.current,
20
21
  "data-state": getDataOpenClosed(this.opts.open.current),
21
22
  "data-disabled": getDataDisabled(this.opts.disabled.current),
22
- [COLLAPSIBLE_ROOT_ATTR]: "",
23
+ [collapsibleAttrs.root]: "",
23
24
  ...attachRef(this.opts.ref),
24
25
  }));
25
26
  }
@@ -84,7 +85,7 @@ class CollapsibleContentState {
84
85
  },
85
86
  "data-state": getDataOpenClosed(this.root.opts.open.current),
86
87
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
87
- [COLLAPSIBLE_CONTENT_ATTR]: "",
88
+ [collapsibleAttrs.content]: "",
88
89
  ...attachRef(this.opts.ref, (v) => (this.root.contentNode = v)),
89
90
  }));
90
91
  }
@@ -121,7 +122,7 @@ class CollapsibleTriggerState {
121
122
  "aria-expanded": getAriaExpanded(this.root.opts.open.current),
122
123
  "data-state": getDataOpenClosed(this.root.opts.open.current),
123
124
  "data-disabled": getDataDisabled(this.#isDisabled),
124
- [COLLAPSIBLE_TRIGGER_ATTR]: "",
125
+ [collapsibleAttrs.trigger]: "",
125
126
  //
126
127
  onclick: this.onclick,
127
128
  onkeydown: this.onkeydown,
@@ -124,7 +124,6 @@ declare class CommandRootState {
124
124
  props: {
125
125
  readonly id: string;
126
126
  readonly role: "application";
127
- readonly "data-command-root": "";
128
127
  readonly tabindex: -1;
129
128
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
130
129
  };
@@ -141,7 +140,6 @@ declare class CommandEmptyState {
141
140
  props: {
142
141
  readonly id: string;
143
142
  readonly role: "presentation";
144
- readonly "data-command-empty": "";
145
143
  };
146
144
  }
147
145
  type CommandGroupContainerStateProps = WithRefProps<ReadableBoxedValues<{
@@ -160,7 +158,6 @@ declare class CommandGroupContainerState {
160
158
  readonly role: "presentation";
161
159
  readonly hidden: true | undefined;
162
160
  readonly "data-value": string;
163
- readonly "data-command-group": "";
164
161
  };
165
162
  }
166
163
  type CommandGroupHeadingStateProps = WithRefProps;
@@ -170,7 +167,6 @@ declare class CommandGroupHeadingState {
170
167
  constructor(opts: CommandGroupHeadingStateProps, group: CommandGroupContainerState);
171
168
  props: {
172
169
  readonly id: string;
173
- readonly "data-command-group-heading": "";
174
170
  };
175
171
  }
176
172
  type CommandGroupItemsStateProps = WithRefProps;
@@ -181,7 +177,6 @@ declare class CommandGroupItemsState {
181
177
  props: {
182
178
  readonly id: string;
183
179
  readonly role: "group";
184
- readonly "data-command-group-items": "";
185
180
  readonly "aria-labelledby": string | undefined;
186
181
  };
187
182
  }
@@ -198,7 +193,6 @@ declare class CommandInputState {
198
193
  props: {
199
194
  readonly id: string;
200
195
  readonly type: "text";
201
- readonly "data-command-input": "";
202
196
  readonly autocomplete: "off";
203
197
  readonly autocorrect: "off";
204
198
  readonly spellcheck: false;
@@ -236,7 +230,6 @@ declare class CommandItemState {
236
230
  readonly "data-disabled": "" | undefined;
237
231
  readonly "data-selected": "" | undefined;
238
232
  readonly "data-value": string;
239
- readonly "data-command-item": "";
240
233
  readonly role: "option";
241
234
  readonly onpointermove: (_: BitsPointerEvent) => void;
242
235
  readonly onclick: (_: BitsMouseEvent) => void;
@@ -255,7 +248,6 @@ declare class CommandLoadingState {
255
248
  readonly "aria-valuemin": 0;
256
249
  readonly "aria-valuemax": 100;
257
250
  readonly "aria-label": "Loading...";
258
- readonly "data-command-loading": "";
259
251
  };
260
252
  }
261
253
  type CommandSeparatorStateProps = WithRefProps & ReadableBoxedValues<{
@@ -269,7 +261,6 @@ declare class CommandSeparatorState {
269
261
  props: {
270
262
  readonly id: string;
271
263
  readonly "aria-hidden": "true";
272
- readonly "data-command-separator": "";
273
264
  };
274
265
  }
275
266
  type CommandListStateProps = WithRefProps & ReadableBoxedValues<{
@@ -283,7 +274,6 @@ declare class CommandListState {
283
274
  readonly id: string;
284
275
  readonly role: "listbox";
285
276
  readonly "aria-label": string;
286
- readonly "data-command-list": "";
287
277
  };
288
278
  }
289
279
  type CommandLabelStateProps = WithRefProps<ReadableBoxedValues<{
@@ -295,7 +285,6 @@ declare class CommandLabelState {
295
285
  constructor(opts: CommandLabelStateProps, root: CommandRootState);
296
286
  props: {
297
287
  readonly id: string;
298
- readonly "data-command-input-label": "";
299
288
  readonly for: string | undefined;
300
289
  readonly style: import("svelte-toolbelt").StyleProperties;
301
290
  };
@@ -307,7 +296,6 @@ declare class CommandViewportState {
307
296
  constructor(opts: CommandViewportStateProps, list: CommandListState);
308
297
  props: {
309
298
  readonly id: string;
310
- readonly "data-command-viewport": "";
311
299
  };
312
300
  }
313
301
  export declare function useCommandRoot(props: CommandRootStateProps): CommandRootState;
@@ -2,30 +2,34 @@ import { afterSleep, afterTick, srOnlyStyles, attachRef } from "svelte-toolbelt"
2
2
  import { Context, watch } from "runed";
3
3
  import { findNextSibling, findPreviousSibling } from "./utils.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
- import { getAriaDisabled, getAriaExpanded, getAriaSelected, getDataDisabled, getDataSelected, } from "../../internal/attrs.js";
5
+ import { createBitsAttrs, getAriaDisabled, getAriaExpanded, getAriaSelected, getDataDisabled, getDataSelected, } from "../../internal/attrs.js";
6
6
  import { getFirstNonCommentChild } from "../../internal/dom.js";
7
7
  import { computeCommandScore } from "./index.js";
8
8
  import cssesc from "css.escape";
9
- // attributes
10
- const COMMAND_ROOT_ATTR = "data-command-root";
11
- const COMMAND_LIST_ATTR = "data-command-list";
12
- const COMMAND_INPUT_ATTR = "data-command-input";
13
- const COMMAND_SEPARATOR_ATTR = "data-command-separator";
14
- const COMMAND_LOADING_ATTR = "data-command-loading";
15
- const COMMAND_EMPTY_ATTR = "data-command-empty";
16
- const COMMAND_GROUP_ATTR = "data-command-group";
17
- const COMMAND_GROUP_ITEMS_ATTR = "data-command-group-items";
18
- const COMMAND_GROUP_HEADING_ATTR = "data-command-group-heading";
19
- const COMMAND_ITEM_ATTR = "data-command-item";
20
- const COMMAND_VIEWPORT_ATTR = "data-command-viewport";
21
- const COMMAND_INPUT_LABEL_ATTR = "data-command-input-label";
22
9
  const COMMAND_VALUE_ATTR = "data-value";
10
+ const commandAttrs = createBitsAttrs({
11
+ component: "command",
12
+ parts: [
13
+ "root",
14
+ "list",
15
+ "input",
16
+ "separator",
17
+ "loading",
18
+ "empty",
19
+ "group",
20
+ "group-items",
21
+ "group-heading",
22
+ "item",
23
+ "viewport",
24
+ "input-label",
25
+ ],
26
+ });
23
27
  // selectors
24
- const COMMAND_GROUP_SELECTOR = `[${COMMAND_GROUP_ATTR}]`;
25
- const COMMAND_GROUP_ITEMS_SELECTOR = `[${COMMAND_GROUP_ITEMS_ATTR}]`;
26
- const COMMAND_GROUP_HEADING_SELECTOR = `[${COMMAND_GROUP_HEADING_ATTR}]`;
27
- const COMMAND_ITEM_SELECTOR = `[${COMMAND_ITEM_ATTR}]`;
28
- const COMMAND_VALID_ITEM_SELECTOR = `${COMMAND_ITEM_SELECTOR}:not([aria-disabled="true"])`;
28
+ const COMMAND_GROUP_SELECTOR = commandAttrs.selector("group");
29
+ const COMMAND_GROUP_ITEMS_SELECTOR = commandAttrs.selector("group-items");
30
+ const COMMAND_GROUP_HEADING_SELECTOR = commandAttrs.selector("group-heading");
31
+ const COMMAND_ITEM_SELECTOR = commandAttrs.selector("item");
32
+ const COMMAND_VALID_ITEM_SELECTOR = `${commandAttrs.selector("item")}:not([aria-disabled="true"])`;
29
33
  const CommandRootContext = new Context("Command.Root");
30
34
  const CommandListContext = new Context("Command.List");
31
35
  const CommandGroupContainerContext = new Context("Command.Group");
@@ -568,7 +572,7 @@ class CommandRootState {
568
572
  props = $derived.by(() => ({
569
573
  id: this.opts.id.current,
570
574
  role: "application",
571
- [COMMAND_ROOT_ATTR]: "",
575
+ [commandAttrs.root]: "",
572
576
  tabindex: -1,
573
577
  onkeydown: this.onkeydown,
574
578
  ...attachRef(this.opts.ref),
@@ -592,7 +596,7 @@ class CommandEmptyState {
592
596
  props = $derived.by(() => ({
593
597
  id: this.opts.id.current,
594
598
  role: "presentation",
595
- [COMMAND_EMPTY_ATTR]: "",
599
+ [commandAttrs.empty]: "",
596
600
  ...attachRef(this.opts.ref),
597
601
  }));
598
602
  }
@@ -637,7 +641,7 @@ class CommandGroupContainerState {
637
641
  role: "presentation",
638
642
  hidden: this.shouldRender ? undefined : true,
639
643
  "data-value": this.trueValue,
640
- [COMMAND_GROUP_ATTR]: "",
644
+ [commandAttrs.group]: "",
641
645
  ...attachRef(this.opts.ref),
642
646
  }));
643
647
  }
@@ -650,7 +654,7 @@ class CommandGroupHeadingState {
650
654
  }
651
655
  props = $derived.by(() => ({
652
656
  id: this.opts.id.current,
653
- [COMMAND_GROUP_HEADING_ATTR]: "",
657
+ [commandAttrs["group-heading"]]: "",
654
658
  ...attachRef(this.opts.ref, (v) => (this.group.headingNode = v)),
655
659
  }));
656
660
  }
@@ -664,7 +668,7 @@ class CommandGroupItemsState {
664
668
  props = $derived.by(() => ({
665
669
  id: this.opts.id.current,
666
670
  role: "group",
667
- [COMMAND_GROUP_ITEMS_ATTR]: "",
671
+ [commandAttrs["group-items"]]: "",
668
672
  "aria-labelledby": this.group.headingNode?.id ?? undefined,
669
673
  ...attachRef(this.opts.ref),
670
674
  }));
@@ -696,7 +700,7 @@ class CommandInputState {
696
700
  props = $derived.by(() => ({
697
701
  id: this.opts.id.current,
698
702
  type: "text",
699
- [COMMAND_INPUT_ATTR]: "",
703
+ [commandAttrs.input]: "",
700
704
  autocomplete: "off",
701
705
  autocorrect: "off",
702
706
  spellcheck: false,
@@ -783,7 +787,7 @@ class CommandItemState {
783
787
  "data-disabled": getDataDisabled(this.opts.disabled.current),
784
788
  "data-selected": getDataSelected(this.isSelected),
785
789
  "data-value": this.trueValue,
786
- [COMMAND_ITEM_ATTR]: "",
790
+ [commandAttrs.item]: "",
787
791
  role: "option",
788
792
  onpointermove: this.onpointermove,
789
793
  onclick: this.onclick,
@@ -802,7 +806,7 @@ class CommandLoadingState {
802
806
  "aria-valuemin": 0,
803
807
  "aria-valuemax": 100,
804
808
  "aria-label": "Loading...",
805
- [COMMAND_LOADING_ATTR]: "",
809
+ [commandAttrs.loading]: "",
806
810
  ...attachRef(this.opts.ref),
807
811
  }));
808
812
  }
@@ -818,7 +822,7 @@ class CommandSeparatorState {
818
822
  id: this.opts.id.current,
819
823
  // role="separator" cannot belong to a role="listbox"
820
824
  "aria-hidden": "true",
821
- [COMMAND_SEPARATOR_ATTR]: "",
825
+ [commandAttrs.separator]: "",
822
826
  ...attachRef(this.opts.ref),
823
827
  }));
824
828
  }
@@ -833,7 +837,7 @@ class CommandListState {
833
837
  id: this.opts.id.current,
834
838
  role: "listbox",
835
839
  "aria-label": this.opts.ariaLabel.current,
836
- [COMMAND_LIST_ATTR]: "",
840
+ [commandAttrs.list]: "",
837
841
  ...attachRef(this.opts.ref),
838
842
  }));
839
843
  }
@@ -846,7 +850,7 @@ class CommandLabelState {
846
850
  }
847
851
  props = $derived.by(() => ({
848
852
  id: this.opts.id.current,
849
- [COMMAND_INPUT_LABEL_ATTR]: "",
853
+ [commandAttrs["input-label"]]: "",
850
854
  for: this.opts.for?.current,
851
855
  style: srOnlyStyles,
852
856
  ...attachRef(this.opts.ref, (v) => (this.root.labelNode = v)),
@@ -879,7 +883,7 @@ class CommandViewportState {
879
883
  }
880
884
  props = $derived.by(() => ({
881
885
  id: this.opts.id.current,
882
- [COMMAND_VIEWPORT_ATTR]: "",
886
+ [commandAttrs.viewport]: "",
883
887
  ...attachRef(this.opts.ref, (v) => (this.list.root.viewportNode = v)),
884
888
  }));
885
889
  }