@salt-ds/lab 1.0.0-alpha.55 → 1.0.0-alpha.57

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 (188) hide show
  1. package/CHANGELOG.md +167 -0
  2. package/css/salt-lab.css +44 -7
  3. package/dist-cjs/calendar/Calendar.js +12 -12
  4. package/dist-cjs/calendar/Calendar.js.map +1 -1
  5. package/dist-cjs/calendar/CalendarGrid.css.js +6 -0
  6. package/dist-cjs/calendar/CalendarGrid.css.js.map +1 -0
  7. package/dist-cjs/calendar/CalendarGrid.js +107 -0
  8. package/dist-cjs/calendar/CalendarGrid.js.map +1 -0
  9. package/dist-cjs/calendar/CalendarNavigation.js +219 -201
  10. package/dist-cjs/calendar/CalendarNavigation.js.map +1 -1
  11. package/dist-cjs/calendar/CalendarWeekHeader.js +10 -4
  12. package/dist-cjs/calendar/CalendarWeekHeader.js.map +1 -1
  13. package/dist-cjs/calendar/internal/CalendarContext.js +6 -2
  14. package/dist-cjs/calendar/internal/CalendarContext.js.map +1 -1
  15. package/dist-cjs/calendar/internal/CalendarDay.js +6 -9
  16. package/dist-cjs/calendar/internal/CalendarDay.js.map +1 -1
  17. package/dist-cjs/calendar/internal/CalendarMonth.css.js +1 -1
  18. package/dist-cjs/calendar/internal/CalendarMonth.js +47 -54
  19. package/dist-cjs/calendar/internal/CalendarMonth.js.map +1 -1
  20. package/dist-cjs/calendar/internal/useFocusManagement.js +18 -18
  21. package/dist-cjs/calendar/internal/useFocusManagement.js.map +1 -1
  22. package/dist-cjs/calendar/internal/utils.js +33 -48
  23. package/dist-cjs/calendar/internal/utils.js.map +1 -1
  24. package/dist-cjs/calendar/useCalendar.js +46 -38
  25. package/dist-cjs/calendar/useCalendar.js.map +1 -1
  26. package/dist-cjs/calendar/useCalendarDay.js +15 -21
  27. package/dist-cjs/calendar/useCalendarDay.js.map +1 -1
  28. package/dist-cjs/calendar/useCalendarSelection.js +44 -35
  29. package/dist-cjs/calendar/useCalendarSelection.js.map +1 -1
  30. package/dist-cjs/date-input/DateInput.css.js +1 -1
  31. package/dist-cjs/date-input/DateInputRange.js +102 -107
  32. package/dist-cjs/date-input/DateInputRange.js.map +1 -1
  33. package/dist-cjs/date-input/DateInputSingle.js +39 -51
  34. package/dist-cjs/date-input/DateInputSingle.js.map +1 -1
  35. package/dist-cjs/date-picker/DatePicker.js +15 -13
  36. package/dist-cjs/date-picker/DatePicker.js.map +1 -1
  37. package/dist-cjs/date-picker/DatePickerActions.js +3 -8
  38. package/dist-cjs/date-picker/DatePickerActions.js.map +1 -1
  39. package/dist-cjs/date-picker/DatePickerContext.js +6 -2
  40. package/dist-cjs/date-picker/DatePickerContext.js.map +1 -1
  41. package/dist-cjs/date-picker/DatePickerOverlay.js +1 -0
  42. package/dist-cjs/date-picker/DatePickerOverlay.js.map +1 -1
  43. package/dist-cjs/date-picker/DatePickerOverlayProvider.js +21 -8
  44. package/dist-cjs/date-picker/DatePickerOverlayProvider.js.map +1 -1
  45. package/dist-cjs/date-picker/DatePickerRangeInput.js +77 -28
  46. package/dist-cjs/date-picker/DatePickerRangeInput.js.map +1 -1
  47. package/dist-cjs/date-picker/DatePickerRangePanel.js +45 -40
  48. package/dist-cjs/date-picker/DatePickerRangePanel.js.map +1 -1
  49. package/dist-cjs/date-picker/DatePickerSingleInput.js +123 -84
  50. package/dist-cjs/date-picker/DatePickerSingleInput.js.map +1 -1
  51. package/dist-cjs/date-picker/DatePickerSinglePanel.js +17 -20
  52. package/dist-cjs/date-picker/DatePickerSinglePanel.js.map +1 -1
  53. package/dist-cjs/date-picker/DatePickerTrigger.js +32 -0
  54. package/dist-cjs/date-picker/DatePickerTrigger.js.map +1 -0
  55. package/dist-cjs/date-picker/useDatePicker.js +60 -110
  56. package/dist-cjs/date-picker/useDatePicker.js.map +1 -1
  57. package/dist-cjs/dropdown/DropdownButton.js.map +1 -1
  58. package/dist-cjs/index.js +19 -20
  59. package/dist-cjs/index.js.map +1 -1
  60. package/dist-cjs/localization-provider/LocalizationProvider.js +48 -0
  61. package/dist-cjs/localization-provider/LocalizationProvider.js.map +1 -0
  62. package/dist-cjs/overlay/OverlayHeader.css.js +6 -0
  63. package/dist-cjs/overlay/OverlayHeader.css.js.map +1 -0
  64. package/dist-cjs/overlay/OverlayHeader.js +35 -0
  65. package/dist-cjs/overlay/OverlayHeader.js.map +1 -0
  66. package/dist-cjs/system-status/SystemStatus.css.js +1 -1
  67. package/dist-cjs/tabs-next/TabListNext.css.js +1 -1
  68. package/dist-cjs/tabs-next/TabListNext.js +4 -0
  69. package/dist-cjs/tabs-next/TabListNext.js.map +1 -1
  70. package/dist-es/calendar/Calendar.js +12 -12
  71. package/dist-es/calendar/Calendar.js.map +1 -1
  72. package/dist-es/calendar/CalendarGrid.css.js +4 -0
  73. package/dist-es/calendar/CalendarGrid.css.js.map +1 -0
  74. package/dist-es/calendar/CalendarGrid.js +105 -0
  75. package/dist-es/calendar/CalendarGrid.js.map +1 -0
  76. package/dist-es/calendar/CalendarNavigation.js +220 -202
  77. package/dist-es/calendar/CalendarNavigation.js.map +1 -1
  78. package/dist-es/calendar/CalendarWeekHeader.js +11 -5
  79. package/dist-es/calendar/CalendarWeekHeader.js.map +1 -1
  80. package/dist-es/calendar/internal/CalendarContext.js +6 -2
  81. package/dist-es/calendar/internal/CalendarContext.js.map +1 -1
  82. package/dist-es/calendar/internal/CalendarDay.js +6 -9
  83. package/dist-es/calendar/internal/CalendarDay.js.map +1 -1
  84. package/dist-es/calendar/internal/CalendarMonth.css.js +1 -1
  85. package/dist-es/calendar/internal/CalendarMonth.js +48 -55
  86. package/dist-es/calendar/internal/CalendarMonth.js.map +1 -1
  87. package/dist-es/calendar/internal/useFocusManagement.js +15 -15
  88. package/dist-es/calendar/internal/useFocusManagement.js.map +1 -1
  89. package/dist-es/calendar/internal/utils.js +32 -45
  90. package/dist-es/calendar/internal/utils.js.map +1 -1
  91. package/dist-es/calendar/useCalendar.js +40 -32
  92. package/dist-es/calendar/useCalendar.js.map +1 -1
  93. package/dist-es/calendar/useCalendarDay.js +11 -17
  94. package/dist-es/calendar/useCalendarDay.js.map +1 -1
  95. package/dist-es/calendar/useCalendarSelection.js +40 -29
  96. package/dist-es/calendar/useCalendarSelection.js.map +1 -1
  97. package/dist-es/date-input/DateInput.css.js +1 -1
  98. package/dist-es/date-input/DateInputRange.js +101 -107
  99. package/dist-es/date-input/DateInputRange.js.map +1 -1
  100. package/dist-es/date-input/DateInputSingle.js +39 -51
  101. package/dist-es/date-input/DateInputSingle.js.map +1 -1
  102. package/dist-es/date-picker/DatePicker.js +15 -13
  103. package/dist-es/date-picker/DatePicker.js.map +1 -1
  104. package/dist-es/date-picker/DatePickerActions.js +3 -8
  105. package/dist-es/date-picker/DatePickerActions.js.map +1 -1
  106. package/dist-es/date-picker/DatePickerContext.js +6 -2
  107. package/dist-es/date-picker/DatePickerContext.js.map +1 -1
  108. package/dist-es/date-picker/DatePickerOverlay.js +1 -0
  109. package/dist-es/date-picker/DatePickerOverlay.js.map +1 -1
  110. package/dist-es/date-picker/DatePickerOverlayProvider.js +21 -8
  111. package/dist-es/date-picker/DatePickerOverlayProvider.js.map +1 -1
  112. package/dist-es/date-picker/DatePickerRangeInput.js +78 -30
  113. package/dist-es/date-picker/DatePickerRangeInput.js.map +1 -1
  114. package/dist-es/date-picker/DatePickerRangePanel.js +44 -39
  115. package/dist-es/date-picker/DatePickerRangePanel.js.map +1 -1
  116. package/dist-es/date-picker/DatePickerSingleInput.js +124 -85
  117. package/dist-es/date-picker/DatePickerSingleInput.js.map +1 -1
  118. package/dist-es/date-picker/DatePickerSinglePanel.js +17 -20
  119. package/dist-es/date-picker/DatePickerSinglePanel.js.map +1 -1
  120. package/dist-es/date-picker/DatePickerTrigger.js +30 -0
  121. package/dist-es/date-picker/DatePickerTrigger.js.map +1 -0
  122. package/dist-es/date-picker/useDatePicker.js +61 -111
  123. package/dist-es/date-picker/useDatePicker.js.map +1 -1
  124. package/dist-es/dropdown/DropdownButton.js.map +1 -1
  125. package/dist-es/index.js +8 -7
  126. package/dist-es/index.js.map +1 -1
  127. package/dist-es/localization-provider/LocalizationProvider.js +44 -0
  128. package/dist-es/localization-provider/LocalizationProvider.js.map +1 -0
  129. package/dist-es/overlay/OverlayHeader.css.js +4 -0
  130. package/dist-es/overlay/OverlayHeader.css.js.map +1 -0
  131. package/dist-es/overlay/OverlayHeader.js +33 -0
  132. package/dist-es/overlay/OverlayHeader.js.map +1 -0
  133. package/dist-es/system-status/SystemStatus.css.js +1 -1
  134. package/dist-es/tabs-next/TabListNext.css.js +1 -1
  135. package/dist-es/tabs-next/TabListNext.js +5 -1
  136. package/dist-es/tabs-next/TabListNext.js.map +1 -1
  137. package/dist-types/calendar/Calendar.d.ts +11 -6
  138. package/dist-types/calendar/CalendarGrid.d.ts +13 -0
  139. package/dist-types/calendar/CalendarNavigation.d.ts +9 -11
  140. package/dist-types/calendar/CalendarWeekHeader.d.ts +4 -3
  141. package/dist-types/calendar/index.d.ts +1 -2
  142. package/dist-types/calendar/internal/CalendarContext.d.ts +5 -6
  143. package/dist-types/calendar/internal/CalendarDay.d.ts +6 -8
  144. package/dist-types/calendar/internal/CalendarMonth.d.ts +5 -6
  145. package/dist-types/calendar/internal/useFocusManagement.d.ts +3 -4
  146. package/dist-types/calendar/internal/utils.d.ts +7 -11
  147. package/dist-types/calendar/useCalendar.d.ts +207 -55
  148. package/dist-types/calendar/useCalendarDay.d.ts +5 -7
  149. package/dist-types/calendar/useCalendarSelection.d.ts +92 -58
  150. package/dist-types/date-input/DateInputRange.d.ts +38 -56
  151. package/dist-types/date-input/DateInputSingle.d.ts +32 -49
  152. package/dist-types/date-input/index.d.ts +0 -1
  153. package/dist-types/date-picker/DatePicker.d.ts +23 -5
  154. package/dist-types/date-picker/DatePickerActions.d.ts +13 -12
  155. package/dist-types/date-picker/DatePickerContext.d.ts +42 -59
  156. package/dist-types/date-picker/DatePickerOverlayProvider.d.ts +10 -0
  157. package/dist-types/date-picker/DatePickerRangeInput.d.ts +13 -3
  158. package/dist-types/date-picker/DatePickerRangePanel.d.ts +17 -17
  159. package/dist-types/date-picker/DatePickerSingleInput.d.ts +12 -3
  160. package/dist-types/date-picker/DatePickerSinglePanel.d.ts +11 -11
  161. package/dist-types/date-picker/DatePickerTrigger.d.ts +9 -0
  162. package/dist-types/date-picker/index.d.ts +3 -2
  163. package/dist-types/date-picker/useDatePicker.d.ts +52 -59
  164. package/dist-types/index.d.ts +2 -0
  165. package/dist-types/localization-provider/LocalizationProvider.d.ts +62 -0
  166. package/dist-types/localization-provider/index.d.ts +1 -0
  167. package/dist-types/overlay/OverlayHeader.d.ts +20 -0
  168. package/dist-types/overlay/index.d.ts +1 -0
  169. package/package.json +11 -3
  170. package/dist-cjs/calendar/CalendarDateGrid.css.js +0 -6
  171. package/dist-cjs/calendar/CalendarDateGrid.css.js.map +0 -1
  172. package/dist-cjs/calendar/CalendarDateGrid.js +0 -105
  173. package/dist-cjs/calendar/CalendarDateGrid.js.map +0 -1
  174. package/dist-cjs/calendar/formatDate.js +0 -51
  175. package/dist-cjs/calendar/formatDate.js.map +0 -1
  176. package/dist-cjs/date-input/utils.js +0 -63
  177. package/dist-cjs/date-input/utils.js.map +0 -1
  178. package/dist-es/calendar/CalendarDateGrid.css.js +0 -4
  179. package/dist-es/calendar/CalendarDateGrid.css.js.map +0 -1
  180. package/dist-es/calendar/CalendarDateGrid.js +0 -103
  181. package/dist-es/calendar/CalendarDateGrid.js.map +0 -1
  182. package/dist-es/calendar/formatDate.js +0 -48
  183. package/dist-es/calendar/formatDate.js.map +0 -1
  184. package/dist-es/date-input/utils.js +0 -57
  185. package/dist-es/date-input/utils.js.map +0 -1
  186. package/dist-types/calendar/CalendarDateGrid.d.ts +0 -10
  187. package/dist-types/calendar/formatDate.d.ts +0 -14
  188. package/dist-types/date-input/utils.d.ts +0 -43
@@ -1,43 +1,30 @@
1
- import { getLocalTimeZone, startOfMonth, CalendarDate, endOfMonth } from '@internationalized/date';
2
1
  import { useForkRef, useControlled, useFormFieldProps } from '@salt-ds/core';
3
- import { useMemo, useRef, useState, useEffect, useCallback } from 'react';
4
- import '../calendar/Calendar.js';
5
- import '../calendar/CalendarNavigation.js';
6
- import '../calendar/CalendarWeekHeader.js';
7
- import '../calendar/CalendarDateGrid.js';
8
- import '../calendar/internal/CalendarContext.js';
9
- import { getCurrentLocale } from '../calendar/formatDate.js';
10
- import { CALENDAR_MIN_YEAR, CALENDAR_MAX_YEAR } from '../calendar/useCalendarSelection.js';
2
+ import { useRef, useState, useEffect, useCallback } from 'react';
3
+ import { useLocalization } from '../localization-provider/LocalizationProvider.js';
11
4
  import { useDatePickerOverlay } from './DatePickerOverlayProvider.js';
12
5
 
13
6
  function useDatePicker(props, ref) {
7
+ const {
8
+ defaultDates: { minDate: defaultMinDate, maxDate: defaultMaxDate }
9
+ } = useLocalization();
14
10
  const {
15
11
  readOnly = false,
16
12
  disabled,
17
13
  selectionVariant,
18
- defaultSelectedDate = null,
14
+ defaultSelectedDate,
19
15
  selectedDate: selectedDateProp,
20
- onSelectedDateChange,
16
+ onSelectionChange,
21
17
  onApply,
22
- minDate: minDateProp,
23
- maxDate: maxDateProp,
24
- timeZone = getLocalTimeZone(),
25
- locale = getCurrentLocale(),
18
+ minDate = defaultMinDate,
19
+ maxDate = defaultMaxDate,
26
20
  onCancel
27
21
  } = props;
28
- const minDate = useMemo(
29
- () => minDateProp ?? startOfMonth(new CalendarDate(CALENDAR_MIN_YEAR, 1, 1)),
30
- [minDateProp]
31
- );
32
- const maxDate = useMemo(
33
- () => maxDateProp ?? endOfMonth(new CalendarDate(CALENDAR_MAX_YEAR, 1, 1)),
34
- [maxDateProp]
35
- );
22
+ const previousSelectedDate = useRef();
36
23
  const datePickerRef = useRef(null);
37
24
  const containerRef = useForkRef(ref, datePickerRef);
38
25
  const {
39
26
  state: { open },
40
- helpers: { setOpen }
27
+ helpers: { setOpen, setOnDismiss }
41
28
  } = useDatePickerOverlay();
42
29
  const [selectedDate, setSelectedDate] = useControlled({
43
30
  controlled: selectedDateProp,
@@ -49,117 +36,82 @@ function useDatePicker(props, ref) {
49
36
  const [cancelled, setCancelled] = useState(false);
50
37
  useEffect(() => {
51
38
  if (open) {
39
+ previousSelectedDate.current = selectedDate;
40
+ if (enableApply) {
41
+ setOnDismiss(cancel);
42
+ }
52
43
  setCancelled(false);
53
44
  }
54
- }, [open]);
45
+ }, [enableApply, open, setOnDismiss, setCancelled]);
46
+ useEffect(() => {
47
+ if (cancelled) {
48
+ setSelectedDate(previousSelectedDate == null ? void 0 : previousSelectedDate.current);
49
+ }
50
+ }, [cancelled, setSelectedDate]);
55
51
  const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } = useFormFieldProps();
56
52
  const isReadOnly = readOnly || formFieldReadOnly || false;
57
53
  const isDisabled = disabled || formFieldDisabled || false;
58
- const applySingle = (appliedDate, error) => {
59
- setCancelled(false);
60
- setOpen(false);
61
- if (selectionVariant === "single") {
62
- onApply == null ? void 0 : onApply(appliedDate, error);
63
- }
64
- };
65
- const setSelectedSingleDate = useCallback(
66
- (selection, error) => {
67
- let nextDate;
68
- if (error || !selection) {
69
- nextDate = selection;
70
- } else {
71
- let dateAfterMinDate = true;
72
- let dateBeforeMaxDate = true;
73
- if (minDate && selection) {
74
- dateAfterMinDate = selection.compare(minDate) >= 0;
75
- }
76
- if (maxDate && selection) {
77
- dateBeforeMaxDate = selection.compare(maxDate) <= 0;
78
- }
79
- nextDate = dateAfterMinDate && dateBeforeMaxDate ? selection : null;
54
+ const applySingle = useCallback(
55
+ (event, date) => {
56
+ setCancelled(false);
57
+ setOpen(false);
58
+ if (selectionVariant === "single") {
59
+ onApply == null ? void 0 : onApply(event, date);
80
60
  }
81
- setSelectedDate(nextDate);
61
+ },
62
+ [setCancelled, setOpen, onApply]
63
+ );
64
+ const selectSingle = useCallback(
65
+ (event, date, details) => {
66
+ setSelectedDate(date);
82
67
  if (selectionVariant === "single") {
83
- onSelectedDateChange == null ? void 0 : onSelectedDateChange(nextDate, error);
68
+ onSelectionChange == null ? void 0 : onSelectionChange(event, date, details);
84
69
  }
85
- if (!enableApply) {
86
- setOpen(false);
70
+ if (!enableApply && date) {
71
+ applySingle(event, date);
87
72
  }
88
73
  },
89
74
  [
75
+ applySingle,
90
76
  enableApply,
91
- minDate,
92
- maxDate,
93
- onSelectedDateChange,
77
+ onSelectionChange,
94
78
  selectionVariant,
95
- setSelectedDate,
96
- setOpen
79
+ setSelectedDate
97
80
  ]
98
81
  );
99
- const applyRange = (appliedDate, error) => {
100
- setCancelled(false);
101
- if ((appliedDate == null ? void 0 : appliedDate.startDate) && (appliedDate == null ? void 0 : appliedDate.endDate)) {
82
+ const applyRange = useCallback(
83
+ (event, date) => {
84
+ setCancelled(false);
102
85
  setOpen(false);
103
- }
104
- if (selectionVariant === "range") {
105
- onApply == null ? void 0 : onApply(appliedDate, error);
106
- }
107
- };
108
- const setSelectedRangeDate = useCallback(
109
- (selection, error) => {
110
- let nextDate;
111
- let nextError = { ...error };
112
- let startDateInRange = true;
113
- let endDateInRange = true;
114
- if ((error == null ? void 0 : error.startDate) || (error == null ? void 0 : error.endDate) || !selection) {
115
- nextDate = selection;
116
- } else {
117
- if (maxDate && (selection == null ? void 0 : selection.startDate)) {
118
- startDateInRange = selection.startDate.compare(minDate) >= 0;
119
- }
120
- if (maxDate && (selection == null ? void 0 : selection.endDate)) {
121
- endDateInRange = (selection == null ? void 0 : selection.endDate) && selection.endDate.compare(maxDate) <= 0;
122
- }
123
- if (!startDateInRange && !endDateInRange) {
124
- nextDate = null;
125
- nextError = {
126
- startDate: "is before min date",
127
- endDate: "is after max date"
128
- };
129
- } else {
130
- nextDate = {
131
- startDate: selection.startDate || null,
132
- endDate: selection.endDate || null
133
- };
134
- nextError = {
135
- startDate: !startDateInRange ? "is before min date" : nextError.startDate,
136
- endDate: !endDateInRange ? "is after max date" : nextError.endDate
137
- };
138
- }
86
+ if (selectionVariant === "range") {
87
+ onApply == null ? void 0 : onApply(event, date);
139
88
  }
140
- setSelectedDate(nextDate);
89
+ },
90
+ [onApply, setCancelled, setOpen, selectionVariant]
91
+ );
92
+ const selectRange = useCallback(
93
+ (event, date, details) => {
94
+ setSelectedDate(date);
141
95
  if (selectionVariant === "range") {
142
- onSelectedDateChange == null ? void 0 : onSelectedDateChange(nextDate, nextError);
96
+ onSelectionChange == null ? void 0 : onSelectionChange(event, date, details);
143
97
  }
144
- if (!enableApply && (nextDate == null ? void 0 : nextDate.startDate) && (nextDate == null ? void 0 : nextDate.endDate)) {
145
- setOpen(false);
98
+ if (!enableApply && (date == null ? void 0 : date.startDate) && (date == null ? void 0 : date.endDate)) {
99
+ applyRange(event, date);
146
100
  }
147
101
  },
148
102
  [
103
+ applyRange,
149
104
  enableApply,
150
- minDate,
151
- maxDate,
152
- onSelectedDateChange,
105
+ onSelectionChange,
153
106
  selectionVariant,
154
- setSelectedDate,
155
- setOpen
107
+ setSelectedDate
156
108
  ]
157
109
  );
158
- const cancel = () => {
110
+ const cancel = useCallback(() => {
159
111
  setCancelled(true);
160
112
  setOpen(false);
161
113
  onCancel == null ? void 0 : onCancel();
162
- };
114
+ }, [setCancelled, setOpen, onCancel]);
163
115
  const returnValue = {
164
116
  state: {
165
117
  selectionVariant,
@@ -170,9 +122,7 @@ function useDatePicker(props, ref) {
170
122
  readOnly: isReadOnly,
171
123
  containerRef,
172
124
  minDate,
173
- maxDate,
174
- locale,
175
- timeZone
125
+ maxDate
176
126
  },
177
127
  helpers: {
178
128
  cancel,
@@ -185,7 +135,7 @@ function useDatePicker(props, ref) {
185
135
  helpers: {
186
136
  ...returnValue.helpers,
187
137
  apply: applyRange,
188
- setSelectedDate: setSelectedRangeDate
138
+ select: selectRange
189
139
  }
190
140
  };
191
141
  }
@@ -194,7 +144,7 @@ function useDatePicker(props, ref) {
194
144
  helpers: {
195
145
  ...returnValue.helpers,
196
146
  apply: applySingle,
197
- setSelectedDate: setSelectedSingleDate
147
+ select: selectSingle
198
148
  }
199
149
  };
200
150
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useDatePicker.js","sources":["../src/date-picker/useDatePicker.ts"],"sourcesContent":["import {\n CalendarDate,\n type DateValue,\n endOfMonth,\n getLocalTimeZone,\n startOfMonth,\n} from \"@internationalized/date\";\nimport { useControlled, useForkRef, useFormFieldProps } from \"@salt-ds/core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n CALENDAR_MAX_YEAR,\n CALENDAR_MIN_YEAR,\n type DateRangeSelection,\n type SingleDateSelection,\n getCurrentLocale,\n} from \"../calendar\";\nimport type {\n RangeDatePickerError,\n RangeDatePickerState,\n SingleDatePickerError,\n SingleDatePickerState,\n} from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\ninterface UseDatePickerBaseProps<T> {\n /** If `true`, the component is disabled. */\n disabled?: boolean;\n /** If `true`, the component is read-only. */\n readOnly?: boolean;\n /**\n * The selected date. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: T | null;\n /**\n * The initial selected date, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: UseDatePickerBaseProps<T>[\"selectedDate\"];\n /**\n * The minimum date for the range, default is 1900.\n */\n minDate?: DateValue;\n /**\n * The maximum date for the range, default is 2100.\n */\n maxDate?: DateValue;\n /**\n * Handler for when the date selection is cancelled.\n */\n onCancel?: () => void;\n /**\n * Time zone of the date selection, defaults to the current time zone of the user.\n */\n timeZone?: string;\n /**\n * Locale of the date selection, defaults to the current locale of the user.\n */\n locale?: string;\n}\n\n/**\n * Props for single date selection.\n *\n * @typedef {UseDatePickerBaseProps<SingleDateSelection>} UseDatePickerSingleProps\n * @property {\"single\"} selectionVariant - Single date selection.\n * @property {(selectedSingleDate: SingleDateSelection | null, singleError: string | false) => void} [onSelectedDateChange] - Handler called when the selected date changes.\n * @property {(appliedSingleDate: SingleDateSelection | null, singleError: string | false) => void} [onApply] - Handler called when the selected date is confirmed/applied.\n */\nexport interface UseDatePickerSingleProps\n extends UseDatePickerBaseProps<SingleDateSelection> {\n /**\n * Single date selection.\n */\n selectionVariant: \"single\";\n /**\n * Handler called when the selected date changes.\n * @param {SingleDateSelection | null} selectedSingleDate - The selected date.\n * @param {string | false} singleError - Error returned by the parser or `false`.\n */\n onSelectedDateChange?: (\n selectedSingleDate: SingleDateSelection | null,\n singleError: string | false,\n ) => void;\n /**\n * Handler called when the selected date is confirmed/applied.\n * @param {SingleDateSelection | null} appliedSingleDate - The selected date.\n * @param {string | false} singleError - Error returned by the parser or `false`.\n */\n onApply?: (\n appliedSingleDate: SingleDateSelection | null,\n singleError: string | false,\n ) => void;\n}\n\n/**\n * Props for date range selection.\n *\n * @typedef {UseDatePickerBaseProps<DateRangeSelection>} UseDatePickerRangeProps\n * @property {\"range\"} selectionVariant - Date range selection.\n * @property {(selectedRangeDate: DateRangeSelection | null, rangeError: { startDate: string | false; endDate: string | false }) => void} [onSelectedDateChange] - Handler called when the selected date changes.\n * @property {(appliedRangeDate: DateRangeSelection | null, rangeError: { startDate: string | false; endDate: string | false }) => void} [onApply] - Handler called when the selected date is confirmed/applied.\n */\nexport interface UseDatePickerRangeProps\n extends UseDatePickerBaseProps<DateRangeSelection> {\n /**\n * Date range selection.\n */\n selectionVariant: \"range\";\n /**\n * Handler called when the selected date changes.\n * @param {DateRangeSelection | null} selectedRangeDate - The selected date.\n * @param {{ startDate: string | false; endDate: string | false }} rangeError - Error returned by the parser or `false`.\n */\n onSelectedDateChange?: (\n selectedRangeDate: DateRangeSelection | null,\n rangeError: { startDate: string | false; endDate: string | false },\n ) => void;\n /**\n * Handler called when the selected date is confirmed/applied.\n * @param {DateRangeSelection | null} appliedRangeDate - The selected date.\n * @param {{ startDate: string | false; endDate: string | false }} rangeError - Error returned by the parser or `false`.\n */\n onApply?: (\n appliedRangeDate: DateRangeSelection | null,\n rangeError: { startDate: string | false; endDate: string | false },\n ) => void;\n}\n\n/**\n * Props for the useDatePicker hook.\n *\n * @template SelectionVariant\n * @typedef {SelectionVariant extends \"single\" ? UseDatePickerSingleProps : SelectionVariant extends \"range\" ? UseDatePickerRangeProps : never} UseDatePickerProps\n */\nexport type UseDatePickerProps<SelectionVariant> =\n SelectionVariant extends \"single\"\n ? UseDatePickerSingleProps\n : SelectionVariant extends \"range\"\n ? UseDatePickerRangeProps\n : never;\n\n/**\n * Custom hook for managing date picker state.\n *\n * @template SelectionVariant\n * @param {UseDatePickerProps<SelectionVariant>} props - The props for the date picker.\n * @param {React.ForwardedRef<HTMLDivElement>} ref - The ref for the date picker container.\n * @returns {DatePickerState<SelectionVariant extends \"single\" ? SingleDateSelection : DateRangeSelection>} The date picker state and helpers.\n */\nexport function useDatePicker<SelectionVariant extends \"single\" | \"range\">(\n props: UseDatePickerProps<SelectionVariant>,\n ref: React.ForwardedRef<HTMLDivElement>,\n): SingleDatePickerState | RangeDatePickerState {\n const {\n readOnly = false,\n disabled,\n selectionVariant,\n defaultSelectedDate = null,\n selectedDate: selectedDateProp,\n onSelectedDateChange,\n onApply,\n minDate: minDateProp,\n maxDate: maxDateProp,\n timeZone = getLocalTimeZone(),\n locale = getCurrentLocale(),\n onCancel,\n } = props;\n\n const minDate: DateValue = useMemo(\n () =>\n minDateProp ?? startOfMonth(new CalendarDate(CALENDAR_MIN_YEAR, 1, 1)),\n [minDateProp],\n );\n const maxDate: DateValue = useMemo(\n () => maxDateProp ?? endOfMonth(new CalendarDate(CALENDAR_MAX_YEAR, 1, 1)),\n [maxDateProp],\n );\n\n const datePickerRef = useRef<HTMLDivElement>(null);\n const containerRef = useForkRef(ref, datePickerRef);\n\n const {\n state: { open },\n helpers: { setOpen },\n } = useDatePickerOverlay();\n\n const [selectedDate, setSelectedDate] = useControlled({\n controlled: selectedDateProp,\n default: defaultSelectedDate,\n name: \"DatePicker\",\n state: \"selectedDate\",\n });\n\n const [enableApply, setEnableApply] = useState<boolean>(false);\n const [cancelled, setCancelled] = useState<boolean>(false);\n\n useEffect(() => {\n if (open) {\n setCancelled(false);\n }\n }, [open]);\n\n const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } =\n useFormFieldProps();\n const isReadOnly = readOnly || formFieldReadOnly || false;\n const isDisabled = disabled || formFieldDisabled || false;\n\n const applySingle = (\n appliedDate: SingleDateSelection | null,\n error: SingleDatePickerError,\n ): void => {\n setCancelled(false);\n setOpen(false);\n if (selectionVariant === \"single\") {\n onApply?.(appliedDate, error);\n }\n };\n\n const setSelectedSingleDate = useCallback(\n (selection: SingleDateSelection | null, error: SingleDatePickerError) => {\n let nextDate: typeof selection;\n let nextError = error;\n if (error || !selection) {\n nextDate = selection;\n } else {\n let dateAfterMinDate = true;\n let dateBeforeMaxDate = true;\n if (minDate && selection) {\n dateAfterMinDate = selection.compare(minDate) >= 0;\n }\n if (maxDate && selection) {\n dateBeforeMaxDate = selection.compare(maxDate) <= 0;\n }\n nextDate = dateAfterMinDate && dateBeforeMaxDate ? selection : null;\n nextError = !dateAfterMinDate ? \"is before min date\" : nextError;\n nextError = !dateBeforeMaxDate ? \"is after max date\" : nextError;\n }\n setSelectedDate(nextDate);\n if (selectionVariant === \"single\") {\n onSelectedDateChange?.(nextDate, error);\n }\n\n if (!enableApply) {\n setOpen(false);\n }\n },\n [\n enableApply,\n minDate,\n maxDate,\n onSelectedDateChange,\n selectionVariant,\n setSelectedDate,\n setOpen,\n ],\n );\n\n const applyRange = (\n appliedDate: DateRangeSelection | null,\n error: RangeDatePickerError,\n ): void => {\n setCancelled(false);\n if (appliedDate?.startDate && appliedDate?.endDate) {\n setOpen(false);\n }\n if (selectionVariant === \"range\") {\n onApply?.(appliedDate, error);\n }\n };\n\n const setSelectedRangeDate = useCallback(\n (selection: DateRangeSelection | null, error: RangeDatePickerError) => {\n let nextDate: typeof selection;\n let nextError = { ...error };\n let startDateInRange = true;\n let endDateInRange = true;\n if (error?.startDate || error?.endDate || !selection) {\n nextDate = selection;\n } else {\n if (maxDate && selection?.startDate) {\n startDateInRange = selection.startDate.compare(minDate) >= 0;\n }\n if (maxDate && selection?.endDate) {\n endDateInRange =\n selection?.endDate && selection.endDate.compare(maxDate) <= 0;\n }\n if (!startDateInRange && !endDateInRange) {\n nextDate = null;\n nextError = {\n startDate: \"is before min date\",\n endDate: \"is after max date\",\n };\n } else {\n nextDate = {\n startDate: selection.startDate || null,\n endDate: selection.endDate || null,\n };\n nextError = {\n startDate: !startDateInRange\n ? \"is before min date\"\n : nextError.startDate,\n endDate: !endDateInRange ? \"is after max date\" : nextError.endDate,\n };\n }\n }\n setSelectedDate(nextDate);\n if (selectionVariant === \"range\") {\n onSelectedDateChange?.(nextDate, nextError);\n }\n if (!enableApply && nextDate?.startDate && nextDate?.endDate) {\n setOpen(false);\n }\n },\n [\n enableApply,\n minDate,\n maxDate,\n onSelectedDateChange,\n selectionVariant,\n setSelectedDate,\n setOpen,\n ],\n );\n\n const cancel = () => {\n setCancelled(true);\n setOpen(false);\n onCancel?.();\n };\n\n const returnValue = {\n state: {\n selectionVariant,\n selectedDate,\n cancelled,\n enableApply,\n disabled: isDisabled,\n readOnly: isReadOnly,\n containerRef,\n minDate,\n maxDate,\n locale,\n timeZone,\n },\n helpers: {\n cancel,\n setEnableApply,\n },\n };\n if (props.selectionVariant === \"range\") {\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applyRange,\n setSelectedDate: setSelectedRangeDate,\n },\n } as RangeDatePickerState;\n }\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applySingle,\n setSelectedDate: setSelectedSingleDate,\n },\n } as SingleDatePickerState;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useDatePicker.js","sources":["../src/date-picker/useDatePicker.ts"],"sourcesContent":["import { useControlled, useForkRef, useFormFieldProps } from \"@salt-ds/core\";\nimport type { DateFrameworkType } from \"@salt-ds/date-adapters\";\nimport {\n type SyntheticEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { DateRangeSelection, SingleDateSelection } from \"../calendar\";\nimport type {\n DateInputRangeDetails,\n DateInputSingleDetails,\n} from \"../date-input\";\nimport { useLocalization } from \"../localization-provider\";\nimport type {\n RangeDatePickerState,\n SingleDatePickerState,\n} from \"./DatePickerContext\";\nimport { useDatePickerOverlay } from \"./DatePickerOverlayProvider\";\n\ninterface UseDatePickerBaseProps<TDate> {\n /** If `true`, the component is disabled. */\n disabled?: boolean;\n /** If `true`, the component is read-only. */\n readOnly?: boolean;\n /**\n * The minimum date for the range, default is 1900.\n */\n minDate?: TDate;\n /**\n * The maximum date for the range, default is 2100.\n */\n maxDate?: TDate;\n /**\n * Handler for when the date selection is cancelled.\n */\n onCancel?: () => void;\n}\n\n/**\n * Props for single date selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerSingleProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Single date selection.\n */\n selectionVariant: \"single\";\n /**\n * The selected date. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: SingleDateSelection<TDate> | null;\n /**\n * The initial selected date, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: SingleDateSelection<TDate> | null;\n /**\n * Handler called when the selected date changes.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n * @param details - The selected date details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details?: DateInputSingleDetails,\n ) => void;\n /**\n * Handler called when the selected date is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date or null.\n */\n onApply?: (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for date range selection.\n *\n * @template TDate - The type of the date framework.\n */\nexport interface UseDatePickerRangeProps<TDate extends DateFrameworkType>\n extends UseDatePickerBaseProps<TDate> {\n /**\n * Date range selection.\n */\n selectionVariant: \"range\";\n /**\n * The selected date range. The selected date will be controlled when this prop is provided.\n */\n selectedDate?: DateRangeSelection<TDate> | null;\n /**\n * The initial selected date range, when the selected date is uncontrolled.\n */\n defaultSelectedDate?: DateRangeSelection<TDate> | null;\n /**\n * Handler called when the selected date range changes.\n * @param event - The synthetic event.\n * @param date - The selected date range or null.\n * @param details - The selected date range details.\n */\n onSelectionChange?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details?: DateInputRangeDetails,\n ) => void;\n /**\n * Handler called when the selected date range is confirmed/applied.\n * @param event - The synthetic event.\n * @param date - The selected date range.\n */\n onApply?: (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n ) => void;\n}\n\n/**\n * Props for the useDatePicker hook.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n */\nexport type UseDatePickerProps<\n TDate extends DateFrameworkType,\n SelectionVariant,\n> = SelectionVariant extends \"single\"\n ? UseDatePickerSingleProps<TDate>\n : SelectionVariant extends \"range\"\n ? UseDatePickerRangeProps<TDate>\n : never;\n\n/**\n * Custom hook for managing date picker state.\n *\n * @template TDate - The type of the date framework.\n * @template SelectionVariant - The selection variant, either \"single\" or \"range\".\n * @param props - The props for the date picker.\n * @param ref - The ref for the date picker container.\n * @returns The date picker state and helpers.\n */\nexport function useDatePicker<\n TDate extends DateFrameworkType,\n SelectionVariant extends \"single\" | \"range\",\n>(\n props: UseDatePickerProps<TDate, SelectionVariant>,\n ref: React.ForwardedRef<HTMLDivElement>,\n): SingleDatePickerState<TDate> | RangeDatePickerState<TDate> {\n const {\n defaultDates: { minDate: defaultMinDate, maxDate: defaultMaxDate },\n } = useLocalization<TDate>();\n const {\n readOnly = false,\n disabled,\n selectionVariant,\n defaultSelectedDate,\n selectedDate: selectedDateProp,\n onSelectionChange,\n onApply,\n minDate = defaultMinDate,\n maxDate = defaultMaxDate,\n onCancel,\n } = props;\n\n const previousSelectedDate = useRef<typeof selectedDateProp>();\n const datePickerRef = useRef<HTMLDivElement>(null);\n const containerRef = useForkRef(ref, datePickerRef);\n\n const {\n state: { open },\n helpers: { setOpen, setOnDismiss },\n } = useDatePickerOverlay();\n\n const [selectedDate, setSelectedDate] = useControlled({\n controlled: selectedDateProp,\n default: defaultSelectedDate,\n name: \"DatePicker\",\n state: \"selectedDate\",\n });\n\n const [enableApply, setEnableApply] = useState<boolean>(false);\n const [cancelled, setCancelled] = useState<boolean>(false);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: should run when open changes and not selected date or value\n useEffect(() => {\n if (open) {\n previousSelectedDate.current = selectedDate;\n if (enableApply) {\n setOnDismiss(cancel);\n }\n setCancelled(false);\n }\n }, [enableApply, open, setOnDismiss, setCancelled]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: avoid excessive re-rendering\n useEffect(() => {\n if (cancelled) {\n setSelectedDate(previousSelectedDate?.current);\n }\n }, [cancelled, setSelectedDate]);\n\n const { disabled: formFieldDisabled, readOnly: formFieldReadOnly } =\n useFormFieldProps();\n const isReadOnly = readOnly || formFieldReadOnly || false;\n const isDisabled = disabled || formFieldDisabled || false;\n\n const applySingle = useCallback(\n (event: SyntheticEvent, date: SingleDateSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false);\n if (selectionVariant === \"single\") {\n onApply?.(event, date);\n }\n },\n [setCancelled, setOpen, onApply],\n );\n\n const selectSingle = useCallback(\n (\n event: SyntheticEvent,\n date: SingleDateSelection<TDate> | null,\n details: DateInputSingleDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"single\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date) {\n applySingle(event, date);\n }\n },\n [\n applySingle,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const applyRange = useCallback(\n (event: SyntheticEvent, date: DateRangeSelection<TDate> | null): void => {\n setCancelled(false);\n setOpen(false);\n if (selectionVariant === \"range\") {\n onApply?.(event, date);\n }\n },\n [onApply, setCancelled, setOpen, selectionVariant],\n );\n\n const selectRange = useCallback(\n (\n event: SyntheticEvent,\n date: DateRangeSelection<TDate> | null,\n details: DateInputRangeDetails,\n ) => {\n setSelectedDate(date);\n if (selectionVariant === \"range\") {\n onSelectionChange?.(event, date, details);\n }\n if (!enableApply && date?.startDate && date?.endDate) {\n applyRange(event, date);\n }\n },\n [\n applyRange,\n enableApply,\n onSelectionChange,\n selectionVariant,\n setSelectedDate,\n ],\n );\n\n const cancel = useCallback(() => {\n setCancelled(true);\n setOpen(false);\n onCancel?.();\n }, [setCancelled, setOpen, onCancel]);\n\n const returnValue = {\n state: {\n selectionVariant,\n selectedDate,\n cancelled,\n enableApply,\n disabled: isDisabled,\n readOnly: isReadOnly,\n containerRef,\n minDate,\n maxDate,\n },\n helpers: {\n cancel,\n setEnableApply,\n },\n };\n if (props.selectionVariant === \"range\") {\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applyRange,\n select: selectRange,\n },\n } as RangeDatePickerState<TDate>;\n }\n return {\n ...returnValue,\n helpers: {\n ...returnValue.helpers,\n apply: applySingle,\n select: selectSingle,\n },\n } as SingleDatePickerState<TDate>;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownButton.js","sources":["../src/dropdown/DropdownButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, makePrefixer, useIcon } from \"@salt-ds/core\";\nimport { DEFAULT_ICON_SIZE, type IconProps } from \"@salt-ds/icons\";\nimport { clsx } from \"clsx\";\nimport {\n type AriaAttributes,\n type ComponentType,\n type ForwardedRef,\n forwardRef,\n} from \"react\";\nimport { useFormFieldLegacyProps } from \"../form-field-context-legacy\";\n\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport dropdownButtonCss from \"./DropdownButton.css\";\n\nexport interface DropdownButtonProps extends ButtonProps {\n /**\n * Replace the default Icon component\n */\n IconComponent?: ComponentType<any>;\n /**\n * Whether the dropdown button should hide role='option' via 'aria-hidden'\n */\n ariaHideOptionRole?: boolean;\n /**\n * If, `true`, the Dropdown button will occupy the full width of it's container\n */\n fullWidth?: boolean;\n /**\n * Sets the size of the down arrow icon. If this is not specified, a default size based on density is used.\n */\n iconSize?: IconProps[\"size\"];\n /**\n * Is the dropdown list open\n */\n isOpen?: boolean;\n /**\n * Label for the dropdown button\n */\n label?: string;\n /**\n * Id for the label. This is needed for ARIA attributes.\n */\n labelId?: string;\n /**\n * When the dropdown is collapsed this value is set as aria-posinset on the span containing the selected value\n * **/\n posInSet?: number;\n /**\n * When the dropdown is collapsed this value is set as aria-setsize on the span containing the selected value\n * **/\n setSize?: number;\n /**\n *\n * **/\n labelAriaAttributes?: Pick<\n AriaAttributes,\n \"aria-posinset\" | \"aria-setsize\" | \"aria-selected\"\n >;\n}\n\nconst withBaseName = makePrefixer(\"saltDropdownButton\");\n\nexport const DropdownButton = forwardRef(function DropdownButton(\n {\n IconComponent,\n ariaHideOptionRole,\n className,\n disabled,\n iconSize = DEFAULT_ICON_SIZE,\n isOpen,\n label,\n labelId,\n fullWidth,\n posInSet,\n setSize,\n labelAriaAttributes,\n ...rest\n }: DropdownButtonProps,\n ref: ForwardedRef<HTMLButtonElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-dropdown-button\",\n css: dropdownButtonCss,\n window: targetWindow,\n });\n const { ExpandIcon } = useIcon();\n const Icon = IconComponent === undefined ? ExpandIcon : IconComponent;\n const { inFormField } = useFormFieldLegacyProps();\n // FIXME: use polymorphic button\n // We don't want the 'button' tag to be shown in the DOM to trigger some accessibility testing\n // tool's false alarm on role of 'listbox'\n return (\n <Button\n className={clsx(\n withBaseName(),\n {\n [withBaseName(\"fullwidth\")]: fullWidth,\n [withBaseName(\"formField\")]: inFormField,\n },\n className,\n )}\n data-testid=\"dropdown-button\"\n disabled={disabled}\n variant=\"secondary\"\n {...rest}\n ref={ref}\n >\n <div className={withBaseName(\"content\")}>\n <span\n // 'hidden' so that screen reader won't be confused the additional 'option' which is just a label\n aria-hidden={ariaHideOptionRole ? \"true\" : undefined}\n {...labelAriaAttributes}\n className={withBaseName(\"buttonLabel\")}\n id={labelId}\n // 'option' role here is to suppress accessibility testing tool warning about 'listbox' missing children role.\n role=\"option\"\n >\n {label}\n </span>\n <Icon\n className={withBaseName(\"icon\")}\n size={iconSize}\n aria-label={null}\n aria-hidden=\"true\"\n />\n </div>\n </Button>\n );\n});\n"],"names":["DropdownButton","dropdownButtonCss"],"mappings":";;;;;;;;;;;AA8DA,MAAM,YAAA,GAAe,aAAa,oBAAoB,CAAA;AAEzC,MAAA,cAAA,GAAiB,UAAW,CAAA,SAASA,eAChD,CAAA;AAAA,EACE,aAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAW,GAAA,iBAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,mBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACA,GACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,sBAAA;AAAA,IACR,GAAK,EAAAC,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AACD,EAAM,MAAA,EAAE,UAAW,EAAA,GAAI,OAAQ,EAAA;AAC/B,EAAM,MAAA,IAAA,GAAO,aAAkB,KAAA,KAAA,CAAA,GAAY,UAAa,GAAA,aAAA;AACxD,EAAM,MAAA,EAAE,WAAY,EAAA,GAAI,uBAAwB,EAAA;AAIhD,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA;AAAA,QACT,YAAa,EAAA;AAAA,QACb;AAAA,UACE,CAAC,YAAA,CAAa,WAAW,CAAC,GAAG,SAAA;AAAA,UAC7B,CAAC,YAAA,CAAa,WAAW,CAAC,GAAG;AAAA,SAC/B;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAY,EAAA,iBAAA;AAAA,MACZ,QAAA;AAAA,MACA,OAAQ,EAAA,WAAA;AAAA,MACP,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MAEA,QAAC,kBAAA,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,YAAA,CAAa,SAAS,CACpC,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,aAAA,EAAa,qBAAqB,MAAS,GAAA,KAAA,CAAA;AAAA,YAC1C,GAAG,mBAAA;AAAA,YACJ,SAAA,EAAW,aAAa,aAAa,CAAA;AAAA,YACrC,EAAI,EAAA,OAAA;AAAA,YAEJ,IAAK,EAAA,QAAA;AAAA,YAEJ,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBACA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,aAAa,MAAM,CAAA;AAAA,YAC9B,IAAM,EAAA,QAAA;AAAA,YACN,YAAY,EAAA,IAAA;AAAA,YACZ,aAAY,EAAA;AAAA;AAAA;AACd,OACF,EAAA;AAAA;AAAA,GACF;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"DropdownButton.js","sources":["../src/dropdown/DropdownButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, makePrefixer, useIcon } from \"@salt-ds/core\";\nimport { DEFAULT_ICON_SIZE, type IconProps } from \"@salt-ds/icons\";\nimport { clsx } from \"clsx\";\nimport {\n type AriaAttributes,\n type ComponentType,\n type ForwardedRef,\n forwardRef,\n} from \"react\";\nimport { useFormFieldLegacyProps } from \"../form-field-context-legacy\";\n\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport dropdownButtonCss from \"./DropdownButton.css\";\n\nexport interface DropdownButtonProps extends ButtonProps {\n /**\n * Replace the default Icon component\n */\n IconComponent?: ComponentType<any>;\n /**\n * Whether the dropdown button should hide role='option' via 'aria-hidden'\n */\n ariaHideOptionRole?: boolean;\n /**\n * If, `true`, the Dropdown button will occupy the full width of it's container\n */\n fullWidth?: boolean;\n /**\n * Sets the size of the down arrow icon. If this is not specified, a default size based on density is used.\n */\n iconSize?: IconProps[\"size\"];\n /**\n * Is the dropdown list open\n */\n isOpen?: boolean;\n /**\n * Label for the dropdown button\n */\n label?: string;\n /**\n * Id for the label. This is needed for ARIA attributes.\n */\n labelId?: string;\n /**\n * When the dropdown is collapsed this value is set as aria-posinset on the span containing the selected value\n * **/\n posInSet?: number;\n /**\n * When the dropdown is collapsed this value is set as aria-setsize on the span containing the selected value\n * **/\n setSize?: number;\n /**\n *\n * **/\n labelAriaAttributes?: Pick<\n AriaAttributes,\n \"aria-posinset\" | \"aria-setsize\" | \"aria-selected\"\n >;\n}\n\nconst withBaseName = makePrefixer(\"saltDropdownButton\");\n\nexport const DropdownButton = forwardRef(function DropdownButton(\n {\n IconComponent,\n ariaHideOptionRole,\n className,\n disabled,\n iconSize = DEFAULT_ICON_SIZE,\n isOpen,\n label,\n labelId,\n fullWidth,\n posInSet,\n setSize,\n labelAriaAttributes,\n ...rest\n }: DropdownButtonProps,\n ref: ForwardedRef<HTMLButtonElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-dropdown-button\",\n css: dropdownButtonCss,\n window: targetWindow,\n });\n const { ExpandIcon } = useIcon();\n const Icon = IconComponent === undefined ? ExpandIcon : IconComponent;\n const { inFormField } = useFormFieldLegacyProps();\n // FIXME: use polymorphic button\n // We don't want the 'button' tag to be shown in the DOM to trigger some accessibility testing\n // tool's false alarm on role of 'listbox'\n return (\n <Button\n className={clsx(\n withBaseName(),\n {\n [withBaseName(\"fullwidth\")]: fullWidth,\n [withBaseName(\"formField\")]: inFormField,\n },\n className,\n )}\n data-testid=\"dropdown-button\"\n disabled={disabled}\n variant=\"secondary\"\n {...rest}\n ref={ref}\n >\n <div className={withBaseName(\"content\")}>\n <span\n // 'hidden' so that screen reader won't be confused the additional 'option' which is just a label\n aria-hidden={ariaHideOptionRole ? \"true\" : undefined}\n {...labelAriaAttributes}\n className={withBaseName(\"buttonLabel\")}\n id={labelId}\n // biome-ignore lint/a11y/useAriaPropsForRole: 'option' role here is to suppress accessibility testing tool warning about 'listbox' missing children role\n role=\"option\"\n >\n {label}\n </span>\n <Icon\n className={withBaseName(\"icon\")}\n size={iconSize}\n aria-label={null}\n aria-hidden=\"true\"\n />\n </div>\n </Button>\n );\n});\n"],"names":["DropdownButton","dropdownButtonCss"],"mappings":";;;;;;;;;;;AA8DA,MAAM,YAAA,GAAe,aAAa,oBAAoB,CAAA;AAEzC,MAAA,cAAA,GAAiB,UAAW,CAAA,SAASA,eAChD,CAAA;AAAA,EACE,aAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAW,GAAA,iBAAA;AAAA,EACX,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,mBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACA,GACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,sBAAA;AAAA,IACR,GAAK,EAAAC,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AACD,EAAM,MAAA,EAAE,UAAW,EAAA,GAAI,OAAQ,EAAA;AAC/B,EAAM,MAAA,IAAA,GAAO,aAAkB,KAAA,KAAA,CAAA,GAAY,UAAa,GAAA,aAAA;AACxD,EAAM,MAAA,EAAE,WAAY,EAAA,GAAI,uBAAwB,EAAA;AAIhD,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA;AAAA,QACT,YAAa,EAAA;AAAA,QACb;AAAA,UACE,CAAC,YAAA,CAAa,WAAW,CAAC,GAAG,SAAA;AAAA,UAC7B,CAAC,YAAA,CAAa,WAAW,CAAC,GAAG;AAAA,SAC/B;AAAA,QACA;AAAA,OACF;AAAA,MACA,aAAY,EAAA,iBAAA;AAAA,MACZ,QAAA;AAAA,MACA,OAAQ,EAAA,WAAA;AAAA,MACP,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MAEA,QAAC,kBAAA,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,YAAA,CAAa,SAAS,CACpC,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,aAAA,EAAa,qBAAqB,MAAS,GAAA,KAAA,CAAA;AAAA,YAC1C,GAAG,mBAAA;AAAA,YACJ,SAAA,EAAW,aAAa,aAAa,CAAA;AAAA,YACrC,EAAI,EAAA,OAAA;AAAA,YAEJ,IAAK,EAAA,QAAA;AAAA,YAEJ,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBACA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,aAAa,MAAM,CAAA;AAAA,YAC9B,IAAM,EAAA,QAAA;AAAA,YACN,YAAY,EAAA,IAAA;AAAA,YACZ,aAAY,EAAA;AAAA;AAAA;AACd,OACF,EAAA;AAAA;AAAA,GACF;AAEJ,CAAC;;;;"}
package/dist-es/index.js CHANGED
@@ -27,11 +27,10 @@ export { OrderedButton } from './button-bar/OrderedButton.js';
27
27
  export { Calendar } from './calendar/Calendar.js';
28
28
  export { CalendarNavigation } from './calendar/CalendarNavigation.js';
29
29
  export { CalendarWeekHeader } from './calendar/CalendarWeekHeader.js';
30
- export { CalendarDateGrid } from './calendar/CalendarDateGrid.js';
30
+ export { CalendarGrid } from './calendar/CalendarGrid.js';
31
31
  export { useCalendarDay } from './calendar/useCalendarDay.js';
32
32
  export { useCalendar } from './calendar/useCalendar.js';
33
- export { CALENDAR_MAX_YEAR, CALENDAR_MIN_YEAR, isDateRangeSelection, isMultipleDateSelection, isSingleSelectionValueType, useCalendarSelection, useCalendarSelectionDay } from './calendar/useCalendarSelection.js';
34
- export { formatDate, getCurrentLocale } from './calendar/formatDate.js';
33
+ export { isDateRangeSelection, isMultipleDateSelection, isSingleSelectionValueType, useCalendarSelection, useCalendarSelectionDay } from './calendar/useCalendarSelection.js';
35
34
  export { Carousel } from './carousel/Carousel.js';
36
35
  export { CarouselSlide } from './carousel/CarouselSlide.js';
37
36
  export { CascadingMenu } from './cascading-menu/CascadingMenu.js';
@@ -59,16 +58,16 @@ export { ContactFavoriteToggle } from './contact-details/ContactFavoriteToggle.j
59
58
  export { MailLinkComponent } from './contact-details/MailLinkComponent.js';
60
59
  export { ContentStatus } from './content-status/ContentStatus.js';
61
60
  export { DateInputSingle } from './date-input/DateInputSingle.js';
62
- export { DateInputRange } from './date-input/DateInputRange.js';
63
- export { dateSupportsTime, extractTimeFieldsFromDate, extractTimeFieldsFromDateRange, parseCalendarDate, parseZonedDateTime } from './date-input/utils.js';
61
+ export { DateInputRange, DateParserField } from './date-input/DateInputRange.js';
64
62
  export { DatePicker, DatePickerMain } from './date-picker/DatePicker.js';
65
63
  export { DatePickerActions } from './date-picker/DatePickerActions.js';
66
64
  export { DateRangeSelectionContext, SingleDateSelectionContext, useDatePickerContext } from './date-picker/DatePickerContext.js';
67
65
  export { DatePickerOverlay } from './date-picker/DatePickerOverlay.js';
66
+ export { DatePickerRangeInput, defaultRangeValidator } from './date-picker/DatePickerRangeInput.js';
67
+ export { DatePickerRangePanel } from './date-picker/DatePickerRangePanel.js';
68
68
  export { DatePickerSingleInput } from './date-picker/DatePickerSingleInput.js';
69
69
  export { DatePickerSinglePanel } from './date-picker/DatePickerSinglePanel.js';
70
- export { DatePickerRangeInput } from './date-picker/DatePickerRangeInput.js';
71
- export { DatePickerRangePanel } from './date-picker/DatePickerRangePanel.js';
70
+ export { DatePickerTrigger } from './date-picker/DatePickerTrigger.js';
72
71
  export { DeckItem } from './deck-item/DeckItem.js';
73
72
  export { DeckLayout } from './deck-layout/DeckLayout.js';
74
73
  export { DialogHeader } from './dialog/DialogHeader.js';
@@ -95,6 +94,7 @@ export { useList } from './list/useList.js';
95
94
  export { VirtualizedList } from './list/VirtualizedList.js';
96
95
  export { ListNext } from './list-next/ListNext.js';
97
96
  export { ListItemNext } from './list-next/ListItemNext.js';
97
+ export { LocalizationProvider, LocalizationProviderContext, useLocalization } from './localization-provider/LocalizationProvider.js';
98
98
  export { Logo } from './logo/Logo.js';
99
99
  export { LogoImage } from './logo/LogoImage.js';
100
100
  export { LogoSeparator } from './logo/LogoSeparator.js';
@@ -102,6 +102,7 @@ export { MenuButton } from './menu-button/MenuButton.js';
102
102
  export { Metric } from './metric/Metric.js';
103
103
  export { MetricHeader } from './metric/MetricHeader.js';
104
104
  export { MetricContent } from './metric/MetricContent.js';
105
+ export { OverlayHeader } from './overlay/OverlayHeader.js';
105
106
  export { Portal } from './portal/Portal.js';
106
107
  export { QueryInput } from './query-input/QueryInput.js';
107
108
  export { useQueryInput } from './query-input/useQueryInput.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,44 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { createContext, useMemo, useContext } from 'react';
3
+
4
+ const MIN_DATE = "1900-01-01T00:00:00.000";
5
+ const MAX_DATE = "2099-12-31T00:00:00.000";
6
+ const LocalizationProviderContext = createContext(null);
7
+ if (process.env.NODE_ENV !== "production") {
8
+ LocalizationProviderContext.displayName = "LocalizationProviderContext";
9
+ }
10
+ const LocalizationProvider = function LocalizationProvider2(props) {
11
+ const { children, DateAdapter, instance, locale, minDate, maxDate } = props;
12
+ const dateAdapter = useMemo(() => {
13
+ return new DateAdapter({
14
+ locale,
15
+ instance
16
+ });
17
+ }, [DateAdapter, locale]);
18
+ const defaultDates = useMemo(
19
+ () => ({
20
+ minDate: minDate || dateAdapter.date(MIN_DATE),
21
+ maxDate: maxDate || dateAdapter.date(MAX_DATE)
22
+ }),
23
+ [dateAdapter, minDate, maxDate]
24
+ );
25
+ const contextValue = useMemo(() => {
26
+ return {
27
+ dateAdapter,
28
+ defaultDates
29
+ };
30
+ }, [dateAdapter, defaultDates]);
31
+ return /* @__PURE__ */ jsx(LocalizationProviderContext.Provider, { value: contextValue, children });
32
+ };
33
+ const useLocalization = () => {
34
+ const localization = useContext(LocalizationProviderContext);
35
+ if (!localization) {
36
+ throw new Error(
37
+ "useLocalization should be called inside LocalizationProviderContext.Provider"
38
+ );
39
+ }
40
+ return localization;
41
+ };
42
+
43
+ export { LocalizationProvider, LocalizationProviderContext, useLocalization };
44
+ //# sourceMappingURL=LocalizationProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalizationProvider.js","sources":["../src/localization-provider/LocalizationProvider.tsx"],"sourcesContent":["import type {\n DateFrameworkType,\n SaltDateAdapter,\n} from \"@salt-ds/date-adapters\";\nimport { createContext, useContext, useMemo } from \"react\";\n\nconst MIN_DATE = \"1900-01-01T00:00:00.000\";\nconst MAX_DATE = \"2099-12-31T00:00:00.000\";\n\nexport interface LocalizationProviderValue<TDate extends DateFrameworkType> {\n defaultDates: {\n minDate: TDate;\n maxDate: TDate;\n };\n dateAdapter: SaltDateAdapter<TDate>;\n}\n\n/**\n * Props for the LocalizationProvider component.\n *\n * @template TDate - The type of the date object used in the provider.\n * @template TLocale - The type of the locale, defaulting to string.\n */\nexport interface LocalizationProviderProps<\n TDate extends DateFrameworkType,\n TLocale = string,\n> {\n /**\n * The child components to be rendered within the provider.\n */\n children?: React.ReactNode;\n\n /**\n * The instance of the date library being used.\n */\n instance?: any;\n\n /**\n * The date adapter class, which provides methods for date manipulation and formatting.\n * This should be a constructor for a class implementing the SaltDateAdapter interface.\n */\n DateAdapter: new (\n ...args: any\n ) => SaltDateAdapter<TDate, TLocale>;\n\n /**\n * The locale to be used for date formatting and manipulation.\n */\n locale?: TLocale;\n\n /**\n * The minimum date allowed for all date selections.\n * Defaults to January 1, 1900.\n */\n minDate?: TDate;\n\n /**\n * The maximum date allowed for all date selections.\n * Defaults to December 31, 2099.\n */\n maxDate?: TDate;\n}\n\nexport type LocalizationProviderContext<TDate extends DateFrameworkType> = {\n [K in keyof LocalizationProviderValue<TDate>]:\n | LocalizationProviderValue<TDate>[K]\n | null;\n};\n\nexport const LocalizationProviderContext =\n createContext<LocalizationProviderValue<any> | null>(null);\n\nif (process.env.NODE_ENV !== \"production\") {\n LocalizationProviderContext.displayName = \"LocalizationProviderContext\";\n}\n\nexport const LocalizationProvider = function LocalizationProvider<\n TDate extends DateFrameworkType,\n TLocale,\n>(props: LocalizationProviderProps<TDate, TLocale>) {\n const { children, DateAdapter, instance, locale, minDate, maxDate } = props;\n\n const dateAdapter = useMemo(() => {\n return new DateAdapter({\n locale,\n instance,\n });\n }, [DateAdapter, locale]);\n\n const defaultDates: LocalizationProviderValue<TDate>[\"defaultDates\"] =\n useMemo(\n () => ({\n minDate: minDate || dateAdapter.date(MIN_DATE),\n maxDate: maxDate || dateAdapter.date(MAX_DATE),\n }),\n [dateAdapter, minDate, maxDate],\n );\n\n const contextValue: LocalizationProviderValue<TDate> = useMemo(() => {\n return {\n dateAdapter,\n defaultDates,\n };\n }, [dateAdapter, defaultDates]);\n\n return (\n <LocalizationProviderContext.Provider value={contextValue}>\n {children}\n </LocalizationProviderContext.Provider>\n );\n};\n\n/**\n * Custom hook to access the localization context.\n *\n * This hook provides access to the localization settings and utilities\n * within the `LocalizationProviderContext`. It should be used within a\n * component that is a descendant of `LocalizationProviderContext.Provider`.\n *\n * @template TDate - The type of the date object used in the localization context.\n *\n * @returns The localization provider value, which includes date manipulation and formatting utilities.\n *\n * @throws Will throw an error if the hook is used outside of a `LocalizationProviderContext.Provider`.\n */\nexport const useLocalization = <\n TDate extends DateFrameworkType,\n>(): LocalizationProviderValue<TDate> => {\n const localization = useContext(LocalizationProviderContext);\n if (!localization) {\n throw new Error(\n \"useLocalization should be called inside LocalizationProviderContext.Provider\",\n );\n }\n return localization;\n};\n"],"names":["LocalizationProvider"],"mappings":";;;AAMA,MAAM,QAAW,GAAA,yBAAA;AACjB,MAAM,QAAW,GAAA,yBAAA;AA8DJ,MAAA,2BAAA,GACX,cAAqD,IAAI;AAE3D,IAAI,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AACzC,EAAA,2BAAA,CAA4B,WAAc,GAAA,6BAAA;AAC5C;AAEa,MAAA,oBAAA,GAAuB,SAASA,qBAAAA,CAG3C,KAAkD,EAAA;AAClD,EAAA,MAAM,EAAE,QAAU,EAAA,WAAA,EAAa,UAAU,MAAQ,EAAA,OAAA,EAAS,SAAY,GAAA,KAAA;AAEtE,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM;AAChC,IAAA,OAAO,IAAI,WAAY,CAAA;AAAA,MACrB,MAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,GACA,EAAA,CAAC,WAAa,EAAA,MAAM,CAAC,CAAA;AAExB,EAAA,MAAM,YACJ,GAAA,OAAA;AAAA,IACE,OAAO;AAAA,MACL,OAAS,EAAA,OAAA,IAAW,WAAY,CAAA,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC7C,OAAS,EAAA,OAAA,IAAW,WAAY,CAAA,IAAA,CAAK,QAAQ;AAAA,KAC/C,CAAA;AAAA,IACA,CAAC,WAAa,EAAA,OAAA,EAAS,OAAO;AAAA,GAChC;AAEF,EAAM,MAAA,YAAA,GAAiD,QAAQ,MAAM;AACnE,IAAO,OAAA;AAAA,MACL,WAAA;AAAA,MACA;AAAA,KACF;AAAA,GACC,EAAA,CAAC,WAAa,EAAA,YAAY,CAAC,CAAA;AAE9B,EAAA,2BACG,2BAA4B,CAAA,QAAA,EAA5B,EAAqC,KAAA,EAAO,cAC1C,QACH,EAAA,CAAA;AAEJ;AAeO,MAAM,kBAAkB,MAEU;AACvC,EAAM,MAAA,YAAA,GAAe,WAAW,2BAA2B,CAAA;AAC3D,EAAA,IAAI,CAAC,YAAc,EAAA;AACjB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,YAAA;AACT;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltOverlayHeader {\n padding: var(--salt-spacing-100);\n width: 100%;\n align-items: center;\n display: flex;\n flex-direction: row;\n justify-content: stretch;\n gap: var(--salt-spacing-100);\n box-sizing: border-box;\n}\n\n.saltOverlayHeader-container {\n flex-grow: 1;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-50);\n}\n\n.saltOverlayHeader-header > .saltText {\n margin: 0;\n}\n\n.saltOverlayHeader-actionsContainer {\n align-self: flex-start;\n}\n\n/* Overrides */\n.saltOverlayHeader ~ .saltOverlayPanelContent {\n padding-top: 0;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=OverlayHeader.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayHeader.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,33 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { makePrefixer, Text } from '@salt-ds/core';
3
+ import { useComponentCssInjection } from '@salt-ds/styles';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import { clsx } from 'clsx';
6
+ import { forwardRef } from 'react';
7
+ import css_248z from './OverlayHeader.css.js';
8
+
9
+ const withBaseName = makePrefixer("saltOverlayHeader");
10
+ const OverlayHeader = forwardRef(
11
+ function OverlayHeader2(props, ref) {
12
+ const targetWindow = useWindow();
13
+ useComponentCssInjection({
14
+ testId: "salt-overlay-header",
15
+ css: css_248z,
16
+ window: targetWindow
17
+ });
18
+ const { className, description, header, actions, preheader, ...rest } = props;
19
+ return /* @__PURE__ */ jsxs("div", { className: clsx(withBaseName(), className), ...rest, ref, children: [
20
+ /* @__PURE__ */ jsxs("div", { className: withBaseName("container"), children: [
21
+ /* @__PURE__ */ jsxs("div", { className: withBaseName("header"), children: [
22
+ preheader && /* @__PURE__ */ jsx(Text, { className: withBaseName("preheader"), children: preheader }),
23
+ header
24
+ ] }),
25
+ description && /* @__PURE__ */ jsx(Text, { color: "secondary", className: withBaseName("description"), children: description })
26
+ ] }),
27
+ actions && /* @__PURE__ */ jsx("div", { className: withBaseName("actionsContainer"), children: actions })
28
+ ] });
29
+ }
30
+ );
31
+
32
+ export { OverlayHeader };
33
+ //# sourceMappingURL=OverlayHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverlayHeader.js","sources":["../src/overlay/OverlayHeader.tsx"],"sourcesContent":["import { Text, makePrefixer } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n} from \"react\";\nimport overlayHeaderCss from \"./OverlayHeader.css\";\n\nconst withBaseName = makePrefixer(\"saltOverlayHeader\");\n\nexport interface OverlayHeaderProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * Description text is displayed just below the header\n **/\n description?: ReactNode;\n /**\n * Actions to be displayed in header\n */\n actions?: ReactNode;\n /**\n * Header text\n */\n header?: ReactNode;\n /**\n * Preheader text is displayed just above the header\n **/\n preheader?: ReactNode;\n}\n\nexport const OverlayHeader = forwardRef<HTMLDivElement, OverlayHeaderProps>(\n function OverlayHeader(props, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-overlay-header\",\n css: overlayHeaderCss,\n window: targetWindow,\n });\n\n const { className, description, header, actions, preheader, ...rest } =\n props;\n\n return (\n <div className={clsx(withBaseName(), className)} {...rest} ref={ref}>\n <div className={withBaseName(\"container\")}>\n <div className={withBaseName(\"header\")}>\n {preheader && (\n <Text className={withBaseName(\"preheader\")}>{preheader}</Text>\n )}\n {header}\n </div>\n {description && (\n <Text color=\"secondary\" className={withBaseName(\"description\")}>\n {description}\n </Text>\n )}\n </div>\n {actions && (\n <div className={withBaseName(\"actionsContainer\")}>{actions}</div>\n )}\n </div>\n );\n },\n);\n"],"names":["OverlayHeader","overlayHeaderCss"],"mappings":";;;;;;;;AAWA,MAAM,YAAA,GAAe,aAAa,mBAAmB,CAAA;AAqB9C,MAAM,aAAgB,GAAA,UAAA;AAAA,EAC3B,SAASA,cAAc,CAAA,KAAA,EAAO,GAAK,EAAA;AACjC,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,qBAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IAAM,MAAA,EAAE,WAAW,WAAa,EAAA,MAAA,EAAQ,SAAS,SAAW,EAAA,GAAG,MAC7D,GAAA,KAAA;AAEF,IACE,uBAAA,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,IAAK,CAAA,YAAA,IAAgB,SAAS,CAAA,EAAI,GAAG,IAAA,EAAM,GACzD,EAAA,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,YAAa,CAAA,WAAW,CACtC,EAAA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,YAAa,CAAA,QAAQ,CAClC,EAAA,QAAA,EAAA;AAAA,UAAA,SAAA,wBACE,IAAK,EAAA,EAAA,SAAA,EAAW,YAAa,CAAA,WAAW,GAAI,QAAU,EAAA,SAAA,EAAA,CAAA;AAAA,UAExD;AAAA,SACH,EAAA,CAAA;AAAA,QACC,WAAA,wBACE,IAAK,EAAA,EAAA,KAAA,EAAM,aAAY,SAAW,EAAA,YAAA,CAAa,aAAa,CAAA,EAC1D,QACH,EAAA,WAAA,EAAA;AAAA,OAEJ,EAAA,CAAA;AAAA,MACC,2BACE,GAAA,CAAA,KAAA,EAAA,EAAI,WAAW,YAAa,CAAA,kBAAkB,GAAI,QAAQ,EAAA,OAAA,EAAA;AAAA,KAE/D,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -1,4 +1,4 @@
1
- var css_248z = "/* Styles applied to root component */\n.saltSystemStatus {\n --saltIcon-color: var(--salt-content-bold-foreground);\n\n background: var(--saltSystemStatus-background, var(--systemStatus-background));\n border-color: var(--saltSystemStatus-borderColor, var(--systemStatus-borderColor));\n border-width: var(--saltSystemStatus-borderWidth, var(--salt-size-border));\n border-style: var(--saltSystemStatus-borderStyle, var(--salt-container-borderStyle));\n box-sizing: border-box;\n display: flex;\n gap: var(--salt-spacing-75);\n padding: var(--saltSystemStatus-padding, var(--salt-spacing-50) var(--salt-spacing-100));\n width: 100%;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n}\n\n/* Styles applied to icon */\n.saltSystemStatus-icon.saltIcon {\n min-height: var(--salt-size-base);\n}\n\n/* Styles applied when state = \"info\" */\n.saltSystemStatus-info {\n --systemStatus-borderColor: var(--salt-status-info-bold-background);\n --systemStatus-background: var(--salt-status-info-bold-background);\n}\n\n/* Styles applied when state = \"error\" */\n.saltSystemStatus-error {\n --systemStatus-borderColor: var(--salt-status-error-bold-background);\n --systemStatus-background: var(--salt-status-error-bold-background);\n}\n\n/* Styles applied when state = \"warning\" */\n.saltSystemStatus-warning {\n --systemStatus-borderColor: var(--salt-status-warning-bold-background);\n --systemStatus-background: var(--salt-status-warning-bold-background);\n}\n\n/* Styles applied when state = \"success\" */\n.saltSystemStatus-success {\n --systemStatus-borderColor: var(--salt-status-success-bold-background);\n --systemStatus-background: var(--salt-status-success-bold-background);\n}\n";
1
+ var css_248z = "/* Styles applied to root component */\n.saltSystemStatus {\n background: var(--saltSystemStatus-background, var(--systemStatus-background));\n border-color: var(--saltSystemStatus-borderColor, var(--systemStatus-borderColor));\n border-width: var(--saltSystemStatus-borderWidth, var(--salt-size-border));\n border-style: var(--saltSystemStatus-borderStyle, var(--salt-container-borderStyle));\n box-sizing: border-box;\n display: flex;\n gap: var(--salt-spacing-75);\n padding: var(--saltSystemStatus-padding, var(--salt-spacing-50) var(--salt-spacing-100));\n width: 100%;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n}\n\n/* Styles applied to icon */\n.saltSystemStatus-icon.saltIcon {\n min-height: var(--salt-size-base);\n --saltIcon-color: var(--salt-content-bold-foreground);\n}\n\n/* Styles applied when state = \"info\" */\n.saltSystemStatus-info {\n --systemStatus-borderColor: var(--salt-status-info-bold-background);\n --systemStatus-background: var(--salt-status-info-bold-background);\n}\n\n/* Styles applied when state = \"error\" */\n.saltSystemStatus-error {\n --systemStatus-borderColor: var(--salt-status-error-bold-background);\n --systemStatus-background: var(--salt-status-error-bold-background);\n}\n\n/* Styles applied when state = \"warning\" */\n.saltSystemStatus-warning {\n --systemStatus-borderColor: var(--salt-status-warning-bold-background);\n --systemStatus-background: var(--salt-status-warning-bold-background);\n}\n\n/* Styles applied when state = \"success\" */\n.saltSystemStatus-success {\n --systemStatus-borderColor: var(--salt-status-success-bold-background);\n --systemStatus-background: var(--salt-status-success-bold-background);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=SystemStatus.css.js.map
@@ -1,4 +1,4 @@
1
- var css_248z = "/* Component class applied to the root element */\n.saltTabListNext {\n display: flex;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n position: relative;\n background: transparent;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n gap: var(--salt-spacing-100);\n max-width: 100%;\n}\n\n.saltTabListNext-center {\n justify-content: center;\n}\n\n.saltTabListNext-right {\n justify-content: flex-end;\n}\n\n.saltTabListNext-activeColorPrimary {\n --saltTabListNext-activeColor: var(--salt-container-primary-background);\n}\n\n.saltTabListNext-activeColorSecondary {\n --saltTabListNext-activeColor: var(--salt-container-secondary-background);\n}\n\n.saltTabListNext-activeColorTertiary {\n --saltTabListNext-activeColor: var(--salt-container-tertiary-background);\n}\n";
1
+ var css_248z = "/* Component class applied to the root element */\n.saltTabListNext {\n display: flex;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n position: relative;\n background: transparent;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n gap: var(--salt-spacing-100);\n max-width: 100%;\n}\n\n.saltTabListNext-center {\n justify-content: center;\n}\n\n.saltTabListNext-right {\n justify-content: flex-end;\n}\n\n.saltTabListNext-activeColorPrimary {\n --saltTabListNext-activeColor: var(--salt-container-primary-background);\n}\n\n.saltTabListNext-activeColorSecondary {\n --saltTabListNext-activeColor: var(--salt-container-secondary-background);\n}\n\n.saltTabListNext-activeColorTertiary {\n --saltTabListNext-activeColor: var(--salt-container-tertiary-background);\n}\n\n.saltTabListNext-overflowWarning {\n display: none;\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=TabListNext.css.js.map
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { makePrefixer, useForkRef, useIsomorphicLayoutEffect, capitalize } from '@salt-ds/core';
2
+ import { makePrefixer, useForkRef, useIsomorphicLayoutEffect, useId, capitalize } from '@salt-ds/core';
3
3
  import { useComponentCssInjection } from '@salt-ds/styles';
4
4
  import { useWindow } from '@salt-ds/window';
5
5
  import { clsx } from 'clsx';
@@ -15,6 +15,7 @@ const TabListNext = forwardRef(
15
15
  const {
16
16
  appearance = "bordered",
17
17
  activeColor = "primary",
18
+ "aria-describedby": ariaDescribedBy,
18
19
  children,
19
20
  className,
20
21
  onKeyDown,
@@ -87,6 +88,7 @@ const TabListNext = forwardRef(
87
88
  }
88
89
  });
89
90
  }, [visible, returnFocus, targetWindow, items, selected]);
91
+ const warningId = useId();
90
92
  return /* @__PURE__ */ jsxs(
91
93
  "div",
92
94
  {
@@ -101,8 +103,10 @@ const TabListNext = forwardRef(
101
103
  "data-ismeasuring": isMeasuring ? true : void 0,
102
104
  ref: handleRef,
103
105
  onKeyDown: handleKeyDown,
106
+ "aria-describedby": clsx(ariaDescribedBy, warningId),
104
107
  ...rest,
105
108
  children: [
109
+ hidden.length > 0 && /* @__PURE__ */ jsx("span", { id: warningId, className: withBaseName("overflowWarning"), children: "Note: This tab list includes overflow; tab positions may be inaccurate or change when a tab is selected" }),
106
110
  visible,
107
111
  /* @__PURE__ */ jsx(
108
112
  TabOverflowList,
@@ -1 +1 @@
1
- {"version":3,"file":"TabListNext.js","sources":["../src/tabs-next/TabListNext.tsx"],"sourcesContent":["import {\n capitalize,\n makePrefixer,\n useForkRef,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n forwardRef,\n useRef,\n} from \"react\";\n\nimport tablistNextCss from \"./TabListNext.css\";\nimport { TabOverflowList } from \"./TabOverflowList\";\nimport { useTabsNext } from \"./TabsNextContext\";\nimport { useOverflow } from \"./hooks/useOverflow\";\n\nconst withBaseName = makePrefixer(\"saltTabListNext\");\n\nexport interface TabListNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * Styling active color variant. Defaults to \"primary\".\n */\n activeColor?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * The appearance of the tabs. Defaults to \"bordered\".\n */\n appearance?: \"bordered\" | \"transparent\";\n}\n\nexport const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(\n function TabstripNext(props, ref) {\n const {\n appearance = \"bordered\",\n activeColor = \"primary\",\n children,\n className,\n onKeyDown,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tablist-next\",\n css: tablistNextCss,\n window: targetWindow,\n });\n\n const {\n selected,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n returnFocus,\n } = useTabsNext();\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n const overflowButtonRef = useRef<HTMLButtonElement>(null);\n\n const [visible, hidden, isMeasuring] = useOverflow({\n container: tabstripRef,\n tabs: items,\n children,\n selected,\n overflowButton: overflowButtonRef,\n });\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n const actionMap = {\n ArrowRight: getNext,\n ArrowLeft: getPrevious,\n Home: getFirst,\n End: getLast,\n ArrowUp: menuOpen ? getPrevious : undefined,\n ArrowDown: menuOpen ? getNext : undefined,\n };\n\n const action = actionMap[event.key as keyof typeof actionMap];\n\n if (action) {\n event.preventDefault();\n const activeTabId = activeTab.current?.id;\n if (!activeTabId) return;\n const nextItem = action(activeTabId);\n if (nextItem) {\n nextItem.element?.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n nextItem.element?.focus({ preventScroll: true });\n }\n }\n };\n\n useIsomorphicLayoutEffect(() => {\n if (!returnFocus.current || visible.length < 1 || selected === undefined)\n return;\n\n const itemToFocus = items.find((i) => i.value === returnFocus.current);\n itemToFocus?.element?.focus({ preventScroll: true });\n\n requestAnimationFrame(() => {\n if (targetWindow?.document?.activeElement === itemToFocus?.element) {\n returnFocus.current = undefined;\n }\n });\n }, [visible, returnFocus, targetWindow, items, selected]);\n\n return (\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(appearance),\n withBaseName(\"horizontal\"),\n withBaseName(`activeColor${capitalize(activeColor)}`),\n className,\n )}\n data-ismeasuring={isMeasuring ? true : undefined}\n ref={handleRef}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {visible}\n <TabOverflowList\n isMeasuring={isMeasuring}\n buttonRef={overflowButtonRef}\n tabstripRef={tabstripRef}\n open={menuOpen}\n setOpen={setMenuOpen}\n >\n {hidden}\n </TabOverflowList>\n </div>\n );\n },\n);\n"],"names":["tablistNextCss","_a"],"mappings":"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"}
1
+ {"version":3,"file":"TabListNext.js","sources":["../src/tabs-next/TabListNext.tsx"],"sourcesContent":["import {\n capitalize,\n makePrefixer,\n useForkRef,\n useId,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n forwardRef,\n useRef,\n} from \"react\";\n\nimport tablistNextCss from \"./TabListNext.css\";\nimport { TabOverflowList } from \"./TabOverflowList\";\nimport { useTabsNext } from \"./TabsNextContext\";\nimport { useOverflow } from \"./hooks/useOverflow\";\n\nconst withBaseName = makePrefixer(\"saltTabListNext\");\n\nexport interface TabListNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * Styling active color variant. Defaults to \"primary\".\n */\n activeColor?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * The appearance of the tabs. Defaults to \"bordered\".\n */\n appearance?: \"bordered\" | \"transparent\";\n}\n\nexport const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(\n function TabstripNext(props, ref) {\n const {\n appearance = \"bordered\",\n activeColor = \"primary\",\n \"aria-describedby\": ariaDescribedBy,\n children,\n className,\n onKeyDown,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tablist-next\",\n css: tablistNextCss,\n window: targetWindow,\n });\n\n const {\n selected,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n returnFocus,\n } = useTabsNext();\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n const overflowButtonRef = useRef<HTMLButtonElement>(null);\n\n const [visible, hidden, isMeasuring] = useOverflow({\n container: tabstripRef,\n tabs: items,\n children,\n selected,\n overflowButton: overflowButtonRef,\n });\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n const actionMap = {\n ArrowRight: getNext,\n ArrowLeft: getPrevious,\n Home: getFirst,\n End: getLast,\n ArrowUp: menuOpen ? getPrevious : undefined,\n ArrowDown: menuOpen ? getNext : undefined,\n };\n\n const action = actionMap[event.key as keyof typeof actionMap];\n\n if (action) {\n event.preventDefault();\n const activeTabId = activeTab.current?.id;\n if (!activeTabId) return;\n const nextItem = action(activeTabId);\n if (nextItem) {\n nextItem.element?.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n nextItem.element?.focus({ preventScroll: true });\n }\n }\n };\n\n useIsomorphicLayoutEffect(() => {\n if (!returnFocus.current || visible.length < 1 || selected === undefined)\n return;\n\n const itemToFocus = items.find((i) => i.value === returnFocus.current);\n itemToFocus?.element?.focus({ preventScroll: true });\n\n requestAnimationFrame(() => {\n if (targetWindow?.document?.activeElement === itemToFocus?.element) {\n returnFocus.current = undefined;\n }\n });\n }, [visible, returnFocus, targetWindow, items, selected]);\n\n const warningId = useId();\n\n return (\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(appearance),\n withBaseName(\"horizontal\"),\n withBaseName(`activeColor${capitalize(activeColor)}`),\n className,\n )}\n data-ismeasuring={isMeasuring ? true : undefined}\n ref={handleRef}\n onKeyDown={handleKeyDown}\n aria-describedby={clsx(ariaDescribedBy, warningId)}\n {...rest}\n >\n {hidden.length > 0 && (\n <span id={warningId} className={withBaseName(\"overflowWarning\")}>\n Note: This tab list includes overflow; tab positions may be\n inaccurate or change when a tab is selected\n </span>\n )}\n {visible}\n <TabOverflowList\n isMeasuring={isMeasuring}\n buttonRef={overflowButtonRef}\n tabstripRef={tabstripRef}\n open={menuOpen}\n setOpen={setMenuOpen}\n >\n {hidden}\n </TabOverflowList>\n </div>\n );\n },\n);\n"],"names":["tablistNextCss","_a"],"mappings":"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"}