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
@@ -5,7 +5,7 @@ import type { ReadableBoxedValues, WritableBoxedValues } from "../../internal/bo
5
5
  import type { BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, WithRefProps } from "../../internal/types.js";
6
6
  import { type Announcer } from "../../internal/date-time/announcer.js";
7
7
  import { type Formatter } from "../../internal/date-time/formatter.js";
8
- import { type CalendarParts } from "../../internal/date-time/calendar-helpers.svelte.js";
8
+ import { calendarAttrs } from "../../internal/date-time/calendar-helpers.svelte.js";
9
9
  import type { WeekStartsOn } from "../../shared/date/types.js";
10
10
  type RangeCalendarRootStateProps = WithRefProps<WritableBoxedValues<{
11
11
  value: DateRange;
@@ -39,16 +39,14 @@ type RangeCalendarRootStateProps = WithRefProps<WritableBoxedValues<{
39
39
  export declare class RangeCalendarRootState {
40
40
  #private;
41
41
  readonly opts: RangeCalendarRootStateProps;
42
+ readonly visibleMonths: DateValue[];
42
43
  months: Month<DateValue>[];
43
- visibleMonths: DateValue[];
44
44
  announcer: Announcer;
45
45
  formatter: Formatter;
46
46
  accessibleHeadingId: string;
47
47
  focusedValue: DateValue | undefined;
48
48
  lastPressedDateValue: DateValue | undefined;
49
49
  domContext: DOMContext;
50
- constructor(opts: RangeCalendarRootStateProps);
51
- setMonths: (months: Month<DateValue>[]) => void;
52
50
  /**
53
51
  * This derived state holds an array of localized day names for the current
54
52
  * locale and calendar view. It dynamically syncs with the 'weekStartsOn' option,
@@ -56,24 +54,26 @@ export declare class RangeCalendarRootState {
56
54
  * calendar's days of the week is strongly recommended, as it guarantees that
57
55
  * the days are correctly formatted for the current locale and calendar view.
58
56
  */
59
- weekdays: string[];
57
+ readonly weekdays: string[];
58
+ readonly isStartInvalid: boolean;
59
+ readonly isEndInvalid: boolean;
60
+ readonly isInvalid: boolean;
61
+ readonly isNextButtonDisabled: boolean;
62
+ readonly isPrevButtonDisabled: boolean;
63
+ readonly headingValue: string;
64
+ readonly fullCalendarLabel: string;
65
+ readonly highlightedRange: {
66
+ start: DateValue;
67
+ end: DateValue;
68
+ } | null;
69
+ constructor(opts: RangeCalendarRootStateProps);
70
+ setMonths: (months: Month<DateValue>[]) => void;
60
71
  isOutsideVisibleMonths(date: DateValue): boolean;
61
72
  isDateDisabled(date: DateValue): boolean;
62
73
  isDateUnavailable(date: DateValue): boolean;
63
- isStartInvalid: boolean;
64
- isEndInvalid: boolean;
65
- isInvalid: boolean;
66
- isNextButtonDisabled: boolean;
67
- isPrevButtonDisabled: boolean;
68
- headingValue: string;
69
- fullCalendarLabel: string;
70
74
  isSelectionStart(date: DateValue): boolean;
71
75
  isSelectionEnd(date: DateValue): boolean;
72
76
  isSelected(date: DateValue): boolean;
73
- highlightedRange: {
74
- start: DateValue;
75
- end: DateValue;
76
- } | null;
77
77
  shiftFocus(node: HTMLElement, add: number): void;
78
78
  handleCellClick(e: Event, date: DateValue): void;
79
79
  onkeydown(event: BitsKeyboardEvent): void;
@@ -89,12 +89,12 @@ export declare class RangeCalendarRootState {
89
89
  prevYear(): void;
90
90
  setYear(year: number): void;
91
91
  setMonth(month: number): void;
92
- getBitsAttr(part: CalendarParts): string;
93
- snippetProps: {
92
+ getBitsAttr: (typeof calendarAttrs)["getAttr"];
93
+ readonly snippetProps: {
94
94
  months: Month<DateValue>[];
95
95
  weekdays: string[];
96
96
  };
97
- props: {
97
+ readonly props: {
98
98
  readonly onkeydown: (event: BitsKeyboardEvent) => void;
99
99
  readonly id: string;
100
100
  readonly role: "application";
@@ -111,26 +111,26 @@ type RangeCalendarCellStateProps = WithRefProps<ReadableBoxedValues<{
111
111
  export declare class RangeCalendarCellState {
112
112
  readonly opts: RangeCalendarCellStateProps;
113
113
  readonly root: RangeCalendarRootState;
114
- cellDate: Date;
115
- isDisabled: boolean;
116
- isUnavailable: boolean;
117
- isDateToday: boolean;
118
- isOutsideMonth: boolean;
119
- isOutsideVisibleMonths: boolean;
120
- isFocusedDate: boolean;
121
- isSelectedDate: boolean;
122
- isSelectionStart: boolean;
123
- isSelectionEnd: boolean;
124
- isHighlighted: boolean;
125
- labelText: string;
114
+ readonly cellDate: Date;
115
+ readonly isDisabled: boolean;
116
+ readonly isUnavailable: boolean;
117
+ readonly isDateToday: boolean;
118
+ readonly isOutsideMonth: boolean;
119
+ readonly isOutsideVisibleMonths: boolean;
120
+ readonly isFocusedDate: boolean;
121
+ readonly isSelectedDate: boolean;
122
+ readonly isSelectionStart: boolean;
123
+ readonly isSelectionEnd: boolean;
124
+ readonly isHighlighted: boolean;
125
+ readonly labelText: string;
126
126
  constructor(opts: RangeCalendarCellStateProps, root: RangeCalendarRootState);
127
- snippetProps: {
127
+ readonly snippetProps: {
128
128
  disabled: boolean;
129
129
  unavailable: boolean;
130
130
  selected: boolean;
131
131
  };
132
- ariaDisabled: boolean;
133
- sharedDataAttrs: {
132
+ readonly ariaDisabled: boolean;
133
+ readonly sharedDataAttrs: {
134
134
  readonly "data-unavailable": "" | undefined;
135
135
  readonly "data-today": "" | undefined;
136
136
  readonly "data-outside-month": "" | undefined;
@@ -144,7 +144,7 @@ export declare class RangeCalendarCellState {
144
144
  readonly "data-type": string;
145
145
  readonly "data-disabled": "" | undefined;
146
146
  };
147
- props: {
147
+ readonly props: {
148
148
  readonly "data-unavailable": "" | undefined;
149
149
  readonly "data-today": "" | undefined;
150
150
  readonly "data-outside-month": "" | undefined;
@@ -172,14 +172,14 @@ declare class RangeCalendarDayState {
172
172
  onclick(e: BitsMouseEvent): void;
173
173
  onmouseenter(_: BitsMouseEvent): void;
174
174
  onfocusin(_: BitsFocusEvent): void;
175
- snippetProps: {
175
+ readonly snippetProps: {
176
176
  disabled: boolean;
177
177
  unavailable: boolean;
178
178
  selected: boolean;
179
179
  day: string;
180
180
  };
181
- props: {
182
- readonly tabindex: number | undefined;
181
+ readonly props: {
182
+ readonly tabindex: 0 | -1 | undefined;
183
183
  readonly "data-bits-day": "";
184
184
  readonly onclick: (e: BitsMouseEvent) => void;
185
185
  readonly onmouseenter: (_: BitsMouseEvent) => void;
@@ -6,19 +6,93 @@ import { useId } from "../../internal/use-id.js";
6
6
  import { getAriaDisabled, getAriaSelected, getDataDisabled, getDataSelected, getDataUnavailable, } from "../../internal/attrs.js";
7
7
  import { getAnnouncer } from "../../internal/date-time/announcer.js";
8
8
  import { createFormatter } from "../../internal/date-time/formatter.js";
9
- import { createMonths, getCalendarElementProps, getCalendarHeadingValue, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
9
+ import { calendarAttrs, createMonths, getCalendarElementProps, getCalendarHeadingValue, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
10
10
  import { areAllDaysBetweenValid, getDateValueType, isAfter, isBefore, isBetweenInclusive, toDate, } from "../../internal/date-time/utils.js";
11
11
  import { onMount } from "svelte";
12
12
  export class RangeCalendarRootState {
13
13
  opts;
14
- months = $state([]);
15
14
  visibleMonths = $derived.by(() => this.months.map((month) => month.value));
15
+ months = $state([]);
16
16
  announcer;
17
17
  formatter;
18
18
  accessibleHeadingId = useId();
19
19
  focusedValue = $state(undefined);
20
20
  lastPressedDateValue = undefined;
21
21
  domContext;
22
+ /**
23
+ * This derived state holds an array of localized day names for the current
24
+ * locale and calendar view. It dynamically syncs with the 'weekStartsOn' option,
25
+ * updating its content when the option changes. Using this state to render the
26
+ * calendar's days of the week is strongly recommended, as it guarantees that
27
+ * the days are correctly formatted for the current locale and calendar view.
28
+ */
29
+ weekdays = $derived.by(() => {
30
+ return getWeekdays({
31
+ months: this.months,
32
+ formatter: this.formatter,
33
+ weekdayFormat: this.opts.weekdayFormat.current,
34
+ });
35
+ });
36
+ isStartInvalid = $derived.by(() => {
37
+ if (!this.opts.startValue.current)
38
+ return false;
39
+ return (this.isDateUnavailable(this.opts.startValue.current) ||
40
+ this.isDateDisabled(this.opts.startValue.current));
41
+ });
42
+ isEndInvalid = $derived.by(() => {
43
+ if (!this.opts.endValue.current)
44
+ return false;
45
+ return (this.isDateUnavailable(this.opts.endValue.current) ||
46
+ this.isDateDisabled(this.opts.endValue.current));
47
+ });
48
+ isInvalid = $derived.by(() => {
49
+ if (this.isStartInvalid || this.isEndInvalid)
50
+ return true;
51
+ if (this.opts.endValue.current &&
52
+ this.opts.startValue.current &&
53
+ isBefore(this.opts.endValue.current, this.opts.startValue.current))
54
+ return true;
55
+ return false;
56
+ });
57
+ isNextButtonDisabled = $derived.by(() => {
58
+ return getIsNextButtonDisabled({
59
+ maxValue: this.opts.maxValue.current,
60
+ months: this.months,
61
+ disabled: this.opts.disabled.current,
62
+ });
63
+ });
64
+ isPrevButtonDisabled = $derived.by(() => {
65
+ return getIsPrevButtonDisabled({
66
+ minValue: this.opts.minValue.current,
67
+ months: this.months,
68
+ disabled: this.opts.disabled.current,
69
+ });
70
+ });
71
+ headingValue = $derived.by(() => {
72
+ return getCalendarHeadingValue({
73
+ months: this.months,
74
+ formatter: this.formatter,
75
+ locale: this.opts.locale.current,
76
+ });
77
+ });
78
+ fullCalendarLabel = $derived.by(() => `${this.opts.calendarLabel.current} ${this.headingValue}`);
79
+ highlightedRange = $derived.by(() => {
80
+ if (this.opts.startValue.current && this.opts.endValue.current)
81
+ return null;
82
+ if (!this.opts.startValue.current || !this.focusedValue)
83
+ return null;
84
+ const isStartBeforeFocused = isBefore(this.opts.startValue.current, this.focusedValue);
85
+ const start = isStartBeforeFocused ? this.opts.startValue.current : this.focusedValue;
86
+ const end = isStartBeforeFocused ? this.focusedValue : this.opts.startValue.current;
87
+ const range = { start, end };
88
+ if (isSameDay(start.add({ days: 1 }), end) || isSameDay(start, end)) {
89
+ return range;
90
+ }
91
+ const isValid = areAllDaysBetweenValid(start, end, this.isDateUnavailable, this.isDateDisabled);
92
+ if (isValid)
93
+ return range;
94
+ return null;
95
+ });
22
96
  constructor(opts) {
23
97
  this.opts = opts;
24
98
  this.domContext = new DOMContext(opts.ref);
@@ -173,20 +247,6 @@ export class RangeCalendarRootState {
173
247
  setMonths = (months) => {
174
248
  this.months = months;
175
249
  };
176
- /**
177
- * This derived state holds an array of localized day names for the current
178
- * locale and calendar view. It dynamically syncs with the 'weekStartsOn' option,
179
- * updating its content when the option changes. Using this state to render the
180
- * calendar's days of the week is strongly recommended, as it guarantees that
181
- * the days are correctly formatted for the current locale and calendar view.
182
- */
183
- weekdays = $derived.by(() => {
184
- return getWeekdays({
185
- months: this.months,
186
- formatter: this.formatter,
187
- weekdayFormat: this.opts.weekdayFormat.current,
188
- });
189
- });
190
250
  isOutsideVisibleMonths(date) {
191
251
  return !this.visibleMonths.some((month) => isSameMonth(date, month));
192
252
  }
@@ -206,49 +266,6 @@ export class RangeCalendarRootState {
206
266
  return true;
207
267
  return false;
208
268
  }
209
- isStartInvalid = $derived.by(() => {
210
- if (!this.opts.startValue.current)
211
- return false;
212
- return (this.isDateUnavailable(this.opts.startValue.current) ||
213
- this.isDateDisabled(this.opts.startValue.current));
214
- });
215
- isEndInvalid = $derived.by(() => {
216
- if (!this.opts.endValue.current)
217
- return false;
218
- return (this.isDateUnavailable(this.opts.endValue.current) ||
219
- this.isDateDisabled(this.opts.endValue.current));
220
- });
221
- isInvalid = $derived.by(() => {
222
- if (this.isStartInvalid || this.isEndInvalid)
223
- return true;
224
- if (this.opts.endValue.current &&
225
- this.opts.startValue.current &&
226
- isBefore(this.opts.endValue.current, this.opts.startValue.current))
227
- return true;
228
- return false;
229
- });
230
- isNextButtonDisabled = $derived.by(() => {
231
- return getIsNextButtonDisabled({
232
- maxValue: this.opts.maxValue.current,
233
- months: this.months,
234
- disabled: this.opts.disabled.current,
235
- });
236
- });
237
- isPrevButtonDisabled = $derived.by(() => {
238
- return getIsPrevButtonDisabled({
239
- minValue: this.opts.minValue.current,
240
- months: this.months,
241
- disabled: this.opts.disabled.current,
242
- });
243
- });
244
- headingValue = $derived.by(() => {
245
- return getCalendarHeadingValue({
246
- months: this.months,
247
- formatter: this.formatter,
248
- locale: this.opts.locale.current,
249
- });
250
- });
251
- fullCalendarLabel = $derived.by(() => `${this.opts.calendarLabel.current} ${this.headingValue}`);
252
269
  isSelectionStart(date) {
253
270
  if (!this.opts.startValue.current)
254
271
  return false;
@@ -269,23 +286,6 @@ export class RangeCalendarRootState {
269
286
  }
270
287
  return false;
271
288
  }
272
- highlightedRange = $derived.by(() => {
273
- if (this.opts.startValue.current && this.opts.endValue.current)
274
- return null;
275
- if (!this.opts.startValue.current || !this.focusedValue)
276
- return null;
277
- const isStartBeforeFocused = isBefore(this.opts.startValue.current, this.focusedValue);
278
- const start = isStartBeforeFocused ? this.opts.startValue.current : this.focusedValue;
279
- const end = isStartBeforeFocused ? this.focusedValue : this.opts.startValue.current;
280
- const range = { start, end };
281
- if (isSameDay(start.add({ days: 1 }), end) || isSameDay(start, end)) {
282
- return range;
283
- }
284
- const isValid = areAllDaysBetweenValid(start, end, this.isDateUnavailable, this.isDateDisabled);
285
- if (isValid)
286
- return range;
287
- return null;
288
- });
289
289
  shiftFocus(node, add) {
290
290
  return shiftCalendarFocus({
291
291
  node,
@@ -403,9 +403,9 @@ export class RangeCalendarRootState {
403
403
  setMonth(month) {
404
404
  this.opts.placeholder.current = this.opts.placeholder.current.set({ month });
405
405
  }
406
- getBitsAttr(part) {
407
- return `data-range-calendar-${part}`;
408
- }
406
+ getBitsAttr = (part) => {
407
+ return calendarAttrs.getAttr(part, "range-calendar");
408
+ };
409
409
  snippetProps = $derived.by(() => ({
410
410
  months: this.months,
411
411
  weekdays: this.weekdays,
@@ -65,7 +65,6 @@ declare class RatingGroupRootState {
65
65
  readonly "data-readonly": "" | undefined;
66
66
  readonly "data-orientation": Orientation;
67
67
  readonly tabindex: 0 | -1;
68
- readonly "data-rating-group-root": "";
69
68
  readonly onkeydown: (e: BitsKeyboardEvent) => void;
70
69
  readonly onpointerleave: () => void;
71
70
  };
@@ -92,7 +91,6 @@ declare class RatingGroupItemState {
92
91
  readonly "data-disabled": "" | undefined;
93
92
  readonly "data-readonly": "" | undefined;
94
93
  readonly "data-state": RatingGroupItemStateType;
95
- readonly "data-rating-group-item": "";
96
94
  readonly onclick: (e: BitsMouseEvent) => void;
97
95
  readonly onpointermove: (e: BitsPointerEvent) => void;
98
96
  };
@@ -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
  }