@dmsi/wedgekit-react 0.0.550 → 0.0.552

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 (180) hide show
  1. package/dist/{chunk-U3QGZAVS.js → chunk-JADOJNBI.js} +4 -4
  2. package/dist/{chunk-N2KPADIL.js → chunk-WNGFRQ4Y.js} +7 -7
  3. package/dist/{chunk-ZVY3TLXL.js → chunk-ZIPJMN2E.js} +4 -4
  4. package/dist/components/Alert.js +2 -2
  5. package/dist/components/CalendarRange.js +10 -10
  6. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.js +10 -10
  7. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.js +10 -10
  8. package/dist/components/DataGrid/PinnedColumns.js +10 -10
  9. package/dist/components/DataGrid/TableBody/LoadingCell.js +10 -10
  10. package/dist/components/DataGrid/TableBody/TableBodyRow.js +10 -10
  11. package/dist/components/DataGrid/TableBody/index.js +10 -10
  12. package/dist/components/DataGrid/index.js +10 -10
  13. package/dist/components/DataGrid/utils.js +10 -10
  14. package/dist/components/DateInput.js +10 -10
  15. package/dist/components/DateRangeInput.js +10 -10
  16. package/dist/components/FilterGroup.js +5 -5
  17. package/dist/components/MobileDataGrid/ColumnSelector/index.js +10 -10
  18. package/dist/components/MobileDataGrid/MobileDataGridHeader.js +10 -10
  19. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.js +5 -5
  20. package/dist/components/MobileDataGrid/index.js +10 -10
  21. package/dist/components/Modal.js +4 -4
  22. package/dist/components/ModalButtons.js +2 -2
  23. package/dist/components/ModalHeader.js +2 -2
  24. package/dist/components/NavigationTab.js +2 -2
  25. package/dist/components/NavigationTabs.js +2 -2
  26. package/dist/components/NestedMenu.js +3 -3
  27. package/dist/components/Notification.js +3 -3
  28. package/dist/components/OptionPill.js +2 -2
  29. package/dist/components/PDFViewer/DownloadIcon.js +2 -2
  30. package/dist/components/PDFViewer/PDFNavigation.js +2 -2
  31. package/dist/components/PDFViewer/index.js +6 -6
  32. package/dist/components/ProductImagePreview/index.js +1 -1
  33. package/dist/components/Stepper.js +3 -3
  34. package/dist/components/Toast.js +3 -3
  35. package/dist/components/Upload.js +3 -3
  36. package/dist/components/index.js +16 -16
  37. package/package.json +8 -9
  38. package/src/brand.css +0 -125
  39. package/src/classNames.ts +0 -174
  40. package/src/components/AccessChangerTabItem.tsx +0 -71
  41. package/src/components/Accordion.tsx +0 -108
  42. package/src/components/Alert.tsx +0 -81
  43. package/src/components/Breadcrumbs.tsx +0 -142
  44. package/src/components/Button.tsx +0 -216
  45. package/src/components/CalendarRange.tsx +0 -628
  46. package/src/components/Caption.tsx +0 -144
  47. package/src/components/Card.tsx +0 -88
  48. package/src/components/Checkbox.tsx +0 -206
  49. package/src/components/CompactImagesPreview.tsx +0 -135
  50. package/src/components/ContentTab.tsx +0 -84
  51. package/src/components/ContentTabs.tsx +0 -136
  52. package/src/components/DMSiLogo.tsx +0 -33
  53. package/src/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.tsx +0 -35
  54. package/src/components/DataGrid/ColumnSelectorHeaderCell/index.tsx +0 -74
  55. package/src/components/DataGrid/PinnedColumns.tsx +0 -183
  56. package/src/components/DataGrid/TableBody/LoadingCell.tsx +0 -44
  57. package/src/components/DataGrid/TableBody/TableBodyRow.tsx +0 -157
  58. package/src/components/DataGrid/TableBody/index.tsx +0 -185
  59. package/src/components/DataGrid/index.tsx +0 -756
  60. package/src/components/DataGrid/types.ts +0 -98
  61. package/src/components/DataGrid/utils.tsx +0 -15
  62. package/src/components/DataGridCell.tsx +0 -526
  63. package/src/components/DataTable.tsx +0 -881
  64. package/src/components/DateInput.tsx +0 -306
  65. package/src/components/DateRangeInput.tsx +0 -758
  66. package/src/components/DebugJson.tsx +0 -28
  67. package/src/components/Display.tsx +0 -66
  68. package/src/components/EditingContext.tsx +0 -43
  69. package/src/components/EmptyCartIcon.tsx +0 -18
  70. package/src/components/FilterGroup.tsx +0 -264
  71. package/src/components/FullViewportBox.tsx +0 -19
  72. package/src/components/Grid.tsx +0 -97
  73. package/src/components/Heading.tsx +0 -72
  74. package/src/components/HorizontalDivider.tsx +0 -22
  75. package/src/components/Icon.tsx +0 -39
  76. package/src/components/ImagePlaceholder.tsx +0 -22
  77. package/src/components/Input.tsx +0 -609
  78. package/src/components/InputGroup.tsx +0 -59
  79. package/src/components/Label.tsx +0 -46
  80. package/src/components/Link.tsx +0 -117
  81. package/src/components/List.tsx +0 -18
  82. package/src/components/ListGroup.tsx +0 -82
  83. package/src/components/LiveChatComponent.tsx +0 -56
  84. package/src/components/LoadingScrim.tsx +0 -33
  85. package/src/components/LogoAgilityTopBar.tsx +0 -54
  86. package/src/components/LogoDMSiTopBar.tsx +0 -33
  87. package/src/components/LogoMillworkTopBar.tsx +0 -119
  88. package/src/components/MainBar.tsx +0 -91
  89. package/src/components/MaxViewportBox.tsx +0 -19
  90. package/src/components/Menu.tsx +0 -316
  91. package/src/components/MenuOption.tsx +0 -330
  92. package/src/components/MobileDataGrid/ColumnList.tsx +0 -66
  93. package/src/components/MobileDataGrid/ColumnSelector/index.tsx +0 -97
  94. package/src/components/MobileDataGrid/GridContextProvider/GridContext.tsx +0 -25
  95. package/src/components/MobileDataGrid/GridContextProvider/index.tsx +0 -132
  96. package/src/components/MobileDataGrid/GridContextProvider/useGridContext.ts +0 -10
  97. package/src/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.tsx +0 -27
  98. package/src/components/MobileDataGrid/MobileDataGridCard/index.tsx +0 -138
  99. package/src/components/MobileDataGrid/MobileDataGridHeader.tsx +0 -81
  100. package/src/components/MobileDataGrid/RowDetailModalProvider/ModalContent.tsx +0 -42
  101. package/src/components/MobileDataGrid/RowDetailModalProvider/index.tsx +0 -68
  102. package/src/components/MobileDataGrid/dataGridReducer.ts +0 -55
  103. package/src/components/MobileDataGrid/index.tsx +0 -92
  104. package/src/components/MobileDataGrid/types.ts +0 -4
  105. package/src/components/Modal.tsx +0 -312
  106. package/src/components/ModalButtons.tsx +0 -62
  107. package/src/components/ModalContent.tsx +0 -31
  108. package/src/components/ModalHeader.tsx +0 -78
  109. package/src/components/ModalScrim.tsx +0 -42
  110. package/src/components/NavigationTab.tsx +0 -95
  111. package/src/components/NavigationTabs.tsx +0 -70
  112. package/src/components/NestedMenu.tsx +0 -131
  113. package/src/components/Notification.tsx +0 -128
  114. package/src/components/OptionPill.tsx +0 -139
  115. package/src/components/OrderCheckIcon.tsx +0 -19
  116. package/src/components/PDFViewer/DownloadIcon.tsx +0 -25
  117. package/src/components/PDFViewer/PDFElement.tsx +0 -90
  118. package/src/components/PDFViewer/PDFNavigation.tsx +0 -68
  119. package/src/components/PDFViewer/PDFPage.tsx +0 -34
  120. package/src/components/PDFViewer/index.tsx +0 -128
  121. package/src/components/Pagination.tsx +0 -182
  122. package/src/components/Paragraph.tsx +0 -55
  123. package/src/components/Password.tsx +0 -62
  124. package/src/components/ProductImagePreview/CarouselPagination.tsx +0 -54
  125. package/src/components/ProductImagePreview/MobileImageCarousel.tsx +0 -226
  126. package/src/components/ProductImagePreview/ProductPrimaryImage.tsx +0 -219
  127. package/src/components/ProductImagePreview/Thumbnail.tsx +0 -55
  128. package/src/components/ProductImagePreview/ZoomWindow.tsx +0 -136
  129. package/src/components/ProductImagePreview/index.tsx +0 -182
  130. package/src/components/ProductImagePreview/useProductImagePreview.ts +0 -211
  131. package/src/components/ProjectBar.tsx +0 -82
  132. package/src/components/Radio.tsx +0 -146
  133. package/src/components/Search.tsx +0 -152
  134. package/src/components/SearchResultImage/index.tsx +0 -39
  135. package/src/components/Select.tsx +0 -114
  136. package/src/components/SideMenu.tsx +0 -30
  137. package/src/components/SideMenuGroup.tsx +0 -95
  138. package/src/components/SideMenuItem.tsx +0 -109
  139. package/src/components/SimpleTable.tsx +0 -77
  140. package/src/components/SkeletonParagraph.tsx +0 -31
  141. package/src/components/Spinner.tsx +0 -32
  142. package/src/components/Stack.tsx +0 -347
  143. package/src/components/StatusPill.tsx +0 -59
  144. package/src/components/Stepper.tsx +0 -128
  145. package/src/components/Subheader.tsx +0 -50
  146. package/src/components/Surface.tsx +0 -37
  147. package/src/components/Swatch.tsx +0 -1341
  148. package/src/components/Textarea.tsx +0 -102
  149. package/src/components/Theme.tsx +0 -27
  150. package/src/components/Time.tsx +0 -460
  151. package/src/components/Toast.tsx +0 -268
  152. package/src/components/Tooltip.tsx +0 -159
  153. package/src/components/TopBar.tsx +0 -139
  154. package/src/components/Upload.tsx +0 -107
  155. package/src/components/WorldpayIframe.tsx +0 -7
  156. package/src/components/index.ts +0 -34
  157. package/src/components/useMenuSystem.tsx +0 -456
  158. package/src/components/useMounted.tsx +0 -14
  159. package/src/darkmode.css +0 -278
  160. package/src/fonts.css +0 -23
  161. package/src/hooks/index.ts +0 -4
  162. package/src/hooks/useInfiniteScroll.tsx +0 -40
  163. package/src/hooks/useKeydown.ts +0 -42
  164. package/src/hooks/useMatchesMedia.ts +0 -18
  165. package/src/hooks/useTableLayout.ts +0 -106
  166. package/src/index.css +0 -800
  167. package/src/index.tsx +0 -5
  168. package/src/types.ts +0 -150
  169. package/src/utils/date.ts +0 -236
  170. package/src/utils/formatting.tsx +0 -81
  171. package/src/utils/index.ts +0 -4
  172. package/src/utils/mergeObjectArrays.ts +0 -18
  173. package/src/utils.ts +0 -24
  174. package/dist/{chunk-7FQ7PGUF.js → chunk-7COWXCPA.js} +3 -3
  175. package/dist/{chunk-NKCFYM7A.js → chunk-7SFFUICM.js} +3 -3
  176. package/dist/{chunk-25RZP3VR.js → chunk-AKJUBFJK.js} +3 -3
  177. package/dist/{chunk-TAPYQBQU.js → chunk-CMMQTIVM.js} +3 -3
  178. package/dist/{chunk-GYEXSNFP.js → chunk-FWCVZWE6.js} +3 -3
  179. package/dist/{chunk-MV6W7OMC.js → chunk-QMMPHXVE.js} +3 -3
  180. package/dist/{chunk-GG5OZTI5.js → chunk-XRE52QTN.js} +3 -3
@@ -1,102 +0,0 @@
1
- "use client";
2
- import clsx from "clsx";
3
- import { ComponentProps, ReactNode } from "react";
4
- import { baseTransition, componentGap, componentPaddingMinusBorder, typography } from "../classNames";
5
-
6
- interface TextareaProps
7
- extends Omit<
8
- ComponentProps<"textarea">,
9
- "children" | "dangerouslySetInnerHTML" | "id"
10
- > {
11
- id?: string;
12
- testid?: string;
13
- label?: string;
14
- error?: boolean;
15
- caption?: ReactNode;
16
- }
17
-
18
- const textareaBaseClass = clsx(
19
- "w-full min-h-19",
20
- "rounded-base border border-border-primary-normal bg-background-primary-normal caret-text-action-normal",
21
- "outline-transparent outline-2",
22
- componentPaddingMinusBorder,
23
- baseTransition,
24
- );
25
-
26
- const textareaInvalidClass = clsx(
27
- "data-error:not-disabled:border-transparent data-error:not-focus:outline-border-primary-error data-error:not-focus:outline-1",
28
- );
29
-
30
- const textareaFocusClass = clsx(
31
- "focus:border-transparent focus:outline-border-primary-focus",
32
- );
33
-
34
- const textareaDisabledClass = clsx(
35
- "disabled:bg-background-action-secondary-disabled disabled:border-border-primary-normal",
36
- );
37
-
38
- const textareaReadOnlyClass = clsx(
39
- "read-only:outline-none read-only:bg-transparent read-only:border-transparent read-only:appearance-none read-only:resize-none read-only:not-disabled:pl-0",
40
- );
41
-
42
- export const Textarea = ({
43
- id,
44
- testid,
45
- label,
46
- error,
47
- caption,
48
- ...props
49
- }: TextareaProps) => {
50
- const attributes = {
51
- "data-error": error || null,
52
- };
53
-
54
- return (
55
- <label
56
- htmlFor={id}
57
- className={clsx(
58
- "flex flex-col w-full",
59
- "text-text-primary-normal has-disabled:text-text-primary-disabled",
60
- !props.disabled &&
61
- !props.readOnly &&
62
- "has-[[data-error]]:text-text-primary-error",
63
- componentGap
64
- )}
65
- >
66
- {label && (
67
- <span
68
- className={clsx(
69
- typography.label,
70
- "text-inherit",
71
- props.disabled || props.readOnly
72
- ? "cursor-default"
73
- : "cursor-pointer",
74
- "inline-block",
75
- )}
76
- >
77
- {label}
78
- </span>
79
- )}
80
-
81
- <textarea
82
- {...props}
83
- {...attributes}
84
- id={id}
85
- data-testid={testid}
86
- className={clsx(
87
- "disabled:text-text-primary-disabled",
88
- typography.paragraph,
89
- textareaBaseClass,
90
- textareaInvalidClass,
91
- textareaFocusClass,
92
- textareaDisabledClass,
93
- textareaReadOnlyClass,
94
- )}
95
- ></textarea>
96
-
97
- {caption && <div id={id ? `${id}-caption` : undefined} data-testid={testid ? `${testid}-caption` : undefined}>{caption}</div>}
98
- </label>
99
- );
100
- };
101
-
102
- Textarea.displayName = "Textarea";
@@ -1,27 +0,0 @@
1
- export function Theme({
2
- theme,
3
- children,
4
- id,
5
- testid,
6
- ref,
7
- }: {
8
- theme: "auto" | "brand";
9
- children: React.ReactNode;
10
- id?: string;
11
- testid?: string;
12
- ref?: React.RefObject<HTMLDivElement | null>;
13
- }) {
14
- return (
15
- <div
16
- id={id}
17
- data-testid={testid}
18
- className="contents"
19
- data-theme={theme}
20
- ref={(e) => {
21
- if (ref) ref.current = e;
22
- }}
23
- >
24
- {children}
25
- </div>
26
- );
27
- }
@@ -1,460 +0,0 @@
1
- import { ComponentProps, ReactNode, useEffect, useRef, useState } from "react";
2
- import { InputBase } from "./Input";
3
- import { createPortal } from "react-dom";
4
- import clsx from "clsx";
5
- import { typography } from "../classNames";
6
- import { Icon } from "./Icon";
7
- import { findDocumentRoot } from "../utils";
8
- import { Stack } from "./Stack";
9
-
10
- type TimeProps = {
11
- label?: string;
12
- error?: boolean;
13
- readOnly?: boolean;
14
- caption?: ReactNode;
15
- format?: "12h" | "24h";
16
- id?: string;
17
- testid?: string;
18
- } & Omit<
19
- ComponentProps<"input">,
20
- "type" | "children" | "dangerouslySetInnerHTML" | "id"
21
- >;
22
-
23
- const timePickerScrollableStyle = "overflow-auto max-h-full py-4 no-scrollbar";
24
-
25
- export const Time = ({ onChange, format = "12h", id, testid, ...props }: TimeProps) => {
26
- const [showTimePicker, setShowTimePicker] = useState(false);
27
- const [hasInteracted, setHasInteracted] = useState(false);
28
- const inputRef = useRef<HTMLInputElement>(null);
29
- const inputContainerRef = useRef<HTMLLabelElement>(null);
30
- const timeRef = useRef<HTMLDivElement>(null);
31
- const [timePosition, setTimePosition] = useState({
32
- top: 0,
33
- left: 0,
34
- width: 0,
35
- });
36
-
37
- const [hour, setHour] = useState<string | null>(null);
38
- const [minute, setMinute] = useState<string | null>(null);
39
- const [meridiem, setMeridiem] = useState<"AM" | "PM" | null>(null);
40
- const [inputValue, setInputValue] = useState("");
41
-
42
- const is12HourFormat = format === "12h";
43
-
44
- const formattedTime =
45
- hour && minute
46
- ? is12HourFormat
47
- ? meridiem
48
- ? `${hour}:${minute} ${meridiem}`
49
- : `${hour}:${minute}`
50
- : `${hour}:${minute}`
51
- : "";
52
-
53
- const updatePosition = () => {
54
- if (inputContainerRef.current) {
55
- const rect = inputContainerRef.current.getBoundingClientRect();
56
- setTimePosition({
57
- top: rect.bottom + window.scrollY + 6,
58
- left: rect.left + window.scrollX,
59
- width: rect.width,
60
- });
61
- }
62
- };
63
-
64
- useEffect(() => {
65
- if (showTimePicker) {
66
- updatePosition();
67
- }
68
- }, [showTimePicker, is12HourFormat]);
69
-
70
- useEffect(() => {
71
- const handleClickOutside = (event: MouseEvent) => {
72
- if (
73
- inputRef.current &&
74
- timeRef.current &&
75
- !inputRef.current.contains(event.target as Node) &&
76
- !timeRef.current.contains(event.target as Node)
77
- ) {
78
- setShowTimePicker(false);
79
- }
80
- };
81
-
82
- if (showTimePicker) {
83
- document.addEventListener("mousedown", handleClickOutside);
84
- }
85
-
86
- return () => {
87
- document.removeEventListener("mousedown", handleClickOutside);
88
- };
89
- }, [showTimePicker, is12HourFormat]);
90
-
91
- useEffect(() => {
92
- if (formattedTime && hasInteracted) {
93
- setInputValue(formattedTime);
94
-
95
- onChange?.({
96
- target: { value: formattedTime },
97
- } as unknown as React.ChangeEvent<HTMLInputElement>);
98
- }
99
- }, [formattedTime, hasInteracted, onChange]);
100
-
101
- const handleFocus = () => {
102
- if (!props.disabled && !props.readOnly) {
103
- setHasInteracted(true);
104
- setShowTimePicker(true);
105
-
106
- // Initialize meridiem to AM if not set and using 12-hour format
107
- if (is12HourFormat && meridiem === null) {
108
- setMeridiem("AM");
109
- }
110
- }
111
- };
112
-
113
- const handleSelect = (
114
- type: "hour" | "minute" | "meridiem",
115
- value: string,
116
- ) => {
117
- if (type === "hour") setHour(value);
118
- if (type === "minute") setMinute(value);
119
- if (type === "meridiem") setMeridiem(value as "AM" | "PM");
120
-
121
- setTimeout(() => {
122
- const allSet =
123
- (type === "hour" ? value : hour) &&
124
- (type === "minute" ? value : minute) &&
125
- (is12HourFormat ? (type === "meridiem" ? value : meridiem) : true);
126
-
127
- if (allSet) {
128
- setShowTimePicker(false);
129
- }
130
- }, 100);
131
- };
132
-
133
- useEffect(() => {
134
- if (!showTimePicker && formattedTime) {
135
- setInputValue(formattedTime);
136
- }
137
- }, [showTimePicker, formattedTime]);
138
-
139
- const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
140
- const value = e.target.value
141
- .toUpperCase()
142
- .replace(/[^0-9:APM ]/gi, "")
143
- .trim();
144
- setInputValue(value);
145
-
146
- // Check if input is cleared
147
- if (value === "") {
148
- setHour(null);
149
- setMinute(null);
150
- setMeridiem(null);
151
- setShowTimePicker(true); // Keep dropdown open
152
- }
153
-
154
- const match = value.match(
155
- is12HourFormat
156
- ? /^(\d{1,2}):(\d{2})(?:\s*(AM|PM))?$/
157
- : /^(\d{1,2}):(\d{2})$/,
158
- );
159
-
160
- if (match) {
161
- const [, hRaw, mRaw, mer] = match;
162
- const h = parseInt(hRaw, 10);
163
- const m = parseInt(mRaw, 10);
164
-
165
- if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
166
- let hStr: string;
167
- const mStr = m.toString().padStart(2, "0");
168
- let meridiemValue = mer as "AM" | "PM" | undefined;
169
-
170
- if (is12HourFormat) {
171
- hStr = (h % 12 || 12).toString().padStart(2, "0");
172
- if (h > 12) {
173
- meridiemValue = "PM";
174
- }
175
- setHour(hStr);
176
- setMinute(mStr);
177
- if (meridiemValue) {
178
- setMeridiem(meridiemValue);
179
- }
180
- } else {
181
- hStr = h.toString().padStart(2, "0");
182
- setHour(hStr);
183
- setMinute(mStr);
184
- }
185
- }
186
- }
187
-
188
- onChange?.(e);
189
- };
190
-
191
- const selectedRefs = {
192
- hour: useRef<HTMLButtonElement | null>(null),
193
- minute: useRef<HTMLButtonElement | null>(null),
194
- meridiem: useRef<HTMLButtonElement | null>(null),
195
- };
196
-
197
- const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
198
- if (e.key === "Enter") {
199
- setShowTimePicker(false);
200
- return;
201
- }
202
-
203
- if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
204
-
205
- e.preventDefault();
206
-
207
- let h: number;
208
- let m: number;
209
- let mer: "AM" | "PM";
210
-
211
- if (
212
- hour === null ||
213
- minute === null ||
214
- (is12HourFormat && meridiem === null)
215
- ) {
216
- const now = new Date();
217
- h = now.getHours();
218
- m = Math.round(now.getMinutes() / 5) * 5;
219
- if (m === 60) {
220
- m = 0;
221
- h += 1;
222
- }
223
- if (is12HourFormat) {
224
- mer = h >= 12 ? "PM" : "AM";
225
- h = h % 12 || 12;
226
- } else {
227
- mer = "AM";
228
- }
229
- } else {
230
- h = parseInt(hour, 10);
231
- m = parseInt(minute, 10);
232
- mer = (meridiem as "AM" | "PM") || "AM";
233
- }
234
-
235
- const step = 5;
236
- const remainder = m % step;
237
- m +=
238
- e.key === "ArrowDown"
239
- ? remainder === 0
240
- ? step
241
- : step - remainder
242
- : -(remainder === 0 ? step : remainder);
243
-
244
- if (m >= 60) {
245
- m -= 60;
246
- h += 1;
247
- } else if (m < 0) {
248
- m += 60;
249
- h -= 1;
250
- }
251
-
252
- if (is12HourFormat) {
253
- if (h > 12) {
254
- h = 1;
255
- mer = mer === "AM" ? "PM" : "AM";
256
- } else if (h <= 0) {
257
- h = 12;
258
- mer = mer === "AM" ? "PM" : "AM";
259
- }
260
- } else {
261
- h = (h + 24) % 24;
262
- }
263
-
264
- setHour(h.toString().padStart(2, "0"));
265
- setMinute(m.toString().padStart(2, "0"));
266
- if (is12HourFormat) setMeridiem(mer);
267
- };
268
-
269
- useEffect(() => {
270
- if (showTimePicker) {
271
- // Use a slight delay to ensure DOM is updated
272
- setTimeout(() => {
273
- selectedRefs.hour.current?.scrollIntoView({
274
- block: "nearest",
275
- behavior: "instant",
276
- });
277
- selectedRefs.minute.current?.scrollIntoView({
278
- block: "nearest",
279
- behavior: "instant",
280
- });
281
- if (is12HourFormat) {
282
- selectedRefs.meridiem.current?.scrollIntoView({
283
- block: "nearest",
284
- behavior: "instant",
285
- });
286
- }
287
- }, 0);
288
- }
289
- }, [
290
- showTimePicker,
291
- is12HourFormat,
292
- selectedRefs.hour,
293
- selectedRefs.minute,
294
- selectedRefs.meridiem,
295
- ]);
296
- const renderOptions = (
297
- items: string[],
298
- type: "hour" | "minute" | "meridiem",
299
- ) =>
300
- items.map((val) => {
301
- const isSelected =
302
- (type === "hour" && val === hour) ||
303
- (type === "minute" && val === minute) ||
304
- (type === "meridiem" && val === meridiem);
305
-
306
- return (
307
- <TimeCell
308
- key={val}
309
- id={id ? `${id}-${type}-${val}` : undefined}
310
- testid={testid ? `${testid}-${type}-${val}` : undefined}
311
- selected={isSelected}
312
- ref={
313
- isSelected
314
- ? (el) => {
315
- selectedRefs[type].current = el;
316
- }
317
- : null
318
- }
319
- onClick={() => handleSelect(type, val)}
320
- className={clsx("!size-10 cursor-pointer", typography.caption)}
321
- >
322
- {val}
323
- </TimeCell>
324
- );
325
- });
326
-
327
- return (
328
- <div className="relative max-w-38">
329
- <InputBase
330
- {...props}
331
- id={id}
332
- testid={testid}
333
- ref={inputRef}
334
- inputContainerRef={inputContainerRef}
335
- value={inputValue}
336
- placeholder={is12HourFormat ? "hh:mm am" : "hh:mm"}
337
- after={
338
- <span className="text-icon-primary-normal contents">
339
- <Icon name="schedule" />
340
- </span>
341
- }
342
- onFocus={handleFocus}
343
- caption={props.caption}
344
- onChange={handleInputChange}
345
- onKeyDown={handleKeyDown}
346
- type="text"
347
- />
348
- {showTimePicker &&
349
- createPortal(
350
- <Stack
351
- id={id ? `${id}-timepicker` : undefined}
352
- elevation={4}
353
- height={240}
354
- position="absolute"
355
- backgroundColor="background-grouped-primary-normal"
356
- overflowX="hidden"
357
- overflowY="hidden"
358
- zIndex={50}
359
- top={timePosition.top}
360
- left={timePosition.left}
361
- minWidth={timePosition.width}
362
- maxWidth={0}
363
- rounded
364
- >
365
- <div ref={timeRef} className="px-4 flex h-60">
366
- <div className={clsx(timePickerScrollableStyle)}>
367
- {renderOptions(
368
- Array.from({ length: is12HourFormat ? 12 : 24 }, (_, i) =>
369
- (i + (is12HourFormat ? 1 : 0)).toString().padStart(2, "0"),
370
- ),
371
- "hour",
372
- )}
373
- </div>
374
- <div className={clsx(timePickerScrollableStyle)}>
375
- {renderOptions(
376
- Array.from({ length: 12 }, (_, i) =>
377
- (i * 5).toString().padStart(2, "0"),
378
- ),
379
- "minute",
380
- )}
381
- </div>
382
- {is12HourFormat && (
383
- <div className="py-4">
384
- {renderOptions(["AM", "PM"], "meridiem")}
385
- </div>
386
- )}
387
- </div>
388
- </Stack>,
389
- findDocumentRoot(timeRef.current),
390
- )}
391
- </div>
392
- );
393
- };
394
-
395
- type TimeCellProps = {
396
- id?: string;
397
- testid?: string;
398
- selected?: boolean;
399
- children?: React.ReactNode;
400
- start?: boolean;
401
- intermediate?: boolean;
402
- end?: boolean;
403
- disabled?: boolean;
404
- today?: boolean;
405
- onClick?: () => void;
406
- onHover?: () => void;
407
- onKeyDown?: (e: React.KeyboardEvent<HTMLButtonElement>) => void;
408
- className?: string;
409
- ref?: React.Ref<HTMLButtonElement> | undefined;
410
- };
411
-
412
- function TimeCell({
413
- id,
414
- testid,
415
- selected = false,
416
- start = false,
417
- intermediate = false,
418
- end = false,
419
- today = false,
420
- disabled = false,
421
- onClick,
422
- onHover,
423
- onKeyDown,
424
- children,
425
- className,
426
- ref,
427
- ...props
428
- }: TimeCellProps) {
429
- const isDefault = !selected && !start && !intermediate && !end && !today;
430
- const isToday = today && !selected && !start && !intermediate && !end;
431
- return (
432
- <button
433
- id={id}
434
- data-testid={testid}
435
- onPointerOver={onHover}
436
- onClick={onClick}
437
- onKeyDown={onKeyDown}
438
- disabled={disabled}
439
- ref={ref}
440
- className={clsx(
441
- "w-full h-full aspect-square flex items-center justify-center ",
442
- isDefault &&
443
- "text-neutral-500 hover:bg-action-100 hover:text-action-500 active:text-action-300 disabled:text-neutral-300 disabled:pointer-events-none rounded",
444
- isToday &&
445
- "rounded-full border border-neutral-300 hover:bg-action-100 hover:text-action-500 active:text-action-300 disabled:text-neutral-300 ",
446
- selected &&
447
- "text-white bg-action-400 hover:bg-action-500 active:bg-action-300 disabled:text-neutral-400 disabled:bg-neutral-200 rounded",
448
- start &&
449
- "bg-action-400 hover:bg-action-500 active:bg-action-300 disabled:text-neutral-400 disabled:bg-neutral-200 rounded-l",
450
- end &&
451
- "bg-action-400 hover:bg-action-500 active:bg-action-300 disabled:text-neutral-400 disabled:bg-neutral-200 rounded-r",
452
- intermediate && "bg-action-100 border-y border-action-400",
453
- className,
454
- )}
455
- {...props}
456
- >
457
- {children}
458
- </button>
459
- );
460
- }