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,17 +7,15 @@ import { executeCallbacks, onMountEffect, attachRef, } from "svelte-toolbelt";
7
7
  import { on } from "svelte/events";
8
8
  import { Context, watch } from "runed";
9
9
  import { getRangeStyles, getThumbStyles, getTickStyles, normalizeSteps, snapValueToCustomSteps, getAdjacentStepValue, getTickLabelStyles, getThumbLabelStyles, } from "./helpers.js";
10
- import { getAriaDisabled, getAriaOrientation, getDataDisabled, getDataOrientation, } from "../../internal/attrs.js";
10
+ import { createBitsAttrs, getAriaDisabled, getAriaOrientation, getDataDisabled, getDataOrientation, } from "../../internal/attrs.js";
11
11
  import { kbd } from "../../internal/kbd.js";
12
12
  import { isElementOrSVGElement } from "../../internal/is.js";
13
13
  import { isValidIndex } from "../../internal/arrays.js";
14
14
  import { linearScale } from "../../internal/math.js";
15
- const SLIDER_ROOT_ATTR = "data-slider-root";
16
- const SLIDER_THUMB_ATTR = "data-slider-thumb";
17
- const SLIDER_RANGE_ATTR = "data-slider-range";
18
- const SLIDER_TICK_ATTR = "data-slider-tick";
19
- const SLIDER_TICK_LABEL_ATTR = "data-slider-tick-label";
20
- const SLIDER_THUMB_LABEL_ATTR = "data-slider-thumb-label";
15
+ const sliderAttrs = createBitsAttrs({
16
+ component: "slider",
17
+ parts: ["root", "thumb", "range", "tick", "tick-label", "thumb-label"],
18
+ });
21
19
  class SliderBaseRootState {
22
20
  opts;
23
21
  isActive = $state(false);
@@ -48,7 +46,7 @@ class SliderBaseRootState {
48
46
  const node = this.opts.ref.current;
49
47
  if (!node)
50
48
  return [];
51
- return Array.from(node.querySelectorAll(`[${SLIDER_THUMB_ATTR}]`));
49
+ return Array.from(node.querySelectorAll(sliderAttrs.selector("thumb")));
52
50
  };
53
51
  getThumbScale = () => {
54
52
  // If trackPadding is explicitly set, use it directly instead of calculating from thumb size
@@ -92,7 +90,7 @@ class SliderBaseRootState {
92
90
  style: {
93
91
  touchAction: this.#touchAction,
94
92
  },
95
- [SLIDER_ROOT_ATTR]: "",
93
+ [sliderAttrs.root]: "",
96
94
  ...attachRef(this.opts.ref),
97
95
  }));
98
96
  }
@@ -225,7 +223,7 @@ class SliderSingleRootState extends SliderBaseRootState {
225
223
  "data-value": thumbValue,
226
224
  "data-orientation": getDataOrientation(this.opts.orientation.current),
227
225
  style,
228
- [SLIDER_THUMB_ATTR]: "",
226
+ [sliderAttrs.thumb]: "",
229
227
  };
230
228
  });
231
229
  });
@@ -250,7 +248,7 @@ class SliderSingleRootState extends SliderBaseRootState {
250
248
  "data-value": tickValue,
251
249
  "data-selected": this.isTickValueSelected(tickValue) ? "" : undefined,
252
250
  style,
253
- [SLIDER_TICK_ATTR]: "",
251
+ [sliderAttrs.tick]: "",
254
252
  };
255
253
  });
256
254
  });
@@ -428,7 +426,7 @@ class SliderMultiRootState extends SliderBaseRootState {
428
426
  const node = this.opts.ref.current;
429
427
  if (!node)
430
428
  return [];
431
- const thumbs = Array.from(node.querySelectorAll(`[${SLIDER_THUMB_ATTR}]`));
429
+ const thumbs = Array.from(node.querySelectorAll(sliderAttrs.selector("thumb")));
432
430
  return thumbs;
433
431
  };
434
432
  updateValue = (thumbValue, idx) => {
@@ -487,7 +485,7 @@ class SliderMultiRootState extends SliderBaseRootState {
487
485
  "data-value": thumbValue,
488
486
  "data-orientation": getDataOrientation(this.opts.orientation.current),
489
487
  style,
490
- [SLIDER_THUMB_ATTR]: "",
488
+ [sliderAttrs.thumb]: "",
491
489
  };
492
490
  });
493
491
  });
@@ -513,7 +511,7 @@ class SliderMultiRootState extends SliderBaseRootState {
513
511
  "data-bounded": bounded ? "" : undefined,
514
512
  "data-value": tickValue,
515
513
  style,
516
- [SLIDER_TICK_ATTR]: "",
514
+ [sliderAttrs.tick]: "",
517
515
  };
518
516
  });
519
517
  });
@@ -591,7 +589,7 @@ class SliderRangeState {
591
589
  "data-orientation": getDataOrientation(this.root.opts.orientation.current),
592
590
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
593
591
  style: this.rangeStyles,
594
- [SLIDER_RANGE_ATTR]: "",
592
+ [sliderAttrs.range]: "",
595
593
  ...attachRef(this.opts.ref),
596
594
  }));
597
595
  }
@@ -740,7 +738,7 @@ class SliderTickLabelState {
740
738
  "data-selected": this.root.isTickValueSelected(tickValue) ? "" : undefined,
741
739
  "data-position": labelPosition,
742
740
  style,
743
- [SLIDER_TICK_LABEL_ATTR]: "",
741
+ [sliderAttrs["tick-label"]]: "",
744
742
  ...attachRef(this.opts.ref),
745
743
  };
746
744
  });
@@ -766,7 +764,7 @@ class SliderThumbLabelState {
766
764
  "data-active": this.root.isThumbActive(this.opts.index.current) ? "" : undefined,
767
765
  "data-position": labelPosition,
768
766
  style,
769
- [SLIDER_THUMB_LABEL_ATTR]: "",
767
+ [sliderAttrs["thumb-label"]]: "",
770
768
  ...attachRef(this.opts.ref),
771
769
  };
772
770
  });
@@ -14,21 +14,20 @@ declare class SwitchRootState {
14
14
  constructor(opts: SwitchRootStateProps);
15
15
  onkeydown(e: BitsKeyboardEvent): void;
16
16
  onclick(_: BitsPointerEvent): void;
17
- sharedProps: {
17
+ readonly sharedProps: {
18
18
  "data-disabled": "" | undefined;
19
19
  "data-state": "checked" | "unchecked";
20
20
  "data-required": "" | undefined;
21
21
  };
22
- snippetProps: {
22
+ readonly snippetProps: {
23
23
  checked: boolean;
24
24
  };
25
- props: {
25
+ readonly props: {
26
26
  readonly id: string;
27
27
  readonly role: "switch";
28
28
  readonly disabled: true | undefined;
29
29
  readonly "aria-checked": "true" | "false" | "mixed";
30
30
  readonly "aria-required": "true" | "false";
31
- readonly "data-switch-root": "";
32
31
  readonly onclick: (_: BitsPointerEvent) => void;
33
32
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
34
33
  readonly "data-disabled": "" | undefined;
@@ -38,7 +37,7 @@ declare class SwitchRootState {
38
37
  }
39
38
  declare class SwitchInputState {
40
39
  readonly root: SwitchRootState;
41
- shouldRender: boolean;
40
+ readonly shouldRender: boolean;
42
41
  constructor(root: SwitchRootState);
43
42
  props: {
44
43
  readonly type: "checkbox";
@@ -54,12 +53,11 @@ declare class SwitchThumbState {
54
53
  readonly opts: SwitchThumbStateProps;
55
54
  readonly root: SwitchRootState;
56
55
  constructor(opts: SwitchThumbStateProps, root: SwitchRootState);
57
- snippetProps: {
56
+ readonly snippetProps: {
58
57
  checked: boolean;
59
58
  };
60
- props: {
59
+ readonly props: {
61
60
  readonly id: string;
62
- readonly "data-switch-thumb": "";
63
61
  readonly "data-disabled": "" | undefined;
64
62
  readonly "data-state": "checked" | "unchecked";
65
63
  readonly "data-required": "" | undefined;
@@ -1,9 +1,11 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
2
  import { Context } from "runed";
3
- import { getAriaChecked, getAriaRequired, getDataChecked, getDataDisabled, getDataRequired, getDisabled, } from "../../internal/attrs.js";
3
+ import { getAriaChecked, getAriaRequired, getDataChecked, getDataDisabled, getDataRequired, getDisabled, createBitsAttrs, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
- const SWITCH_ROOT_ATTR = "data-switch-root";
6
- const SWITCH_THUMB_ATTR = "data-switch-thumb";
5
+ const switchAttrs = createBitsAttrs({
6
+ component: "switch",
7
+ parts: ["root", "thumb"],
8
+ });
7
9
  class SwitchRootState {
8
10
  opts;
9
11
  constructor(opts) {
@@ -40,7 +42,7 @@ class SwitchRootState {
40
42
  disabled: getDisabled(this.opts.disabled.current),
41
43
  "aria-checked": getAriaChecked(this.opts.checked.current, false),
42
44
  "aria-required": getAriaRequired(this.opts.required.current),
43
- [SWITCH_ROOT_ATTR]: "",
45
+ [switchAttrs.root]: "",
44
46
  //
45
47
  onclick: this.onclick,
46
48
  onkeydown: this.onkeydown,
@@ -75,7 +77,7 @@ class SwitchThumbState {
75
77
  props = $derived.by(() => ({
76
78
  ...this.root.sharedProps,
77
79
  id: this.opts.id.current,
78
- [SWITCH_THUMB_ATTR]: "",
80
+ [switchAttrs.thumb]: "",
79
81
  ...attachRef(this.opts.ref),
80
82
  }));
81
83
  }
@@ -16,16 +16,15 @@ declare class TabsRootState {
16
16
  readonly opts: TabsRootStateProps;
17
17
  rovingFocusGroup: UseRovingFocusReturn;
18
18
  triggerIds: string[];
19
- valueToTriggerId: SvelteMap<string, string>;
20
- valueToContentId: SvelteMap<string, string>;
19
+ readonly valueToTriggerId: SvelteMap<string, string>;
20
+ readonly valueToContentId: SvelteMap<string, string>;
21
21
  constructor(opts: TabsRootStateProps);
22
22
  registerTrigger(id: string, value: string): () => void;
23
23
  registerContent(id: string, value: string): () => void;
24
24
  setValue(v: string): void;
25
- props: {
25
+ readonly props: {
26
26
  readonly id: string;
27
27
  readonly "data-orientation": "horizontal" | "vertical";
28
- readonly "data-tabs-root": "";
29
28
  };
30
29
  }
31
30
  type TabsListStateProps = WithRefProps;
@@ -34,12 +33,11 @@ declare class TabsListState {
34
33
  readonly opts: TabsListStateProps;
35
34
  readonly root: TabsRootState;
36
35
  constructor(opts: TabsListStateProps, root: TabsRootState);
37
- props: {
36
+ readonly props: {
38
37
  readonly id: string;
39
38
  readonly role: "tablist";
40
39
  readonly "aria-orientation": "horizontal" | "vertical";
41
40
  readonly "data-orientation": "horizontal" | "vertical";
42
- readonly "data-tabs-list": "";
43
41
  readonly "data-disabled": "" | undefined;
44
42
  };
45
43
  }
@@ -55,7 +53,7 @@ declare class TabsTriggerState {
55
53
  onfocus(_: BitsFocusEvent): void;
56
54
  onclick(_: BitsMouseEvent): void;
57
55
  onkeydown(e: BitsKeyboardEvent): void;
58
- props: {
56
+ readonly props: {
59
57
  readonly id: string;
60
58
  readonly role: "tab";
61
59
  readonly "data-state": "active" | "inactive";
@@ -64,7 +62,6 @@ declare class TabsTriggerState {
64
62
  readonly "data-disabled": "" | undefined;
65
63
  readonly "aria-selected": "true" | "false";
66
64
  readonly "aria-controls": string | undefined;
67
- readonly "data-tabs-trigger": "";
68
65
  readonly disabled: true | undefined;
69
66
  readonly tabindex: number;
70
67
  readonly onclick: (_: BitsMouseEvent) => void;
@@ -88,7 +85,6 @@ declare class TabsContentState {
88
85
  readonly "data-value": string;
89
86
  readonly "data-state": "active" | "inactive";
90
87
  readonly "aria-labelledby": string | undefined;
91
- readonly "data-tabs-content": "";
92
88
  };
93
89
  }
94
90
  export declare function useTabsRoot(props: TabsRootStateProps): TabsRootState;
@@ -1,13 +1,13 @@
1
1
  import { SvelteMap } from "svelte/reactivity";
2
2
  import { attachRef } from "svelte-toolbelt";
3
3
  import { Context, watch } from "runed";
4
- import { getAriaOrientation, getAriaSelected, getDataDisabled, getDataOrientation, getDisabled, getHidden, } from "../../internal/attrs.js";
4
+ import { createBitsAttrs, getAriaOrientation, getAriaSelected, getDataDisabled, getDataOrientation, getDisabled, getHidden, } from "../../internal/attrs.js";
5
5
  import { kbd } from "../../internal/kbd.js";
6
6
  import { useRovingFocus, } from "../../internal/use-roving-focus.svelte.js";
7
- const TABS_ROOT_ATTR = "data-tabs-root";
8
- const TABS_LIST_ATTR = "data-tabs-list";
9
- const TABS_TRIGGER_ATTR = "data-tabs-trigger";
10
- const TABS_CONTENT_ATTR = "data-tabs-content";
7
+ const tabsAttrs = createBitsAttrs({
8
+ component: "tabs",
9
+ parts: ["root", "list", "trigger", "content"],
10
+ });
11
11
  class TabsRootState {
12
12
  opts;
13
13
  rovingFocusGroup;
@@ -19,7 +19,7 @@ class TabsRootState {
19
19
  constructor(opts) {
20
20
  this.opts = opts;
21
21
  this.rovingFocusGroup = useRovingFocus({
22
- candidateAttr: TABS_TRIGGER_ATTR,
22
+ candidateAttr: tabsAttrs.trigger,
23
23
  rootNode: this.opts.ref,
24
24
  loop: this.opts.loop,
25
25
  orientation: this.opts.orientation,
@@ -47,7 +47,7 @@ class TabsRootState {
47
47
  props = $derived.by(() => ({
48
48
  id: this.opts.id.current,
49
49
  "data-orientation": getDataOrientation(this.opts.orientation.current),
50
- [TABS_ROOT_ATTR]: "",
50
+ [tabsAttrs.root]: "",
51
51
  ...attachRef(this.opts.ref),
52
52
  }));
53
53
  }
@@ -64,7 +64,7 @@ class TabsListState {
64
64
  role: "tablist",
65
65
  "aria-orientation": getAriaOrientation(this.root.opts.orientation.current),
66
66
  "data-orientation": getDataOrientation(this.root.opts.orientation.current),
67
- [TABS_LIST_ATTR]: "",
67
+ [tabsAttrs.list]: "",
68
68
  "data-disabled": getDataDisabled(this.#isDisabled),
69
69
  ...attachRef(this.opts.ref),
70
70
  }));
@@ -72,9 +72,9 @@ class TabsListState {
72
72
  class TabsTriggerState {
73
73
  opts;
74
74
  root;
75
+ #tabIndex = $state(0);
75
76
  #isActive = $derived.by(() => this.root.opts.value.current === this.opts.value.current);
76
77
  #isDisabled = $derived.by(() => this.opts.disabled.current || this.root.opts.disabled.current);
77
- #tabIndex = $state(0);
78
78
  #ariaControls = $derived.by(() => this.root.valueToContentId.get(this.opts.value.current));
79
79
  constructor(opts, root) {
80
80
  this.opts = opts;
@@ -129,7 +129,7 @@ class TabsTriggerState {
129
129
  "data-disabled": getDataDisabled(this.#isDisabled),
130
130
  "aria-selected": getAriaSelected(this.#isActive),
131
131
  "aria-controls": this.#ariaControls,
132
- [TABS_TRIGGER_ATTR]: "",
132
+ [tabsAttrs.trigger]: "",
133
133
  disabled: getDisabled(this.#isDisabled),
134
134
  tabindex: this.#tabIndex,
135
135
  //
@@ -159,7 +159,7 @@ class TabsContentState {
159
159
  "data-value": this.opts.value.current,
160
160
  "data-state": getTabDataState(this.#isActive),
161
161
  "aria-labelledby": this.#ariaLabelledBy,
162
- [TABS_CONTENT_ATTR]: "",
162
+ [tabsAttrs.content]: "",
163
163
  ...attachRef(this.opts.ref),
164
164
  }));
165
165
  }
@@ -5,19 +5,20 @@
5
5
  </script>
6
6
 
7
7
  <script lang="ts" generics="T extends TimeValue = Time">
8
+ import { watch } from "runed";
8
9
  import { box } from "svelte-toolbelt";
9
10
  import { useTimeFieldRoot } from "../time-field.svelte.js";
10
11
  import type { TimeFieldRootProps } from "../types.js";
11
12
  import { noop } from "../../../internal/noop.js";
12
13
  import { getDefaultTime } from "../../../internal/date-time/utils.js";
13
- import { watch } from "runed";
14
+ import { resolveLocaleProp } from "../../utilities/config/prop-resolvers.js";
14
15
 
15
16
  let {
16
17
  disabled = false,
17
18
  granularity,
18
19
  hideTimeZone = false,
19
20
  hourCycle,
20
- locale = "en",
21
+ locale,
21
22
  maxValue,
22
23
  minValue,
23
24
  onPlaceholderChange = noop,
@@ -78,7 +79,7 @@
78
79
  granularity: box.with(() => granularity),
79
80
  hideTimeZone: box.with(() => hideTimeZone),
80
81
  hourCycle: box.with(() => hourCycle),
81
- locale: box.with(() => locale),
82
+ locale: resolveLocaleProp(() => locale),
82
83
  maxValue: box.with(() => maxValue),
83
84
  minValue: box.with(() => minValue),
84
85
  validate: box.with(() => validate),
@@ -8,7 +8,7 @@ import { type TimeFormatter } from "../../internal/date-time/formatter.js";
8
8
  import { type Announcer } from "../../internal/date-time/announcer.js";
9
9
  import type { TimeValue } from "../../shared/date/types.js";
10
10
  import type { TimeRangeFieldRootState } from "../time-range-field/time-range-field.svelte.js";
11
- export declare const TIME_FIELD_INPUT_ATTR = "data-time-field-input";
11
+ export declare const timeFieldAttrs: import("../../internal/attrs.js").BitsAttrs<readonly ["input", "label"]>;
12
12
  type SegmentConfig = {
13
13
  min: number | ((root: TimeFieldRootState) => number);
14
14
  max: number | ((root: TimeFieldRootState) => number);
@@ -160,7 +160,6 @@ export declare class TimeFieldInputState {
160
160
  readonly "aria-disabled": "true" | "false";
161
161
  readonly "data-invalid": "" | undefined;
162
162
  readonly "data-disabled": "" | undefined;
163
- readonly "data-time-field-input": "";
164
163
  };
165
164
  }
166
165
  declare class TimeFieldHiddenInputState {
@@ -184,7 +183,6 @@ declare class TimeFieldLabelState {
184
183
  readonly id: string;
185
184
  readonly "data-invalid": "" | undefined;
186
185
  readonly "data-disabled": "" | undefined;
187
- readonly "data-time-field-label": "";
188
186
  readonly onclick: (_: BitsMouseEvent) => void;
189
187
  };
190
188
  }
@@ -2,7 +2,7 @@ import { CalendarDateTime, Time, ZonedDateTime } from "@internationalized/date";
2
2
  import { onDestroyEffect, attachRef, box, DOMContext } from "svelte-toolbelt";
3
3
  import { onMount, untrack } from "svelte";
4
4
  import { Context, watch } from "runed";
5
- import { getAriaDisabled, getAriaHidden, getAriaInvalid, getAriaReadonly, getDataDisabled, getDataInvalid, getDataReadonly, } from "../../internal/attrs.js";
5
+ import { createBitsAttrs, getAriaDisabled, getAriaHidden, getAriaInvalid, getAriaReadonly, getDataDisabled, getDataInvalid, getDataReadonly, } from "../../internal/attrs.js";
6
6
  import { isBrowser, isNumberString } from "../../internal/is.js";
7
7
  import { kbd } from "../../internal/kbd.js";
8
8
  import { useId } from "../../internal/use-id.js";
@@ -13,8 +13,10 @@ import { toDate } from "../../internal/date-time/utils.js";
13
13
  import { areAllTimeSegmentsFilled, convertTimeValueToTime, createTimeContent, getISOTimeValue, getTimeValueFromSegments, initTimeSegmentStates, isFirstTimeSegment, isTimeBefore, removeTimeDescriptionElement, setTimeDescription, } from "../../internal/date-time/field/time-helpers.js";
14
14
  import { getFirstTimeSegment, handleTimeSegmentNavigation, isSegmentNavigationKey, moveToNextTimeSegment, moveToPrevTimeSegment, } from "../../internal/date-time/field/segments.js";
15
15
  import { getDefaultHourCycle, isAcceptableSegmentKey, } from "../../internal/date-time/field/helpers.js";
16
- export const TIME_FIELD_INPUT_ATTR = "data-time-field-input";
17
- const TIME_FIELD_LABEL_ATTR = "data-time-field-label";
16
+ export const timeFieldAttrs = createBitsAttrs({
17
+ component: "time-field",
18
+ parts: ["input", "label"],
19
+ });
18
20
  const SEGMENT_CONFIGS = {
19
21
  hour: {
20
22
  min: (root) => (root.hourCycle === 12 ? 1 : 0),
@@ -478,7 +480,7 @@ export class TimeFieldInputState {
478
480
  "aria-disabled": getAriaDisabled(this.root.disabled.current),
479
481
  "data-invalid": this.root.isInvalid ? "" : undefined,
480
482
  "data-disabled": getDataDisabled(this.root.disabled.current),
481
- [TIME_FIELD_INPUT_ATTR]: "",
483
+ [timeFieldAttrs.input]: "",
482
484
  ...attachRef(this.opts.ref, (v) => this.root.setFieldNode(v)),
483
485
  }));
484
486
  }
@@ -515,7 +517,7 @@ class TimeFieldLabelState {
515
517
  id: this.opts.id.current,
516
518
  "data-invalid": getDataInvalid(this.root.isInvalid),
517
519
  "data-disabled": getDataDisabled(this.root.disabled.current),
518
- [TIME_FIELD_LABEL_ATTR]: "",
520
+ [timeFieldAttrs.label]: "",
519
521
  onclick: this.onclick,
520
522
  ...attachRef(this.opts.ref, (v) => this.root.setLabelNode(v)),
521
523
  }));
@@ -6,13 +6,14 @@
6
6
  </script>
7
7
 
8
8
  <script lang="ts" generics="T extends TimeValue = Time">
9
+ import { watch } from "runed";
9
10
  import { box, mergeProps } from "svelte-toolbelt";
10
11
  import { useTimeRangeFieldRoot } from "../time-range-field.svelte.js";
11
12
  import type { TimeRangeFieldRootProps } from "../types.js";
12
13
  import { createId } from "../../../internal/create-id.js";
13
14
  import { noop } from "../../../internal/noop.js";
14
15
  import { getDefaultTime } from "../../../internal/date-time/utils.js";
15
- import { watch } from "runed";
16
+ import { resolveLocaleProp } from "../../utilities/config/prop-resolvers.js";
16
17
 
17
18
  const uid = $props.id();
18
19
 
@@ -28,7 +29,7 @@
28
29
  required = false,
29
30
  hourCycle,
30
31
  granularity,
31
- locale = "en-US",
32
+ locale,
32
33
  hideTimeZone = false,
33
34
  validate = noop,
34
35
  onInvalid = noop,
@@ -94,7 +95,7 @@
94
95
  required: box.with(() => required),
95
96
  hourCycle: box.with(() => hourCycle),
96
97
  granularity: box.with(() => granularity),
97
- locale: box.with(() => locale),
98
+ locale: resolveLocaleProp(() => locale),
98
99
  hideTimeZone: box.with(() => hideTimeZone),
99
100
  validate: box.with(() => validate),
100
101
  maxValue: box.with(() => maxValue),
@@ -8,7 +8,7 @@ import type { TimeSegmentPart } from "../../shared/index.js";
8
8
  import type { WithRefProps } from "../../internal/types.js";
9
9
  import type { TimeGranularity, TimeOnInvalid, TimeRange, TimeRangeValidator, TimeValue } from "../../shared/date/types.js";
10
10
  import { type TimeFormatter } from "../../internal/date-time/formatter.js";
11
- export declare const TIME_RANGE_FIELD_ROOT_ATTR = "data-time-range-field-root";
11
+ export declare const timeRangeFieldAttrs: import("../../internal/attrs.js").BitsAttrs<readonly ["root", "label"]>;
12
12
  type TimeRangeFieldRootStateProps<T extends TimeValue = Time> = WithRefProps<WritableBoxedValues<{
13
13
  value: TimeRange<T>;
14
14
  placeholder: TimeValue;
@@ -62,7 +62,6 @@ export declare class TimeRangeFieldRootState<T extends TimeValue = Time> {
62
62
  props: {
63
63
  readonly id: string;
64
64
  readonly role: "group";
65
- readonly "data-time-range-field-root": "";
66
65
  readonly "data-invalid": "" | undefined;
67
66
  };
68
67
  }
@@ -76,7 +75,6 @@ declare class TimeRangeFieldLabelState {
76
75
  readonly id: string;
77
76
  readonly "data-invalid": "" | undefined;
78
77
  readonly "data-disabled": "" | undefined;
79
- readonly "data-time-range-field-label": "";
80
78
  readonly onclick: () => void;
81
79
  };
82
80
  }
@@ -2,13 +2,15 @@ import { box, onDestroyEffect, attachRef, DOMContext } from "svelte-toolbelt";
2
2
  import { Context, watch } from "runed";
3
3
  import { TimeFieldInputState, useTimeFieldRoot } from "../time-field/time-field.svelte.js";
4
4
  import { useId } from "../../internal/use-id.js";
5
- import { getDataDisabled, getDataInvalid } from "../../internal/attrs.js";
5
+ import { createBitsAttrs, getDataDisabled, getDataInvalid } from "../../internal/attrs.js";
6
6
  import { createTimeFormatter } from "../../internal/date-time/formatter.js";
7
7
  import { removeDescriptionElement } from "../../internal/date-time/field/helpers.js";
8
8
  import { getFirstSegment } from "../../internal/date-time/field/segments.js";
9
9
  import { convertTimeValueToTime, isTimeBefore, } from "../../internal/date-time/field/time-helpers.js";
10
- export const TIME_RANGE_FIELD_ROOT_ATTR = "data-time-range-field-root";
11
- const TIME_RANGE_FIELD_LABEL_ATTR = "data-time-range-field-label";
10
+ export const timeRangeFieldAttrs = createBitsAttrs({
11
+ component: "time-range-field",
12
+ parts: ["root", "label"],
13
+ });
12
14
  export class TimeRangeFieldRootState {
13
15
  opts;
14
16
  startFieldState = undefined;
@@ -151,7 +153,7 @@ export class TimeRangeFieldRootState {
151
153
  props = $derived.by(() => ({
152
154
  id: this.opts.id.current,
153
155
  role: "group",
154
- [TIME_RANGE_FIELD_ROOT_ATTR]: "",
156
+ [timeRangeFieldAttrs.root]: "",
155
157
  "data-invalid": getDataInvalid(this.isInvalid),
156
158
  ...attachRef(this.opts.ref, (v) => (this.fieldNode = v)),
157
159
  }));
@@ -176,7 +178,7 @@ class TimeRangeFieldLabelState {
176
178
  // TODO: invalid state for field
177
179
  "data-invalid": getDataInvalid(this.root.isInvalid),
178
180
  "data-disabled": getDataDisabled(this.root.opts.disabled.current),
179
- [TIME_RANGE_FIELD_LABEL_ATTR]: "",
181
+ [timeRangeFieldAttrs.label]: "",
180
182
  onclick: this.#onclick,
181
183
  ...attachRef(this.opts.ref, (v) => (this.root.labelNode = v)),
182
184
  }));
@@ -1,5 +1,6 @@
1
1
  import type { ReadableBoxedValues, WritableBoxedValues } from "../../internal/box.svelte.js";
2
2
  import type { BitsMouseEvent, WithRefProps } from "../../internal/types.js";
3
+ export declare const toggleAttrs: import("../../internal/attrs.js").BitsAttrs<readonly ["root"]>;
3
4
  type ToggleRootStateProps = WithRefProps<ReadableBoxedValues<{
4
5
  disabled: boolean;
5
6
  }> & WritableBoxedValues<{
@@ -10,11 +11,10 @@ declare class ToggleRootState {
10
11
  readonly opts: ToggleRootStateProps;
11
12
  constructor(opts: ToggleRootStateProps);
12
13
  onclick(_: BitsMouseEvent): void;
13
- snippetProps: {
14
+ readonly snippetProps: {
14
15
  pressed: boolean;
15
16
  };
16
- props: {
17
- readonly "data-toggle-root": "";
17
+ readonly props: {
18
18
  readonly id: string;
19
19
  readonly "data-disabled": "" | undefined;
20
20
  readonly "aria-pressed": "true" | "false";
@@ -1,6 +1,9 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
- import { getAriaPressed, getDataDisabled, getDisabled } from "../../internal/attrs.js";
3
- const TOGGLE_ROOT_ATTR = "data-toggle-root";
2
+ import { createBitsAttrs, getAriaPressed, getDataDisabled, getDisabled, } from "../../internal/attrs.js";
3
+ export const toggleAttrs = createBitsAttrs({
4
+ component: "toggle",
5
+ parts: ["root"],
6
+ });
4
7
  class ToggleRootState {
5
8
  opts;
6
9
  constructor(opts) {
@@ -21,7 +24,7 @@ class ToggleRootState {
21
24
  pressed: this.opts.pressed.current,
22
25
  }));
23
26
  props = $derived.by(() => ({
24
- [TOGGLE_ROOT_ATTR]: "",
27
+ [toggleAttrs.root]: "",
25
28
  id: this.opts.id.current,
26
29
  "data-disabled": getDataDisabled(this.opts.disabled.current),
27
30
  "aria-pressed": getAriaPressed(this.opts.pressed.current),
@@ -3,6 +3,7 @@ import type { ReadableBoxedValues, WritableBoxedValues } from "../../internal/bo
3
3
  import type { Orientation } from "../../shared/index.js";
4
4
  import { type UseRovingFocusReturn } from "../../internal/use-roving-focus.svelte.js";
5
5
  import type { BitsKeyboardEvent, BitsMouseEvent, WithRefProps } from "../../internal/types.js";
6
+ export declare const toggleGroupAttrs: import("../../internal/attrs.js").BitsAttrs<readonly ["root", "item"]>;
6
7
  type ToggleGroupBaseStateProps = WithRefProps<ReadableBoxedValues<{
7
8
  disabled: boolean;
8
9
  rovingFocus: boolean;
@@ -15,7 +16,6 @@ declare class ToggleGroupBaseState {
15
16
  constructor(opts: ToggleGroupBaseStateProps);
16
17
  props: {
17
18
  readonly id: string;
18
- readonly "data-toggle-group-root": "";
19
19
  readonly role: "group";
20
20
  readonly "data-orientation": "horizontal" | "vertical";
21
21
  readonly "data-disabled": "" | undefined;
@@ -70,7 +70,6 @@ declare class ToggleGroupItemState {
70
70
  readonly "aria-pressed": "true" | "false" | undefined;
71
71
  readonly "aria-checked": "true" | "false" | "mixed" | undefined;
72
72
  readonly disabled: true | undefined;
73
- readonly "data-toggle-group-item": "";
74
73
  readonly onclick: (_: BitsMouseEvent) => void;
75
74
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
76
75
  };
@@ -1,17 +1,19 @@
1
1
  import { attachRef } from "svelte-toolbelt";
2
2
  import { Context } from "runed";
3
- import { getAriaChecked, getAriaPressed, getDataDisabled, getDataOrientation, getDisabled, } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, getAriaChecked, getAriaPressed, getDataDisabled, getDataOrientation, getDisabled, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
5
  import { useRovingFocus, } from "../../internal/use-roving-focus.svelte.js";
6
- const TOGGLE_GROUP_ROOT_ATTR = "data-toggle-group-root";
7
- const TOGGLE_GROUP_ITEM_ATTR = "data-toggle-group-item";
6
+ export const toggleGroupAttrs = createBitsAttrs({
7
+ component: "toggle-group",
8
+ parts: ["root", "item"],
9
+ });
8
10
  class ToggleGroupBaseState {
9
11
  opts;
10
12
  rovingFocusGroup;
11
13
  constructor(opts) {
12
14
  this.opts = opts;
13
15
  this.rovingFocusGroup = useRovingFocus({
14
- candidateAttr: TOGGLE_GROUP_ITEM_ATTR,
16
+ candidateAttr: toggleGroupAttrs.item,
15
17
  rootNode: opts.ref,
16
18
  loop: opts.loop,
17
19
  orientation: opts.orientation,
@@ -19,7 +21,7 @@ class ToggleGroupBaseState {
19
21
  }
20
22
  props = $derived.by(() => ({
21
23
  id: this.opts.id.current,
22
- [TOGGLE_GROUP_ROOT_ATTR]: "",
24
+ [toggleGroupAttrs.root]: "",
23
25
  role: "group",
24
26
  "data-orientation": getDataOrientation(this.opts.orientation.current),
25
27
  "data-disabled": getDataDisabled(this.opts.disabled.current),
@@ -130,7 +132,7 @@ class ToggleGroupItemState {
130
132
  "aria-pressed": this.#ariaPressed,
131
133
  "aria-checked": this.#ariaChecked,
132
134
  disabled: getDisabled(this.#isDisabled),
133
- [TOGGLE_GROUP_ITEM_ATTR]: "",
135
+ [toggleGroupAttrs.item]: "",
134
136
  //
135
137
  onclick: this.onclick,
136
138
  onkeydown: this.onkeydown,