bits-ui 2.3.0 → 2.4.0

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 (110) 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/calendar/components/calendar.svelte +4 -3
  10. package/dist/bits/checkbox/checkbox.svelte.d.ts +0 -3
  11. package/dist/bits/checkbox/checkbox.svelte.js +14 -14
  12. package/dist/bits/collapsible/collapsible.svelte.d.ts +0 -3
  13. package/dist/bits/collapsible/collapsible.svelte.js +8 -7
  14. package/dist/bits/command/command.svelte.d.ts +0 -12
  15. package/dist/bits/command/command.svelte.js +35 -31
  16. package/dist/bits/date-field/components/date-field.svelte +4 -3
  17. package/dist/bits/date-field/date-field.svelte.d.ts +2 -4
  18. package/dist/bits/date-field/date-field.svelte.js +8 -6
  19. package/dist/bits/date-picker/components/date-picker-trigger.svelte +2 -2
  20. package/dist/bits/date-picker/components/date-picker.svelte +4 -3
  21. package/dist/bits/date-range-field/components/date-range-field.svelte +4 -3
  22. package/dist/bits/date-range-field/date-range-field.svelte.d.ts +1 -3
  23. package/dist/bits/date-range-field/date-range-field.svelte.js +7 -5
  24. package/dist/bits/date-range-picker/components/date-range-picker-trigger.svelte +2 -2
  25. package/dist/bits/date-range-picker/components/date-range-picker.svelte +4 -3
  26. package/dist/bits/dialog/dialog.svelte.d.ts +2 -12
  27. package/dist/bits/dialog/dialog.svelte.js +16 -24
  28. package/dist/bits/index.d.ts +1 -0
  29. package/dist/bits/index.js +1 -0
  30. package/dist/bits/label/label.svelte.d.ts +0 -1
  31. package/dist/bits/label/label.svelte.js +6 -2
  32. package/dist/bits/link-preview/link-preview.svelte.d.ts +0 -2
  33. package/dist/bits/link-preview/link-preview.svelte.js +7 -5
  34. package/dist/bits/menu/components/menu-sub-content-static.svelte +1 -1
  35. package/dist/bits/menu/components/menu-sub-content.svelte +1 -1
  36. package/dist/bits/menu/menu.svelte.d.ts +2 -1
  37. package/dist/bits/menu/menu.svelte.js +39 -21
  38. package/dist/bits/menubar/menubar.svelte.d.ts +1 -7
  39. package/dist/bits/menubar/menubar.svelte.js +12 -14
  40. package/dist/bits/meter/meter.svelte.d.ts +0 -1
  41. package/dist/bits/meter/meter.svelte.js +6 -2
  42. package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +2 -11
  43. package/dist/bits/navigation-menu/navigation-menu.svelte.js +30 -25
  44. package/dist/bits/pagination/pagination.svelte.d.ts +0 -4
  45. package/dist/bits/pagination/pagination.svelte.js +9 -10
  46. package/dist/bits/pin-input/pin-input.svelte.d.ts +0 -2
  47. package/dist/bits/pin-input/pin-input.svelte.js +7 -5
  48. package/dist/bits/popover/popover.svelte.d.ts +0 -3
  49. package/dist/bits/popover/popover.svelte.js +9 -5
  50. package/dist/bits/progress/progress.svelte.d.ts +0 -1
  51. package/dist/bits/progress/progress.svelte.js +6 -2
  52. package/dist/bits/radio-group/radio-group.svelte.d.ts +7 -9
  53. package/dist/bits/radio-group/radio-group.svelte.js +9 -10
  54. package/dist/bits/range-calendar/components/range-calendar.svelte +4 -3
  55. package/dist/bits/range-calendar/range-calendar.svelte.d.ts +38 -38
  56. package/dist/bits/range-calendar/range-calendar.svelte.js +79 -79
  57. package/dist/bits/rating-group/rating-group.svelte.d.ts +0 -2
  58. package/dist/bits/rating-group/rating-group.svelte.js +33 -11
  59. package/dist/bits/scroll-area/scroll-area.svelte.d.ts +15 -19
  60. package/dist/bits/scroll-area/scroll-area.svelte.js +10 -10
  61. package/dist/bits/select/select.svelte.d.ts +28 -30
  62. package/dist/bits/select/select.svelte.js +37 -49
  63. package/dist/bits/separator/separator.svelte.d.ts +1 -2
  64. package/dist/bits/separator/separator.svelte.js +6 -3
  65. package/dist/bits/slider/slider.svelte.d.ts +17 -24
  66. package/dist/bits/slider/slider.svelte.js +15 -17
  67. package/dist/bits/switch/switch.svelte.d.ts +6 -8
  68. package/dist/bits/switch/switch.svelte.js +7 -5
  69. package/dist/bits/tabs/tabs.svelte.d.ts +5 -9
  70. package/dist/bits/tabs/tabs.svelte.js +11 -11
  71. package/dist/bits/time-field/components/time-field.svelte +4 -3
  72. package/dist/bits/time-field/time-field.svelte.d.ts +1 -3
  73. package/dist/bits/time-field/time-field.svelte.js +7 -5
  74. package/dist/bits/time-range-field/components/time-range-field.svelte +4 -3
  75. package/dist/bits/time-range-field/time-range-field.svelte.d.ts +1 -3
  76. package/dist/bits/time-range-field/time-range-field.svelte.js +7 -5
  77. package/dist/bits/toggle/toggle.svelte.d.ts +3 -3
  78. package/dist/bits/toggle/toggle.svelte.js +6 -3
  79. package/dist/bits/toggle-group/toggle-group.svelte.d.ts +1 -2
  80. package/dist/bits/toggle-group/toggle-group.svelte.js +8 -6
  81. package/dist/bits/toolbar/toolbar.svelte.d.ts +11 -18
  82. package/dist/bits/toolbar/toolbar.svelte.js +14 -17
  83. package/dist/bits/tooltip/tooltip.svelte.d.ts +13 -14
  84. package/dist/bits/tooltip/tooltip.svelte.js +7 -5
  85. package/dist/bits/utilities/config/bits-config.d.ts +44 -0
  86. package/dist/bits/utilities/config/bits-config.js +92 -0
  87. package/dist/bits/utilities/config/components/bits-config.svelte +14 -0
  88. package/dist/bits/utilities/config/components/bits-config.svelte.d.ts +4 -0
  89. package/dist/bits/utilities/config/exports.d.ts +2 -0
  90. package/dist/bits/utilities/config/exports.js +2 -0
  91. package/dist/bits/utilities/config/index.d.ts +1 -0
  92. package/dist/bits/utilities/config/index.js +1 -0
  93. package/dist/bits/utilities/config/prop-resolvers.d.ts +13 -0
  94. package/dist/bits/utilities/config/prop-resolvers.js +37 -0
  95. package/dist/bits/utilities/config/types.d.ts +13 -0
  96. package/dist/bits/utilities/config/types.js +1 -0
  97. package/dist/bits/utilities/portal/portal.svelte +21 -21
  98. package/dist/bits/utilities/portal/types.d.ts +2 -1
  99. package/dist/index.d.ts +1 -1
  100. package/dist/index.js +1 -1
  101. package/dist/internal/attrs.d.ts +14 -0
  102. package/dist/internal/attrs.js +18 -0
  103. package/dist/internal/date-time/calendar-helpers.svelte.d.ts +1 -0
  104. package/dist/internal/date-time/calendar-helpers.svelte.js +18 -1
  105. package/dist/internal/use-arrow-navigation.d.ts +2 -2
  106. package/dist/internal/use-arrow-navigation.js +1 -1
  107. package/dist/internal/use-data-typeahead.svelte.d.ts +1 -1
  108. package/dist/internal/use-data-typeahead.svelte.js +1 -1
  109. package/dist/types.d.ts +1 -0
  110. package/package.json +1 -1
@@ -7,7 +7,7 @@ import { Context, useDebounce, watch } from "runed";
7
7
  import { untrack } from "svelte";
8
8
  import { SvelteMap } from "svelte/reactivity";
9
9
  import { useId } from "../../shared/index.js";
10
- import { getAriaExpanded, getDataDisabled, getDataOpenClosed, getDataOrientation, } from "../../internal/attrs.js";
10
+ import { createBitsAttrs, getAriaExpanded, getDataDisabled, getDataOpenClosed, getDataOrientation, } from "../../internal/attrs.js";
11
11
  import { noop } from "../../internal/noop.js";
12
12
  import { getTabbableCandidates } from "../../internal/focus.js";
13
13
  import { kbd } from "../../internal/kbd.js";
@@ -17,16 +17,21 @@ import { useArrowNavigation } from "../../internal/use-arrow-navigation.js";
17
17
  import { boxAutoReset } from "../../internal/box-auto-reset.svelte.js";
18
18
  import { useResizeObserver } from "../../internal/use-resize-observer.svelte.js";
19
19
  import { isElement } from "../../internal/is.js";
20
- const NAVIGATION_MENU_ROOT_ATTR = "data-navigation-menu-root";
21
- const NAVIGATION_MENU_ATTR = "data-navigation-menu";
22
- const NAVIGATION_MENU_SUB_ATTR = "data-navigation-menu-sub";
23
- const NAVIGATION_MENU_ITEM_ATTR = "data-navigation-menu-item";
24
- const NAVIGATION_MENU_INDICATOR_ATTR = "data-navigation-menu-indicator";
25
- const NAVIGATION_MENU_LIST_ATTR = "data-navigation-menu-list";
26
- const NAVIGATION_MENU_TRIGGER_ATTR = "data-navigation-menu-trigger";
27
- const NAVIGATION_MENU_CONTENT_ATTR = "data-navigation-menu-content";
28
- const NAVIGATION_MENU_LINK_ATTR = "data-navigation-menu-link";
29
- const NAVIGATION_MENU_VIEWPORT_ATTR = "data-navigation-menu-viewport";
20
+ const navigationMenuAttrs = createBitsAttrs({
21
+ component: "navigation-menu",
22
+ parts: [
23
+ "root",
24
+ "sub",
25
+ "item",
26
+ "list",
27
+ "trigger",
28
+ "content",
29
+ "link",
30
+ "viewport",
31
+ "menu",
32
+ "indicator",
33
+ ],
34
+ });
30
35
  class NavigationMenuProviderState {
31
36
  opts;
32
37
  indicatorTrackRef = box(null);
@@ -135,8 +140,8 @@ class NavigationMenuRootState {
135
140
  id: this.opts.id.current,
136
141
  "data-orientation": getDataOrientation(this.opts.orientation.current),
137
142
  dir: this.opts.dir.current,
138
- [NAVIGATION_MENU_ROOT_ATTR]: "",
139
- [NAVIGATION_MENU_ATTR]: "",
143
+ [navigationMenuAttrs.root]: "",
144
+ [navigationMenuAttrs.menu]: "",
140
145
  ...attachRef(this.opts.ref),
141
146
  }));
142
147
  }
@@ -173,8 +178,8 @@ class NavigationMenuSubState {
173
178
  props = $derived.by(() => ({
174
179
  id: this.opts.id.current,
175
180
  "data-orientation": getDataOrientation(this.opts.orientation.current),
176
- [NAVIGATION_MENU_SUB_ATTR]: "",
177
- [NAVIGATION_MENU_ATTR]: "",
181
+ [navigationMenuAttrs.sub]: "",
182
+ [navigationMenuAttrs.menu]: "",
178
183
  ...attachRef(this.opts.ref),
179
184
  }));
180
185
  }
@@ -191,7 +196,7 @@ class NavigationMenuListState {
191
196
  this.context = context;
192
197
  this.rovingFocusGroup = useRovingFocus({
193
198
  rootNode: opts.ref,
194
- candidateSelector: `[${NAVIGATION_MENU_TRIGGER_ATTR}]:not([data-disabled]), [${NAVIGATION_MENU_LINK_ATTR}]:not([data-disabled])`,
199
+ candidateSelector: `${navigationMenuAttrs.selector("trigger")}:not([data-disabled]), ${navigationMenuAttrs.selector("link")}:not([data-disabled])`,
195
200
  loop: box.with(() => false),
196
201
  orientation: this.context.opts.orientation,
197
202
  });
@@ -210,7 +215,7 @@ class NavigationMenuListState {
210
215
  props = $derived.by(() => ({
211
216
  id: this.opts.id.current,
212
217
  "data-orientation": getDataOrientation(this.context.opts.orientation.current),
213
- [NAVIGATION_MENU_LIST_ATTR]: "",
218
+ [navigationMenuAttrs.list]: "",
214
219
  ...attachRef(this.opts.ref),
215
220
  }));
216
221
  }
@@ -254,7 +259,7 @@ export class NavigationMenuItemState {
254
259
  onContentFocusOutside = this.#handleContentExit;
255
260
  props = $derived.by(() => ({
256
261
  id: this.opts.id.current,
257
- [NAVIGATION_MENU_ITEM_ATTR]: "",
262
+ [navigationMenuAttrs.item]: "",
258
263
  }));
259
264
  }
260
265
  class NavigationMenuTriggerState {
@@ -347,7 +352,7 @@ class NavigationMenuTriggerState {
347
352
  "data-value": this.itemContext.opts.value.current,
348
353
  "aria-expanded": getAriaExpanded(this.open),
349
354
  "aria-controls": this.itemContext.contentId,
350
- [NAVIGATION_MENU_TRIGGER_ATTR]: "",
355
+ [navigationMenuAttrs.trigger]: "",
351
356
  onpointermove: this.onpointermove,
352
357
  onpointerleave: this.onpointerleave,
353
358
  onpointerenter: this.onpointerenter,
@@ -428,7 +433,7 @@ class NavigationMenuLinkState {
428
433
  onblur: this.onblur,
429
434
  onpointerenter: this.onpointerenter,
430
435
  onpointermove: this.onpointermove,
431
- [NAVIGATION_MENU_LINK_ATTR]: "",
436
+ [navigationMenuAttrs.link]: "",
432
437
  ...attachRef(this.opts.ref),
433
438
  }));
434
439
  }
@@ -489,7 +494,7 @@ class NavigationMenuIndicatorImplState {
489
494
  transform: `translateY(${this.position?.offset}px)`,
490
495
  }),
491
496
  },
492
- [NAVIGATION_MENU_INDICATOR_ATTR]: "",
497
+ [navigationMenuAttrs.indicator]: "",
493
498
  ...attachRef(this.opts.ref),
494
499
  }));
495
500
  }
@@ -632,7 +637,7 @@ class NavigationMenuContentImplState {
632
637
  const target = e.target;
633
638
  if (!isElement(target))
634
639
  return;
635
- if (target.closest(`[${NAVIGATION_MENU_ATTR}]`) !==
640
+ if (target.closest(navigationMenuAttrs.selector("menu")) !==
636
641
  this.context.opts.rootNavigationMenuRef.current)
637
642
  return;
638
643
  const isMetaKey = e.altKey || e.ctrlKey || e.metaKey;
@@ -669,7 +674,7 @@ class NavigationMenuContentImplState {
669
674
  return;
670
675
  const newSelectedElement = useArrowNavigation(e, activeEl, undefined, {
671
676
  itemsArray: candidates,
672
- attributeName: `[${NAVIGATION_MENU_LINK_ATTR}]`,
677
+ candidateSelector: navigationMenuAttrs.selector("link"),
673
678
  loop: false,
674
679
  enableIgnoredElement: true,
675
680
  });
@@ -688,7 +693,7 @@ class NavigationMenuContentImplState {
688
693
  "data-orientation": getDataOrientation(this.context.opts.orientation.current),
689
694
  "data-state": getDataOpenClosed(this.context.opts.value.current === this.itemContext.opts.value.current),
690
695
  onkeydown: this.onkeydown,
691
- [NAVIGATION_MENU_CONTENT_ATTR]: "",
696
+ [navigationMenuAttrs.content]: "",
692
697
  ...attachRef(this.opts.ref),
693
698
  }));
694
699
  }
@@ -745,7 +750,7 @@ class NavigationMenuViewportState {
745
750
  "--bits-navigation-menu-viewport-width": this.viewportWidth,
746
751
  "--bits-navigation-menu-viewport-height": this.viewportHeight,
747
752
  },
748
- [NAVIGATION_MENU_VIEWPORT_ATTR]: "",
753
+ [navigationMenuAttrs.viewport]: "",
749
754
  onpointerenter: this.context.onContentEnter,
750
755
  onpointerleave: this.context.onContentLeave,
751
756
  ...attachRef(this.opts.ref, (v) => (this.context.viewportRef.current = v)),
@@ -38,7 +38,6 @@ declare class PaginationRootState {
38
38
  props: {
39
39
  readonly id: string;
40
40
  readonly "data-orientation": "horizontal" | "vertical";
41
- readonly "data-pagination-root": "";
42
41
  };
43
42
  }
44
43
  type PaginationPageStateProps = WithRefProps<ReadableBoxedValues<{
@@ -57,7 +56,6 @@ declare class PaginationPageState {
57
56
  readonly "aria-label": `Page ${number}`;
58
57
  readonly "data-value": `${number}`;
59
58
  readonly "data-selected": "" | undefined;
60
- readonly "data-pagination-page": "";
61
59
  readonly onclick: (e: BitsMouseEvent) => void;
62
60
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
63
61
  };
@@ -76,8 +74,6 @@ declare class PaginationButtonState {
76
74
  onkeydown(e: BitsKeyboardEvent): void;
77
75
  props: {
78
76
  readonly id: string;
79
- readonly "data-pagination-prev": "" | undefined;
80
- readonly "data-pagination-next": "" | undefined;
81
77
  readonly disabled: boolean;
82
78
  readonly onclick: (e: BitsMouseEvent) => void;
83
79
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
@@ -1,14 +1,14 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
2
  import { Context } from "runed";
3
- import { getDataOrientation } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, getDataOrientation } from "../../internal/attrs.js";
4
4
  import { getElemDirection } from "../../internal/locale.js";
5
5
  import { kbd } from "../../internal/kbd.js";
6
6
  import { getDirectionalKeys } from "../../internal/get-directional-keys.js";
7
7
  import { useId } from "../../shared/index.js";
8
- const PAGINATION_ROOT_ATTR = "data-pagination-root";
9
- const PAGINATION_PAGE_ATTR = "data-pagination-page";
10
- const PAGINATION_PREV_ATTR = "data-pagination-prev";
11
- const PAGINATION_NEXT_ATTR = "data-pagination-next";
8
+ const paginationAttrs = createBitsAttrs({
9
+ component: "pagination",
10
+ parts: ["root", "page", "prev", "next"],
11
+ });
12
12
  class PaginationRootState {
13
13
  opts;
14
14
  totalPages = $derived.by(() => {
@@ -42,7 +42,7 @@ class PaginationRootState {
42
42
  const node = this.opts.ref.current;
43
43
  if (!node)
44
44
  return;
45
- return node.querySelector(`[data-pagination-${type}]`);
45
+ return node.querySelector(paginationAttrs.selector(type));
46
46
  }
47
47
  hasPrevPage = $derived.by(() => this.opts.page.current > 1);
48
48
  hasNextPage = $derived.by(() => this.opts.page.current < this.totalPages);
@@ -60,7 +60,7 @@ class PaginationRootState {
60
60
  props = $derived.by(() => ({
61
61
  id: this.opts.id.current,
62
62
  "data-orientation": getDataOrientation(this.opts.orientation.current),
63
- [PAGINATION_ROOT_ATTR]: "",
63
+ [paginationAttrs.root]: "",
64
64
  ...attachRef(this.opts.ref),
65
65
  }));
66
66
  }
@@ -95,7 +95,7 @@ class PaginationPageState {
95
95
  "aria-label": `Page ${this.opts.page.current.value}`,
96
96
  "data-value": `${this.opts.page.current.value}`,
97
97
  "data-selected": this.#isSelected ? "" : undefined,
98
- [PAGINATION_PAGE_ATTR]: "",
98
+ [paginationAttrs.page]: "",
99
99
  //
100
100
  onclick: this.onclick,
101
101
  onkeydown: this.onkeydown,
@@ -141,8 +141,7 @@ class PaginationButtonState {
141
141
  }
142
142
  props = $derived.by(() => ({
143
143
  id: this.opts.id.current,
144
- [PAGINATION_PREV_ATTR]: this.opts.type === "prev" ? "" : undefined,
145
- [PAGINATION_NEXT_ATTR]: this.opts.type === "next" ? "" : undefined,
144
+ [paginationAttrs[this.opts.type]]: "",
146
145
  disabled: this.#isDisabled,
147
146
  //
148
147
  onclick: this.onclick,
@@ -27,7 +27,6 @@ declare class PinInputRootState {
27
27
  onkeydown: (e: BitsKeyboardEvent) => void;
28
28
  rootProps: {
29
29
  readonly id: string;
30
- readonly "data-pin-input-root": "";
31
30
  readonly style: {
32
31
  position: string;
33
32
  cursor: string;
@@ -108,7 +107,6 @@ declare class PinInputCellState {
108
107
  constructor(opts: PinInputCellStateProps);
109
108
  props: {
110
109
  readonly id: string;
111
- readonly "data-pin-input-cell": "";
112
110
  readonly "data-active": "" | undefined;
113
111
  readonly "data-inactive": "" | undefined;
114
112
  };
@@ -2,13 +2,15 @@ import { Previous, watch } from "runed";
2
2
  import { onMount } from "svelte";
3
3
  import { box, attachRef, DOMContext } from "svelte-toolbelt";
4
4
  import { usePasswordManagerBadge } from "./usePasswordManager.svelte.js";
5
- import { getDisabled } from "../../internal/attrs.js";
5
+ import { createBitsAttrs, getDisabled } from "../../internal/attrs.js";
6
6
  import { on } from "svelte/events";
7
7
  export const REGEXP_ONLY_DIGITS = "^\\d+$";
8
8
  export const REGEXP_ONLY_CHARS = "^[a-zA-Z]+$";
9
9
  export const REGEXP_ONLY_DIGITS_AND_CHARS = "^[a-zA-Z0-9]+$";
10
- const ROOT_ATTR = "data-pin-input-root";
11
- const CELL_ATTR = "data-pin-input-cell";
10
+ const pinInputAttrs = createBitsAttrs({
11
+ component: "pin-input",
12
+ parts: ["root", "cell"],
13
+ });
12
14
  const KEYS_TO_IGNORE = [
13
15
  "Backspace",
14
16
  "Delete",
@@ -151,7 +153,7 @@ class PinInputRootState {
151
153
  }));
152
154
  rootProps = $derived.by(() => ({
153
155
  id: this.opts.id.current,
154
- [ROOT_ATTR]: "",
156
+ [pinInputAttrs.root]: "",
155
157
  style: this.#rootStyles,
156
158
  ...attachRef(this.opts.ref),
157
159
  }));
@@ -394,7 +396,7 @@ class PinInputCellState {
394
396
  }
395
397
  props = $derived.by(() => ({
396
398
  id: this.opts.id.current,
397
- [CELL_ATTR]: "",
399
+ [pinInputAttrs.cell]: "",
398
400
  "data-active": this.opts.cell.current.isActive ? "" : undefined,
399
401
  "data-inactive": !this.opts.cell.current.isActive ? "" : undefined,
400
402
  ...attachRef(this.opts.ref),
@@ -28,7 +28,6 @@ declare class PopoverTriggerState {
28
28
  readonly "aria-expanded": "true" | "false";
29
29
  readonly "data-state": "open" | "closed";
30
30
  readonly "aria-controls": string | undefined;
31
- readonly "data-popover-trigger": "";
32
31
  readonly disabled: boolean;
33
32
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
34
33
  readonly onclick: (e: BitsMouseEvent) => void;
@@ -53,7 +52,6 @@ declare class PopoverContentState {
53
52
  readonly id: string;
54
53
  readonly tabindex: -1;
55
54
  readonly "data-state": "open" | "closed";
56
- readonly "data-popover-content": "";
57
55
  readonly style: {
58
56
  readonly pointerEvents: "auto";
59
57
  };
@@ -76,7 +74,6 @@ declare class PopoverCloseState {
76
74
  readonly onclick: (_: BitsPointerEvent) => void;
77
75
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
78
76
  readonly type: "button";
79
- readonly "data-popover-close": "";
80
77
  };
81
78
  }
82
79
  export declare function usePopoverRoot(props: PopoverRootStateProps): PopoverRootState;
@@ -1,8 +1,12 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
2
  import { Context } from "runed";
3
3
  import { kbd } from "../../internal/kbd.js";
4
- import { getAriaExpanded, getDataOpenClosed } from "../../internal/attrs.js";
4
+ import { createBitsAttrs, getAriaExpanded, getDataOpenClosed } from "../../internal/attrs.js";
5
5
  import { isElement } from "../../internal/is.js";
6
+ const popoverAttrs = createBitsAttrs({
7
+ component: "popover",
8
+ parts: ["root", "trigger", "content", "close"],
9
+ });
6
10
  class PopoverRootState {
7
11
  opts;
8
12
  contentNode = $state(null);
@@ -55,7 +59,7 @@ class PopoverTriggerState {
55
59
  "aria-expanded": getAriaExpanded(this.root.opts.open.current),
56
60
  "data-state": getDataOpenClosed(this.root.opts.open.current),
57
61
  "aria-controls": this.#getAriaControls(),
58
- "data-popover-trigger": "",
62
+ [popoverAttrs.trigger]: "",
59
63
  disabled: this.opts.disabled.current,
60
64
  //
61
65
  onkeydown: this.onkeydown,
@@ -76,7 +80,7 @@ class PopoverContentState {
76
80
  return;
77
81
  if (!isElement(e.target))
78
82
  return;
79
- const closestTrigger = e.target.closest(`[data-popover-trigger]`);
83
+ const closestTrigger = e.target.closest(popoverAttrs.selector("trigger"));
80
84
  if (closestTrigger === this.root.triggerNode)
81
85
  return;
82
86
  this.root.handleClose();
@@ -99,7 +103,7 @@ class PopoverContentState {
99
103
  id: this.opts.id.current,
100
104
  tabindex: -1,
101
105
  "data-state": getDataOpenClosed(this.root.opts.open.current),
102
- "data-popover-content": "",
106
+ [popoverAttrs.content]: "",
103
107
  style: {
104
108
  pointerEvents: "auto",
105
109
  },
@@ -134,7 +138,7 @@ class PopoverCloseState {
134
138
  onclick: this.onclick,
135
139
  onkeydown: this.onkeydown,
136
140
  type: "button",
137
- "data-popover-close": "",
141
+ [popoverAttrs.close]: "",
138
142
  ...attachRef(this.opts.ref),
139
143
  }));
140
144
  }
@@ -19,7 +19,6 @@ declare class ProgressRootState {
19
19
  readonly "data-max": number;
20
20
  readonly "data-min": number;
21
21
  readonly "data-indeterminate": "" | undefined;
22
- readonly "data-progress-root": "";
23
22
  };
24
23
  }
25
24
  export declare function useProgressRootState(props: ProgressRootStateProps): ProgressRootState;
@@ -1,5 +1,9 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
- const ROOT_ATTR = "data-progress-root";
2
+ import { createBitsAttrs } from "../../internal/attrs.js";
3
+ const progressAttrs = createBitsAttrs({
4
+ component: "progress",
5
+ parts: ["root"],
6
+ });
3
7
  class ProgressRootState {
4
8
  opts;
5
9
  constructor(opts) {
@@ -16,7 +20,7 @@ class ProgressRootState {
16
20
  "data-max": this.opts.max.current,
17
21
  "data-min": this.opts.min.current,
18
22
  "data-indeterminate": this.opts.value.current === null ? "" : undefined,
19
- [ROOT_ATTR]: "",
23
+ [progressAttrs.root]: "",
20
24
  ...attachRef(this.opts.ref),
21
25
  }));
22
26
  }
@@ -13,18 +13,17 @@ type RadioGroupRootStateProps = WithRefProps<ReadableBoxedValues<{
13
13
  }>>;
14
14
  declare class RadioGroupRootState {
15
15
  readonly opts: RadioGroupRootStateProps;
16
+ readonly hasValue: boolean;
16
17
  rovingFocusGroup: UseRovingFocusReturn;
17
- hasValue: boolean;
18
18
  constructor(opts: RadioGroupRootStateProps);
19
19
  isChecked(value: string): boolean;
20
20
  setValue(value: string): void;
21
- props: {
21
+ readonly props: {
22
22
  readonly id: string;
23
23
  readonly role: "radiogroup";
24
24
  readonly "aria-required": "true" | "false";
25
25
  readonly "data-disabled": "" | undefined;
26
26
  readonly "data-orientation": Orientation;
27
- readonly "data-radio-group-root": "";
28
27
  };
29
28
  }
30
29
  type RadioGroupItemStateProps = WithRefProps<ReadableBoxedValues<{
@@ -35,15 +34,15 @@ declare class RadioGroupItemState {
35
34
  #private;
36
35
  readonly opts: RadioGroupItemStateProps;
37
36
  readonly root: RadioGroupRootState;
38
- checked: boolean;
37
+ readonly checked: boolean;
39
38
  constructor(opts: RadioGroupItemStateProps, root: RadioGroupRootState);
40
39
  onclick(_: BitsMouseEvent): void;
41
40
  onfocus(_: BitsFocusEvent): void;
42
41
  onkeydown(e: BitsKeyboardEvent): void;
43
- snippetProps: {
42
+ readonly snippetProps: {
44
43
  checked: boolean;
45
44
  };
46
- props: {
45
+ readonly props: {
47
46
  readonly id: string;
48
47
  readonly disabled: true | undefined;
49
48
  readonly "data-value": string;
@@ -51,7 +50,6 @@ declare class RadioGroupItemState {
51
50
  readonly "data-disabled": "" | undefined;
52
51
  readonly "data-state": "checked" | "unchecked";
53
52
  readonly "aria-checked": "true" | "false" | "mixed";
54
- readonly "data-radio-group-item": "";
55
53
  readonly type: "button";
56
54
  readonly role: "radio";
57
55
  readonly tabindex: number;
@@ -62,8 +60,8 @@ declare class RadioGroupItemState {
62
60
  }
63
61
  declare class RadioGroupInputState {
64
62
  readonly root: RadioGroupRootState;
65
- shouldRender: boolean;
66
- props: {
63
+ readonly shouldRender: boolean;
64
+ readonly props: {
67
65
  readonly name: string | undefined;
68
66
  readonly value: string;
69
67
  readonly required: boolean;
@@ -1,19 +1,21 @@
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 { useRovingFocus, } from "../../internal/use-roving-focus.svelte.js";
5
5
  import { kbd } from "../../internal/kbd.js";
6
- const RADIO_GROUP_ROOT_ATTR = "data-radio-group-root";
7
- const RADIO_GROUP_ITEM_ATTR = "data-radio-group-item";
6
+ const radioGroupAttrs = createBitsAttrs({
7
+ component: "radio-group",
8
+ parts: ["root", "item"],
9
+ });
8
10
  class RadioGroupRootState {
9
11
  opts;
10
- rovingFocusGroup;
11
12
  hasValue = $derived.by(() => this.opts.value.current !== "");
13
+ rovingFocusGroup;
12
14
  constructor(opts) {
13
15
  this.opts = opts;
14
16
  this.rovingFocusGroup = useRovingFocus({
15
17
  rootNode: this.opts.ref,
16
- candidateAttr: RADIO_GROUP_ITEM_ATTR,
18
+ candidateAttr: radioGroupAttrs.item,
17
19
  loop: this.opts.loop,
18
20
  orientation: this.opts.orientation,
19
21
  });
@@ -30,7 +32,7 @@ class RadioGroupRootState {
30
32
  "aria-required": getAriaRequired(this.opts.required.current),
31
33
  "data-disabled": getDataDisabled(this.opts.disabled.current),
32
34
  "data-orientation": this.opts.orientation.current,
33
- [RADIO_GROUP_ROOT_ATTR]: "",
35
+ [radioGroupAttrs.root]: "",
34
36
  ...attachRef(this.opts.ref),
35
37
  }));
36
38
  }
@@ -93,7 +95,7 @@ class RadioGroupItemState {
93
95
  "data-disabled": getDataDisabled(this.#isDisabled),
94
96
  "data-state": this.#isChecked ? "checked" : "unchecked",
95
97
  "aria-checked": getAriaChecked(this.#isChecked, false),
96
- [RADIO_GROUP_ITEM_ATTR]: "",
98
+ [radioGroupAttrs.item]: "",
97
99
  type: "button",
98
100
  role: "radio",
99
101
  tabindex: this.#tabIndex,
@@ -104,9 +106,6 @@ class RadioGroupItemState {
104
106
  ...attachRef(this.opts.ref),
105
107
  }));
106
108
  }
107
- //
108
- // INPUT
109
- //
110
109
  class RadioGroupInputState {
111
110
  root;
112
111
  shouldRender = $derived.by(() => this.root.opts.name.current !== undefined);
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { watch } from "runed";
2
3
  import { box, mergeProps } from "svelte-toolbelt";
3
4
  import { type DateValue } from "@internationalized/date";
4
5
  import type { RangeCalendarRootProps } from "../types.js";
@@ -6,7 +7,7 @@
6
7
  import { noop } from "../../../internal/noop.js";
7
8
  import { createId } from "../../../internal/create-id.js";
8
9
  import { getDefaultDate } from "../../../internal/date-time/utils.js";
9
- import { watch } from "runed";
10
+ import { resolveLocaleProp } from "../../utilities/config/prop-resolvers.js";
10
11
 
11
12
  const uid = $props.id();
12
13
 
@@ -26,7 +27,7 @@
26
27
  isDateUnavailable = () => false,
27
28
  fixedWeeks = false,
28
29
  numberOfMonths = 1,
29
- locale = "en",
30
+ locale,
30
31
  calendarLabel = "Event",
31
32
  disabled = false,
32
33
  readonly = false,
@@ -107,7 +108,7 @@
107
108
  weekStartsOn: box.with(() => weekStartsOn),
108
109
  weekdayFormat: box.with(() => weekdayFormat),
109
110
  numberOfMonths: box.with(() => numberOfMonths),
110
- locale: box.with(() => locale),
111
+ locale: resolveLocaleProp(() => locale),
111
112
  calendarLabel: box.with(() => calendarLabel),
112
113
  fixedWeeks: box.with(() => fixedWeeks),
113
114
  disableDaysOutsideMonth: box.with(() => disableDaysOutsideMonth),