bits-ui 2.3.0 → 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 (81) 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/label/label.svelte.d.ts +0 -1
  24. package/dist/bits/label/label.svelte.js +6 -2
  25. package/dist/bits/link-preview/link-preview.svelte.d.ts +0 -2
  26. package/dist/bits/link-preview/link-preview.svelte.js +7 -5
  27. package/dist/bits/menu/components/menu-sub-content-static.svelte +1 -1
  28. package/dist/bits/menu/components/menu-sub-content.svelte +1 -1
  29. package/dist/bits/menu/menu.svelte.d.ts +2 -1
  30. package/dist/bits/menu/menu.svelte.js +39 -21
  31. package/dist/bits/menubar/menubar.svelte.d.ts +1 -7
  32. package/dist/bits/menubar/menubar.svelte.js +12 -14
  33. package/dist/bits/meter/meter.svelte.d.ts +0 -1
  34. package/dist/bits/meter/meter.svelte.js +6 -2
  35. package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +2 -11
  36. package/dist/bits/navigation-menu/navigation-menu.svelte.js +30 -25
  37. package/dist/bits/pagination/pagination.svelte.d.ts +0 -4
  38. package/dist/bits/pagination/pagination.svelte.js +9 -10
  39. package/dist/bits/pin-input/pin-input.svelte.d.ts +0 -2
  40. package/dist/bits/pin-input/pin-input.svelte.js +7 -5
  41. package/dist/bits/popover/popover.svelte.d.ts +0 -3
  42. package/dist/bits/popover/popover.svelte.js +9 -5
  43. package/dist/bits/progress/progress.svelte.d.ts +0 -1
  44. package/dist/bits/progress/progress.svelte.js +6 -2
  45. package/dist/bits/radio-group/radio-group.svelte.d.ts +7 -9
  46. package/dist/bits/radio-group/radio-group.svelte.js +9 -10
  47. package/dist/bits/range-calendar/range-calendar.svelte.d.ts +38 -38
  48. package/dist/bits/range-calendar/range-calendar.svelte.js +79 -79
  49. package/dist/bits/rating-group/rating-group.svelte.d.ts +0 -2
  50. package/dist/bits/rating-group/rating-group.svelte.js +33 -11
  51. package/dist/bits/scroll-area/scroll-area.svelte.d.ts +15 -19
  52. package/dist/bits/scroll-area/scroll-area.svelte.js +10 -10
  53. package/dist/bits/select/select.svelte.d.ts +28 -30
  54. package/dist/bits/select/select.svelte.js +36 -48
  55. package/dist/bits/separator/separator.svelte.d.ts +1 -2
  56. package/dist/bits/separator/separator.svelte.js +6 -3
  57. package/dist/bits/slider/slider.svelte.d.ts +17 -24
  58. package/dist/bits/slider/slider.svelte.js +15 -17
  59. package/dist/bits/switch/switch.svelte.d.ts +6 -8
  60. package/dist/bits/switch/switch.svelte.js +7 -5
  61. package/dist/bits/tabs/tabs.svelte.d.ts +5 -9
  62. package/dist/bits/tabs/tabs.svelte.js +11 -11
  63. package/dist/bits/time-field/time-field.svelte.d.ts +1 -3
  64. package/dist/bits/time-field/time-field.svelte.js +7 -5
  65. package/dist/bits/time-range-field/time-range-field.svelte.d.ts +1 -3
  66. package/dist/bits/time-range-field/time-range-field.svelte.js +7 -5
  67. package/dist/bits/toggle/toggle.svelte.d.ts +3 -3
  68. package/dist/bits/toggle/toggle.svelte.js +6 -3
  69. package/dist/bits/toggle-group/toggle-group.svelte.d.ts +1 -2
  70. package/dist/bits/toggle-group/toggle-group.svelte.js +8 -6
  71. package/dist/bits/toolbar/toolbar.svelte.d.ts +11 -18
  72. package/dist/bits/toolbar/toolbar.svelte.js +14 -17
  73. package/dist/bits/tooltip/tooltip.svelte.d.ts +13 -14
  74. package/dist/bits/tooltip/tooltip.svelte.js +7 -5
  75. package/dist/internal/attrs.d.ts +14 -0
  76. package/dist/internal/attrs.js +18 -0
  77. package/dist/internal/date-time/calendar-helpers.svelte.d.ts +1 -0
  78. package/dist/internal/date-time/calendar-helpers.svelte.js +18 -1
  79. package/dist/internal/use-arrow-navigation.d.ts +2 -2
  80. package/dist/internal/use-arrow-navigation.js +1 -1
  81. package/package.json +1 -1
@@ -1,9 +1,11 @@
1
1
  import { attachRef, DOMContext } from "svelte-toolbelt";
2
2
  import { Context } from "runed";
3
- import { getAriaRequired, getDataDisabled } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, getAriaRequired, getDataDisabled } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
- const RATING_GROUP_ROOT_ATTR = "data-rating-group-root";
6
- const RATING_GROUP_ITEM_ATTR = "data-rating-group-item";
5
+ const ratingGroupAttrs = createBitsAttrs({
6
+ component: "rating-group",
7
+ parts: ["root", "item"],
8
+ });
7
9
  class RatingGroupRootState {
8
10
  opts;
9
11
  #hoverValue = $state(null);
@@ -85,22 +87,42 @@ class RatingGroupRootState {
85
87
  this.setHoverValue(null);
86
88
  }
87
89
  handlers = {
88
- [kbd.ARROW_UP]: () => this.#adjustValue(this.opts.allowHalf.current ? 0.5 : 1),
90
+ [kbd.ARROW_UP]: () => {
91
+ this.setHoverValue(null);
92
+ this.#adjustValue(this.opts.allowHalf.current ? 0.5 : 1);
93
+ },
89
94
  [kbd.ARROW_RIGHT]: () => {
95
+ this.setHoverValue(null);
90
96
  const increment = this.opts.allowHalf.current ? 0.5 : 1;
91
97
  // in RTL mode, right arrow should decrement
92
98
  this.#adjustValue(this.isRTL ? -increment : increment);
93
99
  },
94
- [kbd.ARROW_DOWN]: () => this.#adjustValue(this.opts.allowHalf.current ? -0.5 : -1),
100
+ [kbd.ARROW_DOWN]: () => {
101
+ this.setHoverValue(null);
102
+ this.#adjustValue(this.opts.allowHalf.current ? -0.5 : -1);
103
+ },
95
104
  [kbd.ARROW_LEFT]: () => {
105
+ this.setHoverValue(null);
96
106
  const increment = this.opts.allowHalf.current ? 0.5 : 1;
97
107
  // in RTL mode, left arrow should increment
98
108
  this.#adjustValue(this.isRTL ? increment : -increment);
99
109
  },
100
- [kbd.HOME]: () => this.setValue(this.opts.min.current),
101
- [kbd.END]: () => this.setValue(this.opts.max.current),
102
- [kbd.PAGE_UP]: () => this.#adjustValue(1),
103
- [kbd.PAGE_DOWN]: () => this.#adjustValue(-1),
110
+ [kbd.HOME]: () => {
111
+ this.setHoverValue(null);
112
+ this.setValue(this.opts.min.current);
113
+ },
114
+ [kbd.END]: () => {
115
+ this.setHoverValue(null);
116
+ this.setValue(this.opts.max.current);
117
+ },
118
+ [kbd.PAGE_UP]: () => {
119
+ this.setHoverValue(null);
120
+ this.#adjustValue(1);
121
+ },
122
+ [kbd.PAGE_DOWN]: () => {
123
+ this.setHoverValue(null);
124
+ this.#adjustValue(-1);
125
+ },
104
126
  };
105
127
  onkeydown(e) {
106
128
  if (this.opts.disabled.current || this.opts.readonly.current)
@@ -188,7 +210,7 @@ class RatingGroupRootState {
188
210
  "data-readonly": this.opts.readonly.current ? "" : undefined,
189
211
  "data-orientation": this.opts.orientation.current,
190
212
  tabindex: this.opts.disabled.current ? -1 : 0,
191
- [RATING_GROUP_ROOT_ATTR]: "",
213
+ [ratingGroupAttrs.root]: "",
192
214
  onkeydown: this.onkeydown,
193
215
  onpointerleave: this.onpointerleave,
194
216
  ...attachRef(this.opts.ref),
@@ -263,7 +285,7 @@ class RatingGroupItemState {
263
285
  "data-disabled": getDataDisabled(this.#isDisabled),
264
286
  "data-readonly": this.root.opts.readonly.current ? "" : undefined,
265
287
  "data-state": this.#state,
266
- [RATING_GROUP_ITEM_ATTR]: "",
288
+ [ratingGroupAttrs.item]: "",
267
289
  //
268
290
  onclick: this.onclick,
269
291
  onpointermove: this.onpointermove,
@@ -45,7 +45,6 @@ declare class ScrollAreaRootState {
45
45
  readonly "--bits-scroll-area-corner-height": `${number}px`;
46
46
  readonly "--bits-scroll-area-corner-width": `${number}px`;
47
47
  };
48
- readonly "data-scroll-area-root": "";
49
48
  };
50
49
  }
51
50
  type ScrollAreaViewportStateProps = WithRefProps;
@@ -60,7 +59,6 @@ declare class ScrollAreaViewportState {
60
59
  readonly overflowX: "hidden" | "scroll";
61
60
  readonly overflowY: "hidden" | "scroll";
62
61
  };
63
- readonly "data-scroll-area-viewport": "";
64
62
  };
65
63
  contentProps: {
66
64
  readonly id: string;
@@ -83,7 +81,7 @@ type ScrollAreaScrollbarStateProps = WithRefProps<ReadableBoxedValues<{
83
81
  declare class ScrollAreaScrollbarState {
84
82
  readonly opts: ScrollAreaScrollbarStateProps;
85
83
  readonly root: ScrollAreaRootState;
86
- isHorizontal: boolean;
84
+ readonly isHorizontal: boolean;
87
85
  hasThumb: boolean;
88
86
  constructor(opts: ScrollAreaScrollbarStateProps, root: ScrollAreaRootState);
89
87
  }
@@ -92,7 +90,7 @@ declare class ScrollAreaScrollbarHoverState {
92
90
  root: ScrollAreaRootState;
93
91
  isVisible: boolean;
94
92
  constructor(scrollbar: ScrollAreaScrollbarState);
95
- props: {
93
+ readonly props: {
96
94
  readonly "data-state": "hidden" | "visible";
97
95
  };
98
96
  }
@@ -103,11 +101,11 @@ declare class ScrollAreaScrollbarScrollState {
103
101
  state: import("svelte-toolbelt").WritableBox<"hidden" | "scrolling" | "idle" | "interacting">;
104
102
  dispatch: (event: string | number | symbol) => void;
105
103
  };
106
- isHidden: boolean;
104
+ readonly isHidden: boolean;
107
105
  constructor(scrollbar: ScrollAreaScrollbarState);
108
106
  onpointerenter(_: BitsPointerEvent): void;
109
107
  onpointerleave(_: BitsPointerEvent): void;
110
- props: {
108
+ readonly props: {
111
109
  readonly "data-state": "hidden" | "visible";
112
110
  readonly onpointerenter: (_: BitsPointerEvent) => void;
113
111
  readonly onpointerleave: (_: BitsPointerEvent) => void;
@@ -118,7 +116,7 @@ declare class ScrollAreaScrollbarAutoState {
118
116
  root: ScrollAreaRootState;
119
117
  isVisible: boolean;
120
118
  constructor(scrollbar: ScrollAreaScrollbarState);
121
- props: {
119
+ readonly props: {
122
120
  readonly "data-state": "hidden" | "visible";
123
121
  };
124
122
  }
@@ -128,8 +126,8 @@ declare class ScrollAreaScrollbarVisibleState {
128
126
  thumbNode: HTMLElement | null;
129
127
  pointerOffset: number;
130
128
  sizes: Sizes;
131
- thumbRatio: number;
132
- hasThumb: boolean;
129
+ readonly thumbRatio: number;
130
+ readonly hasThumb: boolean;
133
131
  prevTransformStyle: string;
134
132
  constructor(scrollbar: ScrollAreaScrollbarState);
135
133
  setSizes(sizes: Sizes): void;
@@ -184,8 +182,8 @@ declare class ScrollAreaScrollbarXState implements ScrollbarAxisState {
184
182
  onThumbPositionChange: () => void;
185
183
  onWheelScroll: (e: WheelEvent, maxScrollPos: number) => void;
186
184
  onResize: () => void;
187
- thumbSize: number;
188
- props: {
185
+ readonly thumbSize: number;
186
+ readonly props: {
189
187
  readonly id: string;
190
188
  readonly "data-orientation": "horizontal";
191
189
  readonly style: {
@@ -215,8 +213,8 @@ declare class ScrollAreaScrollbarYState implements ScrollbarAxisState {
215
213
  onThumbPositionChange(): void;
216
214
  onWheelScroll(e: WheelEvent, maxScrollPos: number): void;
217
215
  onResize(): void;
218
- thumbSize: number;
219
- props: {
216
+ readonly thumbSize: number;
217
+ readonly props: {
220
218
  readonly id: string;
221
219
  readonly "data-orientation": "vertical";
222
220
  readonly style: {
@@ -244,7 +242,7 @@ declare class ScrollAreaScrollbarSharedState {
244
242
  y: number;
245
243
  }) => void;
246
244
  handleThumbPointerUp: () => void;
247
- maxScrollPos: number;
245
+ readonly maxScrollPos: number;
248
246
  constructor(scrollbarState: ScrollbarAxis);
249
247
  handleDragScroll(e: PointerEvent): void;
250
248
  onpointerdown(e: BitsPointerEvent): void;
@@ -262,7 +260,7 @@ declare class ScrollAreaThumbImplState {
262
260
  constructor(opts: ScrollAreaThumbImplStateProps, scrollbarState: ScrollAreaScrollbarSharedState);
263
261
  onpointerdowncapture(e: BitsPointerEvent): void;
264
262
  onpointerup(_: BitsPointerEvent): void;
265
- props: {
263
+ readonly props: {
266
264
  readonly id: string;
267
265
  readonly "data-state": "hidden" | "visible";
268
266
  readonly style: {
@@ -272,7 +270,6 @@ declare class ScrollAreaThumbImplState {
272
270
  };
273
271
  readonly onpointerdowncapture: (e: BitsPointerEvent) => void;
274
272
  readonly onpointerup: (_: BitsPointerEvent) => void;
275
- readonly "data-scroll-area-thumb": "";
276
273
  };
277
274
  }
278
275
  type ScrollAreaCornerImplStateProps = WithRefProps;
@@ -280,9 +277,9 @@ declare class ScrollAreaCornerImplState {
280
277
  #private;
281
278
  readonly opts: ScrollAreaCornerImplStateProps;
282
279
  readonly root: ScrollAreaRootState;
283
- hasSize: boolean;
280
+ readonly hasSize: boolean;
284
281
  constructor(opts: ScrollAreaCornerImplStateProps, root: ScrollAreaRootState);
285
- props: {
282
+ readonly props: {
286
283
  id: string;
287
284
  style: {
288
285
  width: number;
@@ -292,7 +289,6 @@ declare class ScrollAreaCornerImplState {
292
289
  left: number | undefined;
293
290
  bottom: number;
294
291
  };
295
- "data-scroll-area-corner": string;
296
292
  };
297
293
  }
298
294
  export declare const ScrollAreaRootContext: Context<ScrollAreaRootState>;
@@ -13,11 +13,11 @@ import { useStateMachine } from "../../internal/use-state-machine.svelte.js";
13
13
  import { clamp } from "../../internal/clamp.js";
14
14
  import { useResizeObserver } from "../../internal/use-resize-observer.svelte.js";
15
15
  import { on } from "svelte/events";
16
- const SCROLL_AREA_ROOT_ATTR = "data-scroll-area-root";
17
- const SCROLL_AREA_VIEWPORT_ATTR = "data-scroll-area-viewport";
18
- const SCROLL_AREA_CORNER_ATTR = "data-scroll-area-corner";
19
- const SCROLL_AREA_THUMB_ATTR = "data-scroll-area-thumb";
20
- const SCROLL_AREA_SCROLLBAR_ATTR = "data-scroll-area-scrollbar";
16
+ import { createBitsAttrs } from "../../internal/attrs.js";
17
+ const scrollAreaAttrs = createBitsAttrs({
18
+ component: "scroll-area",
19
+ parts: ["root", "viewport", "corner", "thumb", "scrollbar"],
20
+ });
21
21
  class ScrollAreaRootState {
22
22
  opts;
23
23
  scrollAreaNode = $state(null);
@@ -42,7 +42,7 @@ class ScrollAreaRootState {
42
42
  "--bits-scroll-area-corner-height": `${this.cornerHeight}px`,
43
43
  "--bits-scroll-area-corner-width": `${this.cornerWidth}px`,
44
44
  },
45
- [SCROLL_AREA_ROOT_ATTR]: "",
45
+ [scrollAreaAttrs.root]: "",
46
46
  ...attachRef(this.opts.ref, (v) => (this.scrollAreaNode = v)),
47
47
  }));
48
48
  }
@@ -61,7 +61,7 @@ class ScrollAreaViewportState {
61
61
  overflowX: this.root.scrollbarXEnabled ? "scroll" : "hidden",
62
62
  overflowY: this.root.scrollbarYEnabled ? "scroll" : "hidden",
63
63
  },
64
- [SCROLL_AREA_VIEWPORT_ATTR]: "",
64
+ [scrollAreaAttrs.viewport]: "",
65
65
  ...attachRef(this.opts.ref, (v) => (this.root.viewportNode = v)),
66
66
  }));
67
67
  contentProps = $derived.by(() => ({
@@ -565,7 +565,7 @@ class ScrollAreaScrollbarSharedState {
565
565
  position: "absolute",
566
566
  ...this.scrollbarState.props.style,
567
567
  },
568
- [SCROLL_AREA_SCROLLBAR_ATTR]: "",
568
+ [scrollAreaAttrs.scrollbar]: "",
569
569
  onpointerdown: this.onpointerdown,
570
570
  onpointermove: this.onpointermove,
571
571
  onpointerup: this.onpointerup,
@@ -627,7 +627,7 @@ class ScrollAreaThumbImplState {
627
627
  },
628
628
  onpointerdowncapture: this.onpointerdowncapture,
629
629
  onpointerup: this.onpointerup,
630
- [SCROLL_AREA_THUMB_ATTR]: "",
630
+ [scrollAreaAttrs.thumb]: "",
631
631
  ...attachRef(this.opts.ref, (v) => (this.scrollbarState.scrollbarVis.thumbNode = v)),
632
632
  }));
633
633
  }
@@ -661,7 +661,7 @@ class ScrollAreaCornerImplState {
661
661
  left: this.root.opts.dir.current === "rtl" ? 0 : undefined,
662
662
  bottom: 0,
663
663
  },
664
- [SCROLL_AREA_CORNER_ATTR]: "",
664
+ [scrollAreaAttrs.corner]: "",
665
665
  ...attachRef(this.opts.ref),
666
666
  }));
667
667
  }
@@ -8,6 +8,7 @@ export declare const LAST_KEYS: string[];
8
8
  export declare const FIRST_LAST_KEYS: string[];
9
9
  export declare const SELECTION_KEYS: string[];
10
10
  export declare const CONTENT_MARGIN = 10;
11
+ declare const selectAttrs: import("../../internal/attrs.js").BitsAttrs<readonly ["trigger", "content", "item", "viewport", "scroll-up-button", "scroll-down-button", "group", "group-label", "separator", "arrow", "input", "content-wrapper", "item-text", "value"]>;
11
12
  type SelectBaseRootStateProps = ReadableBoxedValues<{
12
13
  disabled: boolean;
13
14
  required: boolean;
@@ -34,12 +35,11 @@ declare class SelectBaseRootState {
34
35
  triggerNode: HTMLElement | null;
35
36
  valueId: string;
36
37
  highlightedNode: HTMLElement | null;
37
- highlightedValue: string | null;
38
- highlightedId: string | undefined;
39
- highlightedLabel: string | null;
38
+ readonly highlightedValue: string | null;
39
+ readonly highlightedId: string | undefined;
40
+ readonly highlightedLabel: string | null;
40
41
  isUsingKeyboard: boolean;
41
42
  isCombobox: boolean;
42
- bitsAttrs: SelectBitsAttrs;
43
43
  domContext: DOMContext;
44
44
  constructor(opts: SelectBaseRootStateProps);
45
45
  setHighlightedNode(node: HTMLElement | null, initial?: boolean): void;
@@ -51,17 +51,18 @@ declare class SelectBaseRootState {
51
51
  handleOpen(): void;
52
52
  handleClose(): void;
53
53
  toggleMenu(): void;
54
+ getBitsAttr: typeof selectAttrs.getAttr;
54
55
  }
55
56
  type SelectSingleRootStateProps = SelectBaseRootStateProps & WritableBoxedValues<{
56
57
  value: string;
57
58
  }>;
58
59
  declare class SelectSingleRootState extends SelectBaseRootState {
59
60
  readonly opts: SelectSingleRootStateProps;
60
- isMulti: false;
61
- hasValue: boolean;
62
- currentLabel: string;
63
- candidateLabels: string[];
64
- dataTypeaheadEnabled: boolean;
61
+ readonly isMulti: false;
62
+ readonly hasValue: boolean;
63
+ readonly currentLabel: string;
64
+ readonly candidateLabels: string[];
65
+ readonly dataTypeaheadEnabled: boolean;
65
66
  constructor(opts: SelectSingleRootStateProps);
66
67
  includesItem(itemValue: string): boolean;
67
68
  toggleItem(itemValue: string, itemLabel?: string): void;
@@ -72,8 +73,8 @@ type SelectMultipleRootStateProps = SelectBaseRootStateProps & WritableBoxedValu
72
73
  }>;
73
74
  declare class SelectMultipleRootState extends SelectBaseRootState {
74
75
  readonly opts: SelectMultipleRootStateProps;
75
- isMulti: true;
76
- hasValue: boolean;
76
+ readonly isMulti: true;
77
+ readonly hasValue: boolean;
77
78
  constructor(opts: SelectMultipleRootStateProps);
78
79
  includesItem(itemValue: string): boolean;
79
80
  toggleItem(itemValue: string, itemLabel?: string): void;
@@ -89,7 +90,7 @@ declare class SelectInputState {
89
90
  constructor(opts: SelectInputStateProps, root: SelectRootState);
90
91
  onkeydown(e: BitsKeyboardEvent): void;
91
92
  oninput(e: BitsEvent<Event, HTMLInputElement>): void;
92
- props: {
93
+ readonly props: {
93
94
  readonly id: string;
94
95
  readonly role: "combobox";
95
96
  readonly disabled: true | undefined;
@@ -113,7 +114,7 @@ declare class SelectComboTriggerState {
113
114
  * behavior of focusing the button and keep focus on the input.
114
115
  */
115
116
  onpointerdown(e: BitsPointerEvent): void;
116
- props: {
117
+ readonly props: {
117
118
  readonly id: string;
118
119
  readonly disabled: true | undefined;
119
120
  readonly "aria-haspopup": "listbox";
@@ -133,7 +134,7 @@ declare class SelectTriggerState {
133
134
  onclick(e: BitsMouseEvent): void;
134
135
  onpointerdown(e: BitsPointerEvent): void;
135
136
  onpointerup(e: BitsPointerEvent): void;
136
- props: {
137
+ readonly props: {
137
138
  readonly id: string;
138
139
  readonly disabled: true | undefined;
139
140
  readonly "aria-haspopup": "listbox";
@@ -165,10 +166,10 @@ declare class SelectContentState {
165
166
  onEscapeKeydown: (e: KeyboardEvent) => void;
166
167
  onOpenAutoFocus: (e: Event) => void;
167
168
  onCloseAutoFocus: (e: Event) => void;
168
- snippetProps: {
169
+ readonly snippetProps: {
169
170
  open: boolean;
170
171
  };
171
- props: {
172
+ readonly props: {
172
173
  readonly id: string;
173
174
  readonly role: "listbox";
174
175
  readonly "aria-multiselectable": "true" | undefined;
@@ -182,7 +183,7 @@ declare class SelectContentState {
182
183
  };
183
184
  readonly onpointermove: (_: BitsPointerEvent) => void;
184
185
  };
185
- popperProps: {
186
+ readonly popperProps: {
186
187
  onInteractOutside: (e: PointerEvent) => void;
187
188
  onEscapeKeydown: (e: KeyboardEvent) => void;
188
189
  onOpenAutoFocus: (e: Event) => void;
@@ -202,9 +203,9 @@ type SelectItemStateProps = WithRefProps<ReadableBoxedValues<{
202
203
  declare class SelectItemState {
203
204
  readonly opts: SelectItemStateProps;
204
205
  readonly root: SelectRootState;
205
- isSelected: boolean;
206
- isHighlighted: boolean;
207
- prevHighlighted: Previous<boolean>;
206
+ readonly isSelected: boolean;
207
+ readonly isHighlighted: boolean;
208
+ readonly prevHighlighted: Previous<boolean>;
208
209
  mounted: boolean;
209
210
  constructor(opts: SelectItemStateProps, root: SelectRootState);
210
211
  handleSelect(): void;
@@ -240,7 +241,7 @@ declare class SelectGroupState {
240
241
  readonly root: SelectBaseRootState;
241
242
  labelNode: HTMLElement | null;
242
243
  constructor(opts: SelectGroupStateProps, root: SelectBaseRootState);
243
- props: {
244
+ readonly props: {
244
245
  readonly id: string;
245
246
  readonly role: "group";
246
247
  readonly "aria-labelledby": string | undefined;
@@ -251,7 +252,7 @@ declare class SelectGroupHeadingState {
251
252
  readonly opts: SelectGroupHeadingStateProps;
252
253
  readonly group: SelectGroupState;
253
254
  constructor(opts: SelectGroupHeadingStateProps, group: SelectGroupState);
254
- props: {
255
+ readonly props: {
255
256
  readonly id: string;
256
257
  };
257
258
  }
@@ -264,7 +265,7 @@ declare class SelectHiddenInputState {
264
265
  shouldRender: boolean;
265
266
  constructor(opts: SelectHiddenInputStateProps, root: SelectBaseRootState);
266
267
  onfocus(e: BitsFocusEvent): void;
267
- props: {
268
+ readonly props: {
268
269
  readonly disabled: true | undefined;
269
270
  readonly required: true | undefined;
270
271
  readonly name: string;
@@ -279,7 +280,7 @@ declare class SelectViewportState {
279
280
  root: SelectBaseRootState;
280
281
  prevScrollTop: number;
281
282
  constructor(opts: SelectViewportStateProps, content: SelectContentState);
282
- props: {
283
+ readonly props: {
283
284
  readonly id: string;
284
285
  readonly role: "presentation";
285
286
  readonly style: {
@@ -307,7 +308,7 @@ declare class SelectScrollButtonImplState {
307
308
  onpointerdown(_: BitsPointerEvent): void;
308
309
  onpointermove(e: BitsPointerEvent): void;
309
310
  onpointerleave(_: BitsPointerEvent): void;
310
- props: {
311
+ readonly props: {
311
312
  readonly id: string;
312
313
  readonly "aria-hidden": "true" | undefined;
313
314
  readonly style: {
@@ -331,7 +332,7 @@ declare class SelectScrollDownButtonState {
331
332
  */
332
333
  handleScroll: (manual?: boolean) => void;
333
334
  handleAutoScroll: () => void;
334
- props: {
335
+ readonly props: {
335
336
  readonly id: string;
336
337
  readonly "aria-hidden": "true" | undefined;
337
338
  readonly style: {
@@ -354,7 +355,7 @@ declare class SelectScrollUpButtonState {
354
355
  */
355
356
  handleScroll: (manual?: boolean) => void;
356
357
  handleAutoScroll: () => void;
357
- props: {
358
+ readonly props: {
358
359
  readonly id: string;
359
360
  readonly "aria-hidden": "true" | undefined;
360
361
  readonly style: {
@@ -398,7 +399,4 @@ export declare function useSelectScrollDownButton(props: SelectScrollButtonImplS
398
399
  export declare function useSelectGroup(props: SelectGroupStateProps): SelectGroupState;
399
400
  export declare function useSelectGroupHeading(props: SelectGroupHeadingStateProps): SelectGroupHeadingState;
400
401
  export declare function useSelectHiddenInput(props: SelectHiddenInputStateProps): SelectHiddenInputState;
401
- declare const selectParts: readonly ["trigger", "content", "item", "viewport", "scroll-up-button", "scroll-down-button", "group", "group-label", "separator", "arrow", "input", "content-wrapper", "item-text", "value"];
402
- type SelectBitsAttrs = Record<(typeof selectParts)[number], string>;
403
- export declare function getSelectBitsAttrs(root: SelectBaseRootState): SelectBitsAttrs;
404
402
  export {};
@@ -8,6 +8,8 @@ import { noop } from "../../internal/noop.js";
8
8
  import { useDOMTypeahead } from "../../internal/use-dom-typeahead.svelte.js";
9
9
  import { useDataTypeahead } from "../../internal/use-data-typeahead.svelte.js";
10
10
  import { isIOS } from "../../internal/is.js";
11
+ import { createBitsAttrs } from "../../internal/attrs.js";
12
+ import { getFloatingContentCSSVars } from "../../internal/floating-svelte/floating-utils.svelte.js";
11
13
  // prettier-ignore
12
14
  export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ESCAPE, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12];
13
15
  export const FIRST_KEYS = [kbd.ARROW_DOWN, kbd.PAGE_UP, kbd.HOME];
@@ -15,6 +17,25 @@ export const LAST_KEYS = [kbd.ARROW_UP, kbd.PAGE_DOWN, kbd.END];
15
17
  export const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
16
18
  export const SELECTION_KEYS = [kbd.ENTER, kbd.SPACE];
17
19
  export const CONTENT_MARGIN = 10;
20
+ const selectAttrs = createBitsAttrs({
21
+ component: "select",
22
+ parts: [
23
+ "trigger",
24
+ "content",
25
+ "item",
26
+ "viewport",
27
+ "scroll-up-button",
28
+ "scroll-down-button",
29
+ "group",
30
+ "group-label",
31
+ "separator",
32
+ "arrow",
33
+ "input",
34
+ "content-wrapper",
35
+ "item-text",
36
+ "value",
37
+ ],
38
+ });
18
39
  class SelectBaseRootState {
19
40
  opts;
20
41
  touchedInput = $state(false);
@@ -40,12 +61,10 @@ class SelectBaseRootState {
40
61
  });
41
62
  isUsingKeyboard = false;
42
63
  isCombobox = false;
43
- bitsAttrs;
44
64
  domContext = new DOMContext(() => null);
45
65
  constructor(opts) {
46
66
  this.opts = opts;
47
67
  this.isCombobox = opts.isCombobox;
48
- this.bitsAttrs = getSelectBitsAttrs(this);
49
68
  $effect.pre(() => {
50
69
  if (!this.opts.open.current) {
51
70
  this.setHighlightedNode(null);
@@ -62,7 +81,7 @@ class SelectBaseRootState {
62
81
  const node = this.contentNode;
63
82
  if (!node)
64
83
  return [];
65
- return Array.from(node.querySelectorAll(`[${this.bitsAttrs.item}]:not([data-disabled])`));
84
+ return Array.from(node.querySelectorAll(`[${this.getBitsAttr("item")}]:not([data-disabled])`));
66
85
  }
67
86
  setHighlightedToFirstCandidate() {
68
87
  this.setHighlightedNode(null);
@@ -91,6 +110,9 @@ class SelectBaseRootState {
91
110
  toggleMenu() {
92
111
  this.toggleOpen();
93
112
  }
113
+ getBitsAttr = (part) => {
114
+ return selectAttrs.getAttr(part, this.isCombobox ? "combobox" : undefined);
115
+ };
94
116
  }
95
117
  class SelectSingleRootState extends SelectBaseRootState {
96
118
  opts;
@@ -338,7 +360,7 @@ class SelectInputState {
338
360
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
339
361
  onkeydown: this.onkeydown,
340
362
  oninput: this.oninput,
341
- [this.root.bitsAttrs.input]: "",
363
+ [this.root.getBitsAttr("input")]: "",
342
364
  ...attachRef(this.opts.ref, (v) => (this.root.inputNode = v)),
343
365
  }));
344
366
  }
@@ -381,7 +403,7 @@ class SelectComboTriggerState {
381
403
  "aria-haspopup": "listbox",
382
404
  "data-state": getDataOpenClosed(this.root.opts.open.current),
383
405
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
384
- [this.root.bitsAttrs.trigger]: "",
406
+ [this.root.getBitsAttr("trigger")]: "",
385
407
  onpointerdown: this.onpointerdown,
386
408
  onkeydown: this.onkeydown,
387
409
  ...attachRef(this.opts.ref),
@@ -612,7 +634,7 @@ class SelectTriggerState {
612
634
  "data-state": getDataOpenClosed(this.root.opts.open.current),
613
635
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
614
636
  "data-placeholder": this.root.hasValue ? undefined : "",
615
- [this.root.bitsAttrs.trigger]: "",
637
+ [this.root.getBitsAttr("trigger")]: "",
616
638
  onpointerdown: this.onpointerdown,
617
639
  onkeydown: this.onkeydown,
618
640
  onclick: this.onclick,
@@ -648,14 +670,7 @@ class SelectContentState {
648
670
  this.root.isUsingKeyboard = false;
649
671
  }
650
672
  #styles = $derived.by(() => {
651
- const prefix = this.root.isCombobox ? "--bits-combobox" : "--bits-select";
652
- return {
653
- [`${prefix}-content-transform-origin`]: "var(--bits-floating-transform-origin)",
654
- [`${prefix}-content-available-width`]: "var(--bits-floating-available-width)",
655
- [`${prefix}-content-available-height`]: "var(--bits-floating-available-height)",
656
- [`${prefix}-anchor-width`]: " var(--bits-floating-anchor-width)",
657
- [`${prefix}-anchor-height`]: "var(--bits-floating-anchor-height)",
658
- };
673
+ return getFloatingContentCSSVars(this.root.isCombobox ? "combobox" : "select");
659
674
  });
660
675
  onInteractOutside = (e) => {
661
676
  if (e.target === this.root.triggerNode || e.target === this.root.inputNode) {
@@ -685,7 +700,7 @@ class SelectContentState {
685
700
  role: "listbox",
686
701
  "aria-multiselectable": this.root.isMulti ? "true" : undefined,
687
702
  "data-state": getDataOpenClosed(this.root.opts.open.current),
688
- [this.root.bitsAttrs.content]: "",
703
+ [this.root.getBitsAttr("content")]: "",
689
704
  style: {
690
705
  display: "flex",
691
706
  flexDirection: "column",
@@ -822,7 +837,7 @@ class SelectItemState {
822
837
  : undefined,
823
838
  "data-selected": this.root.includesItem(this.opts.value.current) ? "" : undefined,
824
839
  "data-label": this.opts.label.current,
825
- [this.root.bitsAttrs.item]: "",
840
+ [this.root.getBitsAttr("item")]: "",
826
841
  onpointermove: this.onpointermove,
827
842
  onpointerdown: this.onpointerdown,
828
843
  onpointerup: this.onpointerup,
@@ -840,7 +855,7 @@ class SelectGroupState {
840
855
  props = $derived.by(() => ({
841
856
  id: this.opts.id.current,
842
857
  role: "group",
843
- [this.root.bitsAttrs.group]: "",
858
+ [this.root.getBitsAttr("group")]: "",
844
859
  "aria-labelledby": this.labelNode?.id ?? undefined,
845
860
  ...attachRef(this.opts.ref),
846
861
  }));
@@ -854,7 +869,7 @@ class SelectGroupHeadingState {
854
869
  }
855
870
  props = $derived.by(() => ({
856
871
  id: this.opts.id.current,
857
- [this.group.root.bitsAttrs["group-label"]]: "",
872
+ [this.group.root.getBitsAttr("group-label")]: "",
858
873
  ...attachRef(this.opts.ref, (v) => (this.group.labelNode = v)),
859
874
  }));
860
875
  }
@@ -897,7 +912,7 @@ class SelectViewportState {
897
912
  props = $derived.by(() => ({
898
913
  id: this.opts.id.current,
899
914
  role: "presentation",
900
- [this.root.bitsAttrs.viewport]: "",
915
+ [this.root.getBitsAttr("viewport")]: "",
901
916
  style: {
902
917
  // we use position: 'relative' here on the `viewport` so that when we call
903
918
  // `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
@@ -1032,7 +1047,7 @@ class SelectScrollDownButtonState {
1032
1047
  };
1033
1048
  props = $derived.by(() => ({
1034
1049
  ...this.scrollButtonState.props,
1035
- [this.root.bitsAttrs["scroll-down-button"]]: "",
1050
+ [this.root.getBitsAttr("scroll-down-button")]: "",
1036
1051
  }));
1037
1052
  }
1038
1053
  class SelectScrollUpButtonState {
@@ -1073,7 +1088,7 @@ class SelectScrollUpButtonState {
1073
1088
  };
1074
1089
  props = $derived.by(() => ({
1075
1090
  ...this.scrollButtonState.props,
1076
- [this.root.bitsAttrs["scroll-up-button"]]: "",
1091
+ [this.root.getBitsAttr("scroll-up-button")]: "",
1077
1092
  }));
1078
1093
  }
1079
1094
  const SelectRootContext = new Context("Select.Root | Combobox.Root");
@@ -1119,30 +1134,3 @@ export function useSelectGroupHeading(props) {
1119
1134
  export function useSelectHiddenInput(props) {
1120
1135
  return new SelectHiddenInputState(props, SelectRootContext.get());
1121
1136
  }
1122
- ////////////////////////////////////
1123
- // Helpers
1124
- ////////////////////////////////////
1125
- const selectParts = [
1126
- "trigger",
1127
- "content",
1128
- "item",
1129
- "viewport",
1130
- "scroll-up-button",
1131
- "scroll-down-button",
1132
- "group",
1133
- "group-label",
1134
- "separator",
1135
- "arrow",
1136
- "input",
1137
- "content-wrapper",
1138
- "item-text",
1139
- "value",
1140
- ];
1141
- export function getSelectBitsAttrs(root) {
1142
- const isCombobox = root.isCombobox;
1143
- const attrObj = {};
1144
- for (const part of selectParts) {
1145
- attrObj[part] = isCombobox ? `data-combobox-${part}` : `data-select-${part}`;
1146
- }
1147
- return attrObj;
1148
- }
@@ -8,13 +8,12 @@ type SeparatorRootStateProps = WithRefProps<ReadableBoxedValues<{
8
8
  declare class SeparatorRootState {
9
9
  readonly opts: SeparatorRootStateProps;
10
10
  constructor(opts: SeparatorRootStateProps);
11
- props: {
11
+ readonly props: {
12
12
  readonly id: string;
13
13
  readonly role: "none" | "separator";
14
14
  readonly "aria-orientation": "horizontal" | "vertical";
15
15
  readonly "aria-hidden": "true" | undefined;
16
16
  readonly "data-orientation": "horizontal" | "vertical";
17
- readonly "data-separator-root": "";
18
17
  };
19
18
  }
20
19
  export declare function useSeparatorRoot(props: SeparatorRootStateProps): SeparatorRootState;