@dmsi/wedgekit-react 0.0.2

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 (263) hide show
  1. package/README.md +35 -0
  2. package/dist/chunk-27KIIUAR.js +59 -0
  3. package/dist/chunk-2G2E2JMA.js +123 -0
  4. package/dist/chunk-4C66DLIJ.js +51 -0
  5. package/dist/chunk-4RD5ZF2V.js +55 -0
  6. package/dist/chunk-4RJKB7LC.js +14 -0
  7. package/dist/chunk-4T7F5BZZ.js +26 -0
  8. package/dist/chunk-5GOBP2JS.js +53 -0
  9. package/dist/chunk-6ZY524ID.js +42 -0
  10. package/dist/chunk-AWQSSKCK.js +32 -0
  11. package/dist/chunk-BNHSAFMP.js +93 -0
  12. package/dist/chunk-BWRHL2AG.js +439 -0
  13. package/dist/chunk-DKKYR6DS.js +132 -0
  14. package/dist/chunk-E5ALT5W7.js +182 -0
  15. package/dist/chunk-FY7PTP6E.js +322 -0
  16. package/dist/chunk-GTCSRHPF.js +119 -0
  17. package/dist/chunk-I2UVVKQI.js +12 -0
  18. package/dist/chunk-IGQVA7SC.js +41 -0
  19. package/dist/chunk-K3IKUSZW.js +59 -0
  20. package/dist/chunk-KENSVWOY.js +151 -0
  21. package/dist/chunk-KX3O6GJ6.js +138 -0
  22. package/dist/chunk-L4UM372R.js +253 -0
  23. package/dist/chunk-ORMEWXMH.js +37 -0
  24. package/dist/chunk-Q3FKEKIN.js +23 -0
  25. package/dist/chunk-SEKKGFM6.js +28 -0
  26. package/dist/chunk-SY3HT54E.js +91 -0
  27. package/dist/chunk-TAW5ZZ4Z.js +346 -0
  28. package/dist/chunk-TRUPPHBQ.js +109 -0
  29. package/dist/chunk-TU55CHXU.js +30 -0
  30. package/dist/chunk-TWZZB4WO.js +114 -0
  31. package/dist/chunk-TYI74BSP.js +62 -0
  32. package/dist/chunk-U42SKNR6.js +104 -0
  33. package/dist/chunk-UU3FA6LV.js +72 -0
  34. package/dist/chunk-WVUIIBRR.js +51 -0
  35. package/dist/chunk-XUIPGYP5.js +39 -0
  36. package/dist/chunk-Z4UCFUF7.js +299 -0
  37. package/dist/components/Breadcrumbs.cjs +376 -0
  38. package/dist/components/Breadcrumbs.js +90 -0
  39. package/dist/components/Button.cjs +319 -0
  40. package/dist/components/Button.js +8 -0
  41. package/dist/components/CalendarRange.cjs +520 -0
  42. package/dist/components/CalendarRange.js +13 -0
  43. package/dist/components/Caption.cjs +283 -0
  44. package/dist/components/Caption.js +80 -0
  45. package/dist/components/Checkbox.cjs +378 -0
  46. package/dist/components/Checkbox.js +11 -0
  47. package/dist/components/ContentTab.cjs +382 -0
  48. package/dist/components/ContentTab.js +10 -0
  49. package/dist/components/ContentTabs.cjs +472 -0
  50. package/dist/components/ContentTabs.js +98 -0
  51. package/dist/components/DMSiLogo.cjs +79 -0
  52. package/dist/components/DMSiLogo.js +56 -0
  53. package/dist/components/DataGrid.cjs +3113 -0
  54. package/dist/components/DataGrid.js +758 -0
  55. package/dist/components/DataGridCell.cjs +1907 -0
  56. package/dist/components/DataGridCell.js +24 -0
  57. package/dist/components/DataTable.cjs +791 -0
  58. package/dist/components/DataTable.js +720 -0
  59. package/dist/components/DateInput.cjs +1130 -0
  60. package/dist/components/DateInput.js +170 -0
  61. package/dist/components/DateRangeInput.cjs +1131 -0
  62. package/dist/components/DateRangeInput.js +171 -0
  63. package/dist/components/DebugJson.cjs +50 -0
  64. package/dist/components/DebugJson.js +27 -0
  65. package/dist/components/Display.cjs +234 -0
  66. package/dist/components/Display.js +12 -0
  67. package/dist/components/EditingContext.cjs +73 -0
  68. package/dist/components/EditingContext.js +35 -0
  69. package/dist/components/FilterGroup.cjs +1431 -0
  70. package/dist/components/FilterGroup.js +231 -0
  71. package/dist/components/FullViewportBox.cjs +35 -0
  72. package/dist/components/FullViewportBox.js +12 -0
  73. package/dist/components/Grid.cjs +69 -0
  74. package/dist/components/Grid.js +36 -0
  75. package/dist/components/GridContainer.cjs +125 -0
  76. package/dist/components/GridContainer.js +92 -0
  77. package/dist/components/Heading.cjs +238 -0
  78. package/dist/components/Heading.js +14 -0
  79. package/dist/components/HorizontalDivider.cjs +33 -0
  80. package/dist/components/HorizontalDivider.js +10 -0
  81. package/dist/components/Icon.cjs +98 -0
  82. package/dist/components/Icon.js +7 -0
  83. package/dist/components/Input.cjs +672 -0
  84. package/dist/components/Input.js +21 -0
  85. package/dist/components/InputGroup.cjs +270 -0
  86. package/dist/components/InputGroup.js +60 -0
  87. package/dist/components/Label.cjs +223 -0
  88. package/dist/components/Label.js +8 -0
  89. package/dist/components/Link.cjs +262 -0
  90. package/dist/components/Link.js +8 -0
  91. package/dist/components/List.cjs +37 -0
  92. package/dist/components/List.js +14 -0
  93. package/dist/components/LiveChatComponent.cjs +63 -0
  94. package/dist/components/LiveChatComponent.js +40 -0
  95. package/dist/components/LogoAgilityTopBar.cjs +115 -0
  96. package/dist/components/LogoAgilityTopBar.js +92 -0
  97. package/dist/components/LogoDMSiTopBar.cjs +79 -0
  98. package/dist/components/LogoDMSiTopBar.js +7 -0
  99. package/dist/components/LogoMillworkTopBar.cjs +221 -0
  100. package/dist/components/LogoMillworkTopBar.js +198 -0
  101. package/dist/components/MainBar.cjs +211 -0
  102. package/dist/components/MainBar.js +65 -0
  103. package/dist/components/Menu.cjs +437 -0
  104. package/dist/components/Menu.js +11 -0
  105. package/dist/components/MenuOption.cjs +483 -0
  106. package/dist/components/MenuOption.js +13 -0
  107. package/dist/components/MobileDataGrid.cjs +658 -0
  108. package/dist/components/MobileDataGrid.js +125 -0
  109. package/dist/components/Modal.cjs +783 -0
  110. package/dist/components/Modal.js +245 -0
  111. package/dist/components/ModalButtons.cjs +385 -0
  112. package/dist/components/ModalButtons.js +10 -0
  113. package/dist/components/ModalContent.cjs +57 -0
  114. package/dist/components/ModalContent.js +7 -0
  115. package/dist/components/ModalHeader.cjs +426 -0
  116. package/dist/components/ModalHeader.js +11 -0
  117. package/dist/components/ModalScrim.cjs +64 -0
  118. package/dist/components/ModalScrim.js +7 -0
  119. package/dist/components/NavigationTab.cjs +431 -0
  120. package/dist/components/NavigationTab.js +10 -0
  121. package/dist/components/NavigationTabs.cjs +477 -0
  122. package/dist/components/NavigationTabs.js +56 -0
  123. package/dist/components/Notification.cjs +640 -0
  124. package/dist/components/Notification.js +117 -0
  125. package/dist/components/OptionPill.cjs +478 -0
  126. package/dist/components/OptionPill.js +11 -0
  127. package/dist/components/Paragraph.cjs +231 -0
  128. package/dist/components/Paragraph.js +8 -0
  129. package/dist/components/Password.cjs +700 -0
  130. package/dist/components/Password.js +53 -0
  131. package/dist/components/ProjectBar.cjs +242 -0
  132. package/dist/components/ProjectBar.js +63 -0
  133. package/dist/components/Radio.cjs +349 -0
  134. package/dist/components/Radio.js +131 -0
  135. package/dist/components/Search.cjs +767 -0
  136. package/dist/components/Search.js +12 -0
  137. package/dist/components/Select.cjs +758 -0
  138. package/dist/components/Select.js +12 -0
  139. package/dist/components/SideMenu.cjs +54 -0
  140. package/dist/components/SideMenu.js +21 -0
  141. package/dist/components/SideMenuGroup.cjs +422 -0
  142. package/dist/components/SideMenuGroup.js +83 -0
  143. package/dist/components/SideMenuItem.cjs +388 -0
  144. package/dist/components/SideMenuItem.js +70 -0
  145. package/dist/components/Stack.cjs +138 -0
  146. package/dist/components/Stack.js +7 -0
  147. package/dist/components/StatusPill.cjs +265 -0
  148. package/dist/components/StatusPill.js +52 -0
  149. package/dist/components/Stepper.cjs +885 -0
  150. package/dist/components/Stepper.js +105 -0
  151. package/dist/components/Subheader.cjs +226 -0
  152. package/dist/components/Subheader.js +8 -0
  153. package/dist/components/Surface.cjs +98 -0
  154. package/dist/components/Surface.js +40 -0
  155. package/dist/components/Swatch.cjs +1728 -0
  156. package/dist/components/Swatch.js +1319 -0
  157. package/dist/components/Textarea.cjs +269 -0
  158. package/dist/components/Textarea.js +96 -0
  159. package/dist/components/Theme.cjs +36 -0
  160. package/dist/components/Theme.js +7 -0
  161. package/dist/components/Time.cjs +1118 -0
  162. package/dist/components/Time.js +353 -0
  163. package/dist/components/Toast.cjs +644 -0
  164. package/dist/components/Toast.js +218 -0
  165. package/dist/components/Tooltip.cjs +273 -0
  166. package/dist/components/Tooltip.js +9 -0
  167. package/dist/components/TopBar.cjs +352 -0
  168. package/dist/components/TopBar.js +132 -0
  169. package/dist/components/useInfiniteScroll.cjs +57 -0
  170. package/dist/components/useInfiniteScroll.js +8 -0
  171. package/dist/components/useMatchesMedia.cjs +53 -0
  172. package/dist/components/useMatchesMedia.js +9 -0
  173. package/dist/components/useMenuSystem.cjs +358 -0
  174. package/dist/components/useMenuSystem.js +11 -0
  175. package/dist/components/useMounted.cjs +39 -0
  176. package/dist/components/useMounted.js +8 -0
  177. package/dist/fonts.css +21 -0
  178. package/dist/icons-light[FILL]-PPZXOLWS.woff2 +0 -0
  179. package/dist/icons-normal[FILL]-PPZXOLWS.woff2 +0 -0
  180. package/dist/index.css +4401 -0
  181. package/dist/open-sans-55T6A4JE.woff2 +0 -0
  182. package/dist/types.cjs +18 -0
  183. package/dist/types.js +0 -0
  184. package/package.json +66 -0
  185. package/src/brand.css +125 -0
  186. package/src/classNames.ts +144 -0
  187. package/src/components/Breadcrumbs.tsx +116 -0
  188. package/src/components/Button.tsx +210 -0
  189. package/src/components/CalendarRange.tsx +429 -0
  190. package/src/components/Caption.tsx +101 -0
  191. package/src/components/Checkbox.tsx +196 -0
  192. package/src/components/ContentTab.tsx +66 -0
  193. package/src/components/ContentTabs.tsx +103 -0
  194. package/src/components/DMSiLogo.tsx +32 -0
  195. package/src/components/DataGrid.tsx +948 -0
  196. package/src/components/DataGridCell.tsx +384 -0
  197. package/src/components/DataTable.tsx +835 -0
  198. package/src/components/DateInput.tsx +188 -0
  199. package/src/components/DateRangeInput.tsx +179 -0
  200. package/src/components/DebugJson.tsx +24 -0
  201. package/src/components/Display.tsx +60 -0
  202. package/src/components/EditingContext.tsx +40 -0
  203. package/src/components/FilterGroup.tsx +234 -0
  204. package/src/components/FullViewportBox.tsx +11 -0
  205. package/src/components/Grid.tsx +75 -0
  206. package/src/components/GridContainer.tsx +124 -0
  207. package/src/components/Heading.tsx +66 -0
  208. package/src/components/HorizontalDivider.tsx +3 -0
  209. package/src/components/Icon.tsx +36 -0
  210. package/src/components/Input.tsx +511 -0
  211. package/src/components/InputGroup.tsx +51 -0
  212. package/src/components/Label.tsx +40 -0
  213. package/src/components/Link.tsx +106 -0
  214. package/src/components/List.tsx +10 -0
  215. package/src/components/LiveChatComponent.tsx +56 -0
  216. package/src/components/LogoAgilityTopBar.tsx +53 -0
  217. package/src/components/LogoDMSiTopBar.tsx +32 -0
  218. package/src/components/LogoMillworkTopBar.tsx +118 -0
  219. package/src/components/MainBar.tsx +83 -0
  220. package/src/components/Menu.tsx +286 -0
  221. package/src/components/MenuOption.tsx +275 -0
  222. package/src/components/MobileDataGrid.tsx +135 -0
  223. package/src/components/Modal.tsx +271 -0
  224. package/src/components/ModalButtons.tsx +44 -0
  225. package/src/components/ModalContent.tsx +23 -0
  226. package/src/components/ModalHeader.tsx +41 -0
  227. package/src/components/ModalScrim.tsx +35 -0
  228. package/src/components/NavigationTab.tsx +89 -0
  229. package/src/components/NavigationTabs.tsx +63 -0
  230. package/src/components/Notification.tsx +120 -0
  231. package/src/components/OptionPill.tsx +114 -0
  232. package/src/components/Paragraph.tsx +49 -0
  233. package/src/components/Password.tsx +46 -0
  234. package/src/components/ProjectBar.tsx +76 -0
  235. package/src/components/Radio.tsx +140 -0
  236. package/src/components/Search.tsx +129 -0
  237. package/src/components/Select.tsx +104 -0
  238. package/src/components/SideMenu.tsx +21 -0
  239. package/src/components/SideMenuGroup.tsx +81 -0
  240. package/src/components/SideMenuItem.tsx +90 -0
  241. package/src/components/Stack.tsx +179 -0
  242. package/src/components/StatusPill.tsx +51 -0
  243. package/src/components/Stepper.tsx +91 -0
  244. package/src/components/Subheader.tsx +44 -0
  245. package/src/components/Surface.tsx +34 -0
  246. package/src/components/Swatch.tsx +1066 -0
  247. package/src/components/Textarea.tsx +101 -0
  248. package/src/components/Theme.tsx +13 -0
  249. package/src/components/Time.tsx +438 -0
  250. package/src/components/Toast.tsx +244 -0
  251. package/src/components/Tooltip.tsx +137 -0
  252. package/src/components/TopBar.tsx +124 -0
  253. package/src/components/useInfiniteScroll.tsx +40 -0
  254. package/src/components/useMatchesMedia.tsx +28 -0
  255. package/src/components/useMenuSystem.tsx +367 -0
  256. package/src/components/useMounted.tsx +14 -0
  257. package/src/darkmode.css +140 -0
  258. package/src/fonts.css +23 -0
  259. package/src/index.css +509 -0
  260. package/src/index.tsx +2 -0
  261. package/src/types.ts +149 -0
  262. package/src/utils/formatting.tsx +81 -0
  263. package/src/utils.ts +23 -0
@@ -0,0 +1,188 @@
1
+ import { useRef, useEffect, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { InputBaseProps, InputBase } from "./Input";
4
+ import { CalendarRange } from "./CalendarRange";
5
+ import { Icon } from "./Icon";
6
+ import { findDocumentRoot } from "../utils";
7
+
8
+ type DateInputProps = InputBaseProps & {
9
+ /**
10
+ * Value in the format "YYYY-MM-DD" or empty string.
11
+ * When enableRangeInSingleMode is true, this should be in format "YYYY-MM-DD|YYYY-MM-DD"
12
+ */
13
+ value: string;
14
+ /**
15
+ * Called when the date changes.
16
+ * For single date: receives "YYYY-MM-DD"
17
+ * For range: receives "YYYY-MM-DD|YYYY-MM-DD"
18
+ */
19
+ onChange: (value: string) => void;
20
+ /**
21
+ * Optional placeholder text
22
+ */
23
+ placeholder?: string;
24
+ /**
25
+ * Optional disabled state
26
+ */
27
+ disabled?: boolean;
28
+ /**
29
+ * Enable range selection in single mode calendar
30
+ */
31
+ readOnly?: boolean; // If true, input is read-only and cannot be focused
32
+ label?: string; // Optional label for the input
33
+ };
34
+ export const DateInput = ({
35
+ value,
36
+ onChange,
37
+ placeholder = "MM/DD/YYYY",
38
+ disabled,
39
+ readOnly = false,
40
+ label,
41
+ ...props
42
+ }: DateInputProps) => {
43
+ const [visible, setVisible] = useState(false);
44
+ const popoverRef = useRef<HTMLDivElement | null>(null);
45
+ const triggerRef = useRef<HTMLInputElement | null>(null);
46
+ const [calendarPosition, setCalendarPosition] = useState({
47
+ top: 0,
48
+ left: 0,
49
+ width: 0,
50
+ });
51
+
52
+ // Extract from and to values from the pipe-separated string when range is enabled
53
+ const [from, to] = [value, ""];
54
+
55
+ const updatePosition = () => {
56
+ if (triggerRef.current) {
57
+ requestAnimationFrame(() => {
58
+ if (triggerRef.current) {
59
+ const rect = triggerRef.current.getBoundingClientRect();
60
+ setCalendarPosition({
61
+ top: rect.bottom + window.scrollY,
62
+ left: rect.left + window.scrollX,
63
+ width: rect.width,
64
+ });
65
+ }
66
+ });
67
+ }
68
+ };
69
+
70
+ useEffect(() => {
71
+ updatePosition();
72
+
73
+ const resizeObserver = new ResizeObserver(updatePosition);
74
+ if (triggerRef.current) {
75
+ resizeObserver.observe(triggerRef.current);
76
+ }
77
+
78
+ window.addEventListener("scroll", updatePosition);
79
+
80
+ return () => {
81
+ resizeObserver.disconnect();
82
+ window.removeEventListener("scroll", updatePosition);
83
+ };
84
+ }, []);
85
+
86
+ useEffect(() => {
87
+ const handleKeyDown = (event: KeyboardEvent) => {
88
+ if (event.key === "Escape" && popoverRef.current) {
89
+ setVisible(false);
90
+ triggerRef.current?.blur();
91
+ }
92
+ };
93
+ document.addEventListener("keydown", handleKeyDown);
94
+ return () => {
95
+ document.removeEventListener("keydown", handleKeyDown);
96
+ };
97
+ });
98
+
99
+ useEffect(() => {
100
+ const handleClickOutside = (event: MouseEvent) => {
101
+ if (
102
+ popoverRef.current &&
103
+ !popoverRef.current.contains(event.target as HTMLElement) &&
104
+ triggerRef.current &&
105
+ !triggerRef.current.contains(event.target as HTMLElement)
106
+ ) {
107
+ setVisible(false);
108
+ }
109
+ };
110
+ document.addEventListener("mousedown", handleClickOutside);
111
+ return () => {
112
+ document.removeEventListener("mousedown", handleClickOutside);
113
+ };
114
+ }, []);
115
+
116
+ function handleDateChange(fromValue: string) {
117
+ // For single date selection, only pass the from value
118
+ onChange(fromValue);
119
+ setVisible(false);
120
+ }
121
+
122
+ const handleFocus = () => {
123
+ if (readOnly) return;
124
+ setVisible(true);
125
+ updatePosition();
126
+ };
127
+
128
+ function formatDisplayValue(from?: string) {
129
+ if (!from) return "";
130
+
131
+ // Show single date format: "MM/DD/YYYY"
132
+ return formatDate(from ?? "");
133
+ }
134
+
135
+ function formatDate(date: string) {
136
+ if (!date) return "";
137
+ const [y, m, d] = date.split("-");
138
+ return `${m}/${d}/${y}`;
139
+ }
140
+
141
+ return (
142
+ <div className="relative">
143
+ <InputBase
144
+ ref={(el) => {
145
+ triggerRef.current = el;
146
+ }}
147
+ {...props}
148
+ value={formatDisplayValue(from)}
149
+ placeholder={placeholder}
150
+ disabled={disabled}
151
+ readOnly={readOnly}
152
+ after={<Icon name="calendar_month" />}
153
+ onFocus={handleFocus}
154
+ onChange={() => {
155
+ // Input is controlled by calendar picker, ignore direct text changes
156
+ }}
157
+ label={label}
158
+ />
159
+ {visible &&
160
+ !readOnly &&
161
+ createPortal(
162
+ <div
163
+ ref={(el) => {
164
+ popoverRef.current = el;
165
+ }}
166
+ className="absolute z-40 bg-white"
167
+ style={{
168
+ top: `${calendarPosition.top + 16}px`,
169
+ left: `${calendarPosition.left - 4}px`,
170
+ minWidth: `${calendarPosition.width}px`,
171
+ }}
172
+ >
173
+ <CalendarRange
174
+ from={from}
175
+ to={to || from}
176
+ onChange={handleDateChange}
177
+ cardStyle
178
+ mode="single"
179
+ disableRange
180
+ />
181
+ </div>,
182
+ findDocumentRoot(popoverRef.current),
183
+ )}
184
+ </div>
185
+ );
186
+ };
187
+
188
+ DateInput.displayName = "DateInput";
@@ -0,0 +1,179 @@
1
+ import { useRef, useEffect, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { InputBaseProps, InputBase } from "./Input";
4
+ import { CalendarRange } from "./CalendarRange";
5
+ import { Icon } from "./Icon";
6
+ import { findDocumentRoot } from "../utils";
7
+
8
+ type DateRangeInputProps = InputBaseProps & {
9
+ /**
10
+ * Value in the format "YYYY-MM-DD|YYYY-MM-DD" or empty string
11
+ */
12
+ value: string;
13
+ /**
14
+ * Called when the range changes. Value is in the format "YYYY-MM-DD|YYYY-MM-DD"
15
+ */
16
+ onChange: (value: string) => void;
17
+ /**
18
+ * Optional placeholder text
19
+ */
20
+ placeholder?: string;
21
+ /**
22
+ * Optional disabled state
23
+ */
24
+ disabled?: boolean;
25
+ single?: boolean; // If true, allows single date selection instead of range
26
+ readOnly?: boolean; // If true, input is read-only and cannot be focused
27
+ label?: string; // Optional label for the input
28
+ };
29
+
30
+ export const DateRangeInput = ({
31
+ value,
32
+ onChange,
33
+ placeholder = "MM/DD/YYYY - MM/DD/YYYY",
34
+ disabled,
35
+ readOnly = false,
36
+ single = false, // Enables single date selection instead of range
37
+ label,
38
+ ...props
39
+ }: DateRangeInputProps) => {
40
+ const [visible, setVisible] = useState(false);
41
+ const popoverRef = useRef<HTMLDivElement | null>(null);
42
+ const triggerRef = useRef<HTMLInputElement | null>(null);
43
+ const [calendarPosition, setCalendarPosition] = useState({
44
+ top: 0,
45
+ left: 0,
46
+ width: 0,
47
+ });
48
+
49
+ const [from, to] = value.split("|");
50
+
51
+ const updatePosition = () => {
52
+ if (triggerRef.current) {
53
+ requestAnimationFrame(() => {
54
+ const rect = triggerRef.current!.getBoundingClientRect();
55
+ setCalendarPosition({
56
+ top: rect.bottom + window.scrollY,
57
+ left: rect.left + window.scrollX,
58
+ width: rect.width,
59
+ });
60
+ });
61
+ }
62
+ };
63
+
64
+ useEffect(() => {
65
+ updatePosition();
66
+
67
+ const resizeObserver = new ResizeObserver(updatePosition);
68
+ if (triggerRef.current) {
69
+ resizeObserver.observe(triggerRef.current);
70
+ }
71
+
72
+ window.addEventListener("scroll", updatePosition);
73
+
74
+ return () => {
75
+ resizeObserver.disconnect();
76
+ window.removeEventListener("scroll", updatePosition);
77
+ };
78
+ }, []);
79
+
80
+ useEffect(() => {
81
+ const handleKeyDown = (event: KeyboardEvent) => {
82
+ if (event.key === "Escape" && popoverRef.current) {
83
+ setVisible(false);
84
+ triggerRef.current?.blur();
85
+ }
86
+ };
87
+ document.addEventListener("keydown", handleKeyDown);
88
+ return () => {
89
+ document.removeEventListener("keydown", handleKeyDown);
90
+ };
91
+ });
92
+
93
+ useEffect(() => {
94
+ const handleClickOutside = (event: MouseEvent) => {
95
+ if (
96
+ popoverRef.current &&
97
+ !popoverRef.current.contains(event.target as HTMLElement) &&
98
+ triggerRef.current &&
99
+ !triggerRef.current.contains(event.target as HTMLElement)
100
+ ) {
101
+ setVisible(false);
102
+ }
103
+ };
104
+ document.addEventListener("mousedown", handleClickOutside);
105
+ return () => {
106
+ document.removeEventListener("mousedown", handleClickOutside);
107
+ };
108
+ }, []);
109
+
110
+ function handleRangeChange(fromValue: string, toValue: string) {
111
+ onChange(`${fromValue}|${toValue}`);
112
+ setVisible(false);
113
+ }
114
+
115
+ const handleFocus = () => {
116
+ if (readOnly) return; // Do not open calendar if read-only
117
+ setVisible(true);
118
+ updatePosition();
119
+ };
120
+
121
+ function formatDisplayValue(from?: string, to?: string) {
122
+ if (!from && !to) return "";
123
+ if (from && to) return `${formatDate(from)} - ${formatDate(to)}`;
124
+ if (from) return `${formatDate(from)} -`;
125
+ return "";
126
+ }
127
+
128
+ function formatDate(date: string) {
129
+ const [y, m, d] = date.split("-");
130
+ return `${m}/${d}/${y}`;
131
+ }
132
+
133
+ return (
134
+ <div className="relative">
135
+ <InputBase
136
+ ref={(el) => {
137
+ triggerRef.current = el;
138
+ }}
139
+ {...props}
140
+ value={formatDisplayValue(from, to)}
141
+ placeholder={placeholder}
142
+ disabled={disabled}
143
+ after={<Icon name="calendar_month" />}
144
+ onFocus={handleFocus}
145
+ readOnly={readOnly}
146
+ label={label}
147
+ onChange={() => {
148
+ // Input is controlled by calendar picker, ignore direct text changes
149
+ }}
150
+ />
151
+ {visible &&
152
+ !readOnly &&
153
+ createPortal(
154
+ <div
155
+ ref={(el) => {
156
+ popoverRef.current = el;
157
+ }}
158
+ className="absolute z-40 bg-white"
159
+ style={{
160
+ top: `${calendarPosition.top + 16}px`,
161
+ left: `${calendarPosition.left - 4}px`,
162
+ minWidth: `${calendarPosition.width}px`,
163
+ }}
164
+ >
165
+ <CalendarRange
166
+ from={from}
167
+ to={to}
168
+ onChange={handleRangeChange}
169
+ cardStyle
170
+ mode={single ? "single" : "double"}
171
+ />
172
+ </div>,
173
+ findDocumentRoot(popoverRef.current),
174
+ )}
175
+ </div>
176
+ );
177
+ };
178
+
179
+ DateRangeInput.displayName = "DateRangeInput";
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { useState } from "react";
3
+
4
+ export function DebugJson({ data }: { data: unknown }) {
5
+ const [open, setOpen] = useState(false);
6
+
7
+ if (process.env.NODE_ENV !== "development") {
8
+ return null;
9
+ }
10
+
11
+ return (
12
+ <div className="p-2 rounded bg-neutral-100 border border-red-500 my-4">
13
+ <button
14
+ onClick={() => setOpen((prev) => !prev)}
15
+ className="px-4 py-2 border rounded bg-white"
16
+ >
17
+ {open ? "Hide JSON" : "Show JSON"}
18
+ </button>
19
+ {open && <pre className="mt-4">{JSON.stringify(data, null, 4)}</pre>}
20
+ </div>
21
+ );
22
+ }
23
+
24
+ DebugJson.displayName = "dasda";
@@ -0,0 +1,60 @@
1
+ import clsx from "clsx";
2
+ import { AsProps, TextAttributes, TypographyProps } from "../types";
3
+ import { typography } from "../classNames";
4
+
5
+ type Tags = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "span" | "p";
6
+
7
+ type DisplayVariant = "display1" | "display2";
8
+
9
+ type DisplayProps = {
10
+ as?: Tags;
11
+ variant?: DisplayVariant;
12
+ } & AsProps<Tags> &
13
+ TextAttributes &
14
+ TypographyProps;
15
+
16
+ export const Display = ({
17
+ className,
18
+ children,
19
+ as,
20
+ color,
21
+ align,
22
+ variant = "display1",
23
+ ...props
24
+ }: DisplayProps) => {
25
+ const defaultElement = variant === "display1" ? "h1" : "h2";
26
+ const Element = as ?? defaultElement;
27
+
28
+ return (
29
+ <Element
30
+ className={clsx(
31
+ typography[variant],
32
+ className,
33
+ align === "left" && "text-left",
34
+ align === "center" && "text-center",
35
+ align === "right" && "text-right",
36
+ )}
37
+ style={{
38
+ ...props.style,
39
+ color: color ? `var(--color-${color})` : undefined,
40
+ }}
41
+ {...props}
42
+ >
43
+ {children}
44
+ </Element>
45
+ );
46
+ };
47
+
48
+ Display.displayName = "Display";
49
+
50
+ // Backward compatibility exports
51
+ export const Display1 = (props: Omit<DisplayProps, "variant">) => (
52
+ <Display {...props} variant="display1" />
53
+ );
54
+
55
+ export const Display2 = (props: Omit<DisplayProps, "variant">) => (
56
+ <Display {...props} variant="display2" />
57
+ );
58
+
59
+ Display1.displayName = "Display1";
60
+ Display2.displayName = "Display2";
@@ -0,0 +1,40 @@
1
+ "use client";
2
+
3
+ import { createContext, PropsWithChildren, useState } from "react";
4
+
5
+ type EditingContextType<T> = {
6
+ data: T[];
7
+ setData: (row: number, key: string, value: string) => void;
8
+ };
9
+
10
+ export const EditingContext = createContext<EditingContextType<any>>({
11
+ data: [],
12
+ setData: (row: number, key: string, value: string) => {
13
+ console.log(row, key, value);
14
+ },
15
+ });
16
+
17
+ type EditingProviderProps<T> = PropsWithChildren<{ data: T[] }>;
18
+
19
+ export const EditingProvider = <T,>({ data, children }: EditingProviderProps<T>) =>
20
+ {
21
+ const [actual, setData] = useState<T[]>(data);
22
+
23
+ const context: EditingContextType<T> = {
24
+ data: actual,
25
+ setData: (row: number, key: string, value: string) =>
26
+ {
27
+ setData((prev) => {
28
+ const newData = [...prev];
29
+ newData[row] = {
30
+ ...newData[row],
31
+ [key]: value,
32
+ };
33
+
34
+ return newData;
35
+ });
36
+ },
37
+ };
38
+
39
+ return <EditingContext value={context}>{children}</EditingContext>;
40
+ };