@teja-app/ui 0.0.11 → 0.0.12

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 (227) hide show
  1. package/dist/hooks/index.d.ts +1 -1
  2. package/dist/hooks/index.d.ts.map +1 -1
  3. package/dist/hooks/useSidebar.d.ts +32 -1
  4. package/dist/hooks/useSidebar.d.ts.map +1 -1
  5. package/dist/index.cjs +0 -4879
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.ts +6 -3
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +0 -4863
  10. package/dist/index.js.map +1 -1
  11. package/dist/theme/components/Breadcrumbs.d.ts +53 -0
  12. package/dist/theme/components/Breadcrumbs.d.ts.map +1 -0
  13. package/dist/theme/components/Checkbox.d.ts +6 -1
  14. package/dist/theme/components/Checkbox.d.ts.map +1 -1
  15. package/dist/theme/components/OTPInput.d.ts +58 -0
  16. package/dist/theme/components/OTPInput.d.ts.map +1 -0
  17. package/dist/theme/components/PasswordInput.d.ts +48 -0
  18. package/dist/theme/components/PasswordInput.d.ts.map +1 -0
  19. package/dist/{components/PillSelector/PillSelector.types.d.ts → theme/components/PillSelector.d.ts} +21 -2
  20. package/dist/theme/components/PillSelector.d.ts.map +1 -0
  21. package/dist/theme/components/Radio.d.ts +89 -0
  22. package/dist/theme/components/Radio.d.ts.map +1 -0
  23. package/dist/theme/components/SidebarNav/SidebarNav.d.ts +20 -0
  24. package/dist/theme/components/SidebarNav/SidebarNav.d.ts.map +1 -0
  25. package/dist/theme/components/SidebarNav/SidebarNavDivider.d.ts +8 -0
  26. package/dist/theme/components/SidebarNav/SidebarNavDivider.d.ts.map +1 -0
  27. package/dist/theme/components/SidebarNav/SidebarNavGroupRow.d.ts +8 -0
  28. package/dist/theme/components/SidebarNav/SidebarNavGroupRow.d.ts.map +1 -0
  29. package/dist/theme/components/SidebarNav/SidebarNavItemRow.d.ts +8 -0
  30. package/dist/theme/components/SidebarNav/SidebarNavItemRow.d.ts.map +1 -0
  31. package/dist/theme/components/SidebarNav/index.d.ts +12 -0
  32. package/dist/theme/components/SidebarNav/index.d.ts.map +1 -0
  33. package/dist/theme/components/SidebarNav/types.d.ts +157 -0
  34. package/dist/theme/components/SidebarNav/types.d.ts.map +1 -0
  35. package/dist/theme/components/Table.d.ts +70 -0
  36. package/dist/theme/components/Table.d.ts.map +1 -0
  37. package/dist/theme/components/index.d.ts +8 -0
  38. package/dist/theme/components/index.d.ts.map +1 -1
  39. package/dist/theme/index.cjs +13092 -1017
  40. package/dist/theme/index.cjs.map +1 -1
  41. package/dist/theme/index.js +13045 -986
  42. package/dist/theme/index.js.map +1 -1
  43. package/dist/ui.css +159 -159
  44. package/dist/useSidebar-BWe09WbE.js.map +1 -1
  45. package/dist/useSidebar-d1VZFhxd.cjs.map +1 -1
  46. package/package.json +1 -1
  47. package/dist/components/Alert/Alert.d.ts +0 -13
  48. package/dist/components/Alert/Alert.d.ts.map +0 -1
  49. package/dist/components/Alert/Alert.types.d.ts +0 -17
  50. package/dist/components/Alert/Alert.types.d.ts.map +0 -1
  51. package/dist/components/Alert/index.d.ts +0 -3
  52. package/dist/components/Alert/index.d.ts.map +0 -1
  53. package/dist/components/Avatar/Avatar.d.ts +0 -13
  54. package/dist/components/Avatar/Avatar.d.ts.map +0 -1
  55. package/dist/components/Avatar/Avatar.types.d.ts +0 -18
  56. package/dist/components/Avatar/Avatar.types.d.ts.map +0 -1
  57. package/dist/components/Avatar/index.d.ts +0 -3
  58. package/dist/components/Avatar/index.d.ts.map +0 -1
  59. package/dist/components/Badge/Badge.d.ts +0 -13
  60. package/dist/components/Badge/Badge.d.ts.map +0 -1
  61. package/dist/components/Badge/Badge.types.d.ts +0 -14
  62. package/dist/components/Badge/Badge.types.d.ts.map +0 -1
  63. package/dist/components/Badge/index.d.ts +0 -3
  64. package/dist/components/Badge/index.d.ts.map +0 -1
  65. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +0 -18
  66. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts.map +0 -1
  67. package/dist/components/Breadcrumbs/Breadcrumbs.types.d.ts +0 -22
  68. package/dist/components/Breadcrumbs/Breadcrumbs.types.d.ts.map +0 -1
  69. package/dist/components/Breadcrumbs/index.d.ts +0 -3
  70. package/dist/components/Breadcrumbs/index.d.ts.map +0 -1
  71. package/dist/components/Button/Button.d.ts +0 -13
  72. package/dist/components/Button/Button.d.ts.map +0 -1
  73. package/dist/components/Button/Button.types.d.ts +0 -18
  74. package/dist/components/Button/Button.types.d.ts.map +0 -1
  75. package/dist/components/Button/index.d.ts +0 -3
  76. package/dist/components/Button/index.d.ts.map +0 -1
  77. package/dist/components/Card/Card.d.ts +0 -18
  78. package/dist/components/Card/Card.d.ts.map +0 -1
  79. package/dist/components/Card/Card.types.d.ts +0 -16
  80. package/dist/components/Card/Card.types.d.ts.map +0 -1
  81. package/dist/components/Card/index.d.ts +0 -3
  82. package/dist/components/Card/index.d.ts.map +0 -1
  83. package/dist/components/Checkbox/Checkbox.d.ts +0 -13
  84. package/dist/components/Checkbox/Checkbox.d.ts.map +0 -1
  85. package/dist/components/Checkbox/Checkbox.types.d.ts +0 -21
  86. package/dist/components/Checkbox/Checkbox.types.d.ts.map +0 -1
  87. package/dist/components/Checkbox/index.d.ts +0 -3
  88. package/dist/components/Checkbox/index.d.ts.map +0 -1
  89. package/dist/components/Combobox/Combobox.d.ts +0 -24
  90. package/dist/components/Combobox/Combobox.d.ts.map +0 -1
  91. package/dist/components/Combobox/Combobox.types.d.ts +0 -43
  92. package/dist/components/Combobox/Combobox.types.d.ts.map +0 -1
  93. package/dist/components/Combobox/index.d.ts +0 -3
  94. package/dist/components/Combobox/index.d.ts.map +0 -1
  95. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +0 -23
  96. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts.map +0 -1
  97. package/dist/components/ConfirmDialog/ConfirmDialog.types.d.ts +0 -24
  98. package/dist/components/ConfirmDialog/ConfirmDialog.types.d.ts.map +0 -1
  99. package/dist/components/ConfirmDialog/index.d.ts +0 -3
  100. package/dist/components/ConfirmDialog/index.d.ts.map +0 -1
  101. package/dist/components/DateInput/DateInput.d.ts +0 -14
  102. package/dist/components/DateInput/DateInput.d.ts.map +0 -1
  103. package/dist/components/DateInput/DateInput.types.d.ts +0 -39
  104. package/dist/components/DateInput/DateInput.types.d.ts.map +0 -1
  105. package/dist/components/DateInput/index.d.ts +0 -3
  106. package/dist/components/DateInput/index.d.ts.map +0 -1
  107. package/dist/components/Drawer/Drawer.d.ts +0 -27
  108. package/dist/components/Drawer/Drawer.d.ts.map +0 -1
  109. package/dist/components/Drawer/Drawer.types.d.ts +0 -25
  110. package/dist/components/Drawer/Drawer.types.d.ts.map +0 -1
  111. package/dist/components/Drawer/index.d.ts +0 -3
  112. package/dist/components/Drawer/index.d.ts.map +0 -1
  113. package/dist/components/EmptyState/EmptyState.d.ts +0 -34
  114. package/dist/components/EmptyState/EmptyState.d.ts.map +0 -1
  115. package/dist/components/EmptyState/EmptyState.types.d.ts +0 -19
  116. package/dist/components/EmptyState/EmptyState.types.d.ts.map +0 -1
  117. package/dist/components/EmptyState/index.d.ts +0 -3
  118. package/dist/components/EmptyState/index.d.ts.map +0 -1
  119. package/dist/components/Input/Input.d.ts +0 -13
  120. package/dist/components/Input/Input.d.ts.map +0 -1
  121. package/dist/components/Input/Input.types.d.ts +0 -20
  122. package/dist/components/Input/Input.types.d.ts.map +0 -1
  123. package/dist/components/Input/index.d.ts +0 -3
  124. package/dist/components/Input/index.d.ts.map +0 -1
  125. package/dist/components/Modal/Modal.d.ts +0 -28
  126. package/dist/components/Modal/Modal.d.ts.map +0 -1
  127. package/dist/components/Modal/Modal.types.d.ts +0 -29
  128. package/dist/components/Modal/Modal.types.d.ts.map +0 -1
  129. package/dist/components/Modal/index.d.ts +0 -3
  130. package/dist/components/Modal/index.d.ts.map +0 -1
  131. package/dist/components/MultiSelect/MultiSelect.d.ts +0 -26
  132. package/dist/components/MultiSelect/MultiSelect.d.ts.map +0 -1
  133. package/dist/components/MultiSelect/MultiSelect.types.d.ts +0 -51
  134. package/dist/components/MultiSelect/MultiSelect.types.d.ts.map +0 -1
  135. package/dist/components/MultiSelect/index.d.ts +0 -3
  136. package/dist/components/MultiSelect/index.d.ts.map +0 -1
  137. package/dist/components/OTPInput/OTPInput.d.ts +0 -22
  138. package/dist/components/OTPInput/OTPInput.d.ts.map +0 -1
  139. package/dist/components/OTPInput/OTPInput.types.d.ts +0 -19
  140. package/dist/components/OTPInput/OTPInput.types.d.ts.map +0 -1
  141. package/dist/components/OTPInput/index.d.ts +0 -3
  142. package/dist/components/OTPInput/index.d.ts.map +0 -1
  143. package/dist/components/Pagination/Pagination.d.ts +0 -35
  144. package/dist/components/Pagination/Pagination.d.ts.map +0 -1
  145. package/dist/components/Pagination/Pagination.types.d.ts +0 -31
  146. package/dist/components/Pagination/Pagination.types.d.ts.map +0 -1
  147. package/dist/components/Pagination/index.d.ts +0 -3
  148. package/dist/components/Pagination/index.d.ts.map +0 -1
  149. package/dist/components/PasswordInput/PasswordInput.d.ts +0 -12
  150. package/dist/components/PasswordInput/PasswordInput.d.ts.map +0 -1
  151. package/dist/components/PasswordInput/PasswordInput.types.d.ts +0 -16
  152. package/dist/components/PasswordInput/PasswordInput.types.d.ts.map +0 -1
  153. package/dist/components/PasswordInput/index.d.ts +0 -3
  154. package/dist/components/PasswordInput/index.d.ts.map +0 -1
  155. package/dist/components/PillSelector/PillSelector.d.ts +0 -16
  156. package/dist/components/PillSelector/PillSelector.d.ts.map +0 -1
  157. package/dist/components/PillSelector/PillSelector.types.d.ts.map +0 -1
  158. package/dist/components/PillSelector/index.d.ts +0 -3
  159. package/dist/components/PillSelector/index.d.ts.map +0 -1
  160. package/dist/components/Radio/Radio.d.ts +0 -12
  161. package/dist/components/Radio/Radio.d.ts.map +0 -1
  162. package/dist/components/Radio/Radio.types.d.ts +0 -49
  163. package/dist/components/Radio/Radio.types.d.ts.map +0 -1
  164. package/dist/components/Radio/RadioGroup.d.ts +0 -23
  165. package/dist/components/Radio/RadioGroup.d.ts.map +0 -1
  166. package/dist/components/Radio/index.d.ts +0 -4
  167. package/dist/components/Radio/index.d.ts.map +0 -1
  168. package/dist/components/Select/Select.d.ts +0 -22
  169. package/dist/components/Select/Select.d.ts.map +0 -1
  170. package/dist/components/Select/Select.types.d.ts +0 -42
  171. package/dist/components/Select/Select.types.d.ts.map +0 -1
  172. package/dist/components/Select/index.d.ts +0 -3
  173. package/dist/components/Select/index.d.ts.map +0 -1
  174. package/dist/components/Sidebar/Sidebar.d.ts +0 -36
  175. package/dist/components/Sidebar/Sidebar.d.ts.map +0 -1
  176. package/dist/components/Sidebar/Sidebar.types.d.ts +0 -200
  177. package/dist/components/Sidebar/Sidebar.types.d.ts.map +0 -1
  178. package/dist/components/Sidebar/SidebarDivider.d.ts +0 -12
  179. package/dist/components/Sidebar/SidebarDivider.d.ts.map +0 -1
  180. package/dist/components/Sidebar/SidebarGroup.d.ts +0 -26
  181. package/dist/components/Sidebar/SidebarGroup.d.ts.map +0 -1
  182. package/dist/components/Sidebar/SidebarItem.d.ts +0 -23
  183. package/dist/components/Sidebar/SidebarItem.d.ts.map +0 -1
  184. package/dist/components/Sidebar/index.d.ts +0 -9
  185. package/dist/components/Sidebar/index.d.ts.map +0 -1
  186. package/dist/components/Skeleton/Skeleton.d.ts +0 -22
  187. package/dist/components/Skeleton/Skeleton.d.ts.map +0 -1
  188. package/dist/components/Skeleton/Skeleton.types.d.ts +0 -19
  189. package/dist/components/Skeleton/Skeleton.types.d.ts.map +0 -1
  190. package/dist/components/Skeleton/index.d.ts +0 -3
  191. package/dist/components/Skeleton/index.d.ts.map +0 -1
  192. package/dist/components/Spinner/Spinner.d.ts +0 -13
  193. package/dist/components/Spinner/Spinner.d.ts.map +0 -1
  194. package/dist/components/Spinner/Spinner.types.d.ts +0 -14
  195. package/dist/components/Spinner/Spinner.types.d.ts.map +0 -1
  196. package/dist/components/Spinner/index.d.ts +0 -3
  197. package/dist/components/Spinner/index.d.ts.map +0 -1
  198. package/dist/components/Table/Table.d.ts +0 -44
  199. package/dist/components/Table/Table.d.ts.map +0 -1
  200. package/dist/components/Table/Table.types.d.ts +0 -33
  201. package/dist/components/Table/Table.types.d.ts.map +0 -1
  202. package/dist/components/Table/index.d.ts +0 -3
  203. package/dist/components/Table/index.d.ts.map +0 -1
  204. package/dist/components/Tabs/Tabs.d.ts +0 -43
  205. package/dist/components/Tabs/Tabs.d.ts.map +0 -1
  206. package/dist/components/Tabs/Tabs.types.d.ts +0 -42
  207. package/dist/components/Tabs/Tabs.types.d.ts.map +0 -1
  208. package/dist/components/Tabs/index.d.ts +0 -3
  209. package/dist/components/Tabs/index.d.ts.map +0 -1
  210. package/dist/components/Textarea/Textarea.d.ts +0 -13
  211. package/dist/components/Textarea/Textarea.d.ts.map +0 -1
  212. package/dist/components/Textarea/Textarea.types.d.ts +0 -22
  213. package/dist/components/Textarea/Textarea.types.d.ts.map +0 -1
  214. package/dist/components/Textarea/index.d.ts +0 -3
  215. package/dist/components/Textarea/index.d.ts.map +0 -1
  216. package/dist/components/Toggle/Toggle.d.ts +0 -20
  217. package/dist/components/Toggle/Toggle.d.ts.map +0 -1
  218. package/dist/components/Toggle/Toggle.types.d.ts +0 -22
  219. package/dist/components/Toggle/Toggle.types.d.ts.map +0 -1
  220. package/dist/components/Toggle/index.d.ts +0 -3
  221. package/dist/components/Toggle/index.d.ts.map +0 -1
  222. package/dist/components/index.d.ts +0 -32
  223. package/dist/components/index.d.ts.map +0 -1
  224. package/dist/style-D6av97Pw.cjs +0 -10406
  225. package/dist/style-D6av97Pw.cjs.map +0 -1
  226. package/dist/style-DyXPy-7b.js +0 -10392
  227. package/dist/style-DyXPy-7b.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -2,4847 +2,6 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const useSidebar = require("./useSidebar-d1VZFhxd.cjs");
4
4
  const utils_index = require("./utils/index.cjs");
5
- const jsxRuntime = require("react/jsx-runtime");
6
- const React = require("react");
7
- const style = require("./style-D6av97Pw.cjs");
8
- const ReactDOM = require("react-dom");
9
- function _interopNamespaceDefault(e2) {
10
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
- if (e2) {
12
- for (const k in e2) {
13
- if (k !== "default") {
14
- const d2 = Object.getOwnPropertyDescriptor(e2, k);
15
- Object.defineProperty(n, k, d2.get ? d2 : {
16
- enumerable: true,
17
- get: () => e2[k]
18
- });
19
- }
20
- }
21
- }
22
- n.default = e2;
23
- return Object.freeze(n);
24
- }
25
- const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
26
- const variantStyles$5 = {
27
- primary: [
28
- // Light mode
29
- "bg-primary-800 text-white border border-gold-500/40",
30
- "hover:bg-primary-900 hover:border-gold-500/60",
31
- "focus:ring-gold-500/20",
32
- // Dark mode
33
- "dark:bg-gold-500 dark:text-primary-900 dark:border-gold-400",
34
- "dark:hover:bg-gold-400 dark:hover:border-gold-300",
35
- "dark:focus:ring-gold-400/30"
36
- ].join(" "),
37
- secondary: [
38
- // Light mode
39
- "bg-white text-primary-800 border border-primary-300",
40
- "hover:bg-primary-50 hover:border-primary-400",
41
- "focus:ring-primary-500/20",
42
- // Dark mode
43
- "dark:bg-primary-800 dark:text-primary-100 dark:border-primary-600",
44
- "dark:hover:bg-primary-700 dark:hover:border-primary-500",
45
- "dark:focus:ring-primary-400/30"
46
- ].join(" "),
47
- ghost: [
48
- // Light mode
49
- "text-primary-600 hover:text-primary-800 hover:bg-primary-50",
50
- "focus:ring-primary-500/20",
51
- // Dark mode
52
- "dark:text-primary-300 dark:hover:text-primary-100 dark:hover:bg-primary-800",
53
- "dark:focus:ring-primary-400/30"
54
- ].join(" "),
55
- danger: [
56
- // Light mode
57
- "bg-error text-white border border-error",
58
- "hover:bg-error/90",
59
- "focus:ring-error/20",
60
- // Dark mode (stays similar, just adjust opacity)
61
- "dark:bg-error dark:border-error/80",
62
- "dark:hover:bg-error/80",
63
- "dark:focus:ring-error/30"
64
- ].join(" ")
65
- };
66
- const sizeStyles$d = {
67
- sm: "px-3 py-1.5 text-sm h-8",
68
- md: "px-4 py-2 text-base h-10",
69
- lg: "px-6 py-3 text-lg h-12"
70
- };
71
- const Button = React.forwardRef(
72
- ({
73
- variant = "primary",
74
- size = "md",
75
- loading = false,
76
- disabled = false,
77
- icon,
78
- iconPosition = "left",
79
- fullWidth = false,
80
- children,
81
- className,
82
- ...props
83
- }, ref) => {
84
- return /* @__PURE__ */ jsxRuntime.jsx(
85
- "button",
86
- {
87
- ref,
88
- className: utils_index.cn(
89
- // Base styles
90
- "inline-flex items-center justify-center gap-2 font-medium rounded-md",
91
- "transition-colors duration-normal",
92
- "focus:outline-none focus:ring-2 focus:ring-offset-2",
93
- "dark:focus:ring-offset-primary-900",
94
- "disabled:opacity-50 disabled:cursor-not-allowed",
95
- // Variant styles
96
- variantStyles$5[variant],
97
- // Size styles
98
- sizeStyles$d[size],
99
- // Width styles
100
- fullWidth && "w-full",
101
- // Custom className (allows override)
102
- className
103
- ),
104
- disabled: disabled || loading,
105
- ...props,
106
- children: loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
107
- /* @__PURE__ */ jsxRuntime.jsxs(
108
- "svg",
109
- {
110
- className: "animate-spin h-5 w-5",
111
- fill: "none",
112
- viewBox: "0 0 24 24",
113
- xmlns: "http://www.w3.org/2000/svg",
114
- "aria-hidden": "true",
115
- children: [
116
- /* @__PURE__ */ jsxRuntime.jsx(
117
- "circle",
118
- {
119
- className: "opacity-25",
120
- cx: "12",
121
- cy: "12",
122
- r: "10",
123
- stroke: "currentColor",
124
- strokeWidth: "4"
125
- }
126
- ),
127
- /* @__PURE__ */ jsxRuntime.jsx(
128
- "path",
129
- {
130
- className: "opacity-75",
131
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
132
- fill: "currentColor"
133
- }
134
- )
135
- ]
136
- }
137
- ),
138
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading..." })
139
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
140
- icon && iconPosition === "left" && icon,
141
- children,
142
- icon && iconPosition === "right" && icon
143
- ] })
144
- }
145
- );
146
- }
147
- );
148
- Button.displayName = "Button";
149
- const sizeStyles$c = {
150
- xs: "h-3 w-3",
151
- // 12px
152
- sm: "h-4 w-4",
153
- // 16px
154
- md: "h-5 w-5",
155
- // 20px
156
- lg: "h-6 w-6"
157
- // 24px
158
- };
159
- const colorStyles = {
160
- current: "text-current",
161
- primary: "text-primary-600 dark:text-primary-400",
162
- white: "text-white",
163
- gold: "text-gold-500 dark:text-gold-400"
164
- };
165
- const Spinner = React.forwardRef(
166
- ({
167
- size = "md",
168
- color = "current",
169
- label = "Loading",
170
- className,
171
- testId,
172
- ...props
173
- }, ref) => {
174
- return /* @__PURE__ */ jsxRuntime.jsxs(
175
- "svg",
176
- {
177
- ref,
178
- className: utils_index.cn(
179
- "animate-spin",
180
- sizeStyles$c[size],
181
- colorStyles[color],
182
- className
183
- ),
184
- fill: "none",
185
- viewBox: "0 0 24 24",
186
- xmlns: "http://www.w3.org/2000/svg",
187
- role: "status",
188
- "aria-label": label,
189
- "data-testid": testId,
190
- ...props,
191
- children: [
192
- /* @__PURE__ */ jsxRuntime.jsx(
193
- "circle",
194
- {
195
- className: "opacity-25",
196
- cx: "12",
197
- cy: "12",
198
- r: "10",
199
- stroke: "currentColor",
200
- strokeWidth: "4"
201
- }
202
- ),
203
- /* @__PURE__ */ jsxRuntime.jsx(
204
- "path",
205
- {
206
- className: "opacity-75",
207
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
208
- fill: "currentColor"
209
- }
210
- )
211
- ]
212
- }
213
- );
214
- }
215
- );
216
- Spinner.displayName = "Spinner";
217
- const Input = React.forwardRef(
218
- ({
219
- label,
220
- error,
221
- helperText,
222
- leftIcon,
223
- rightIcon,
224
- fullWidth = false,
225
- className,
226
- id,
227
- required,
228
- disabled,
229
- isLoading = false,
230
- testId,
231
- ...props
232
- }, ref) => {
233
- const inputId = id || label?.toLowerCase().replace(/\s+/g, "-");
234
- const hasError = !!error;
235
- const errorId = hasError ? `${inputId}-error` : void 0;
236
- const showRightIcon = rightIcon || isLoading;
237
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn(fullWidth ? "w-full" : "w-auto"), "data-testid": testId, children: [
238
- label && /* @__PURE__ */ jsxRuntime.jsxs(
239
- "label",
240
- {
241
- htmlFor: inputId,
242
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
243
- "data-testid": testId ? `${testId}-label` : void 0,
244
- children: [
245
- label,
246
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
247
- ]
248
- }
249
- ),
250
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
251
- leftIcon && /* @__PURE__ */ jsxRuntime.jsx(
252
- "div",
253
- {
254
- className: "pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-primary-400 dark:text-primary-500",
255
- "data-testid": testId ? `${testId}-left-icon` : void 0,
256
- children: leftIcon
257
- }
258
- ),
259
- /* @__PURE__ */ jsxRuntime.jsx(
260
- "input",
261
- {
262
- ref,
263
- id: inputId,
264
- required,
265
- disabled,
266
- "aria-label": !label ? props.placeholder || "Input" : void 0,
267
- "aria-invalid": hasError ? "true" : void 0,
268
- "aria-describedby": errorId,
269
- "data-testid": testId ? `${testId}-input` : void 0,
270
- className: utils_index.cn(
271
- // Base styles - Light mode
272
- "block w-full rounded-md border bg-white px-4 py-2.5 text-sm text-primary-900",
273
- "transition-colors duration-normal",
274
- "placeholder:text-primary-400",
275
- "focus:outline-none focus:ring-2",
276
- "disabled:cursor-not-allowed disabled:bg-primary-50 disabled:text-primary-500",
277
- // Base styles - Dark mode
278
- "dark:bg-primary-800 dark:text-primary-100",
279
- "dark:placeholder:text-primary-500",
280
- "dark:disabled:bg-primary-900 dark:disabled:text-primary-600",
281
- // Border and focus styles
282
- hasError ? "border-error focus:border-error focus:ring-error/20 dark:border-error/70 dark:focus:ring-error/30" : "border-primary-300 focus:border-gold-500 focus:ring-gold-500/20 dark:border-primary-600 dark:focus:border-gold-400 dark:focus:ring-gold-400/30",
283
- // Icon padding
284
- leftIcon && "pl-11",
285
- showRightIcon && "pr-11",
286
- // Custom className
287
- className
288
- ),
289
- ...props
290
- }
291
- ),
292
- showRightIcon && /* @__PURE__ */ jsxRuntime.jsx(
293
- "div",
294
- {
295
- className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-primary-400 dark:text-primary-500",
296
- "data-testid": testId ? `${testId}-right-icon` : void 0,
297
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary" }) : rightIcon
298
- }
299
- )
300
- ] }),
301
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
302
- "p",
303
- {
304
- id: errorId,
305
- role: hasError ? "alert" : void 0,
306
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
307
- className: utils_index.cn(
308
- "mt-1.5 text-sm",
309
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
310
- ),
311
- children: error || helperText
312
- }
313
- )
314
- ] });
315
- }
316
- );
317
- Input.displayName = "Input";
318
- const EyeIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
319
- "svg",
320
- {
321
- className: "h-5 w-5",
322
- fill: "none",
323
- stroke: "currentColor",
324
- viewBox: "0 0 24 24",
325
- "aria-hidden": "true",
326
- children: [
327
- /* @__PURE__ */ jsxRuntime.jsx(
328
- "path",
329
- {
330
- strokeLinecap: "round",
331
- strokeLinejoin: "round",
332
- strokeWidth: 1.5,
333
- d: "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
334
- }
335
- ),
336
- /* @__PURE__ */ jsxRuntime.jsx(
337
- "path",
338
- {
339
- strokeLinecap: "round",
340
- strokeLinejoin: "round",
341
- strokeWidth: 1.5,
342
- d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
343
- }
344
- )
345
- ]
346
- }
347
- );
348
- const EyeSlashIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
349
- "svg",
350
- {
351
- className: "h-5 w-5",
352
- fill: "none",
353
- stroke: "currentColor",
354
- viewBox: "0 0 24 24",
355
- "aria-hidden": "true",
356
- children: /* @__PURE__ */ jsxRuntime.jsx(
357
- "path",
358
- {
359
- strokeLinecap: "round",
360
- strokeLinejoin: "round",
361
- strokeWidth: 1.5,
362
- d: "M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
363
- }
364
- )
365
- }
366
- );
367
- function getPasswordStrength(password) {
368
- if (!password) {
369
- return { strength: 0, label: "", color: "" };
370
- }
371
- let score = 0;
372
- if (password.length >= 8) score++;
373
- if (password.length >= 12) score++;
374
- if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score++;
375
- if (/\d/.test(password)) score++;
376
- if (/[^a-zA-Z0-9]/.test(password)) score++;
377
- if (score <= 2) {
378
- return { strength: 33, label: "Weak", color: "bg-error" };
379
- } else if (score <= 3) {
380
- return { strength: 66, label: "Medium", color: "bg-warning" };
381
- } else {
382
- return { strength: 100, label: "Strong", color: "bg-success" };
383
- }
384
- }
385
- const PasswordInput = React.forwardRef(
386
- ({ showStrengthIndicator = false, value, className, testId, ...props }, ref) => {
387
- const [showPassword, setShowPassword] = React.useState(false);
388
- const togglePasswordVisibility = () => {
389
- setShowPassword((prev) => !prev);
390
- };
391
- const passwordValue = typeof value === "string" ? value : "";
392
- const strength = showStrengthIndicator ? getPasswordStrength(passwordValue) : null;
393
- const toggleButton = /* @__PURE__ */ jsxRuntime.jsx(
394
- "button",
395
- {
396
- type: "button",
397
- tabIndex: -1,
398
- onClick: togglePasswordVisibility,
399
- className: utils_index.cn(
400
- "pointer-events-auto cursor-pointer",
401
- "text-primary-400 hover:text-primary-600",
402
- "dark:text-primary-500 dark:hover:text-primary-300"
403
- ),
404
- "aria-label": showPassword ? "Hide password" : "Show password",
405
- "data-testid": testId ? `${testId}-toggle-button` : void 0,
406
- children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(EyeSlashIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeIcon, {})
407
- }
408
- );
409
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn("w-full", className), "data-testid": testId, children: [
410
- /* @__PURE__ */ jsxRuntime.jsx(
411
- Input,
412
- {
413
- ...props,
414
- ref,
415
- type: showPassword ? "text" : "password",
416
- value,
417
- rightIcon: toggleButton,
418
- testId: testId ? `${testId}-input` : void 0
419
- }
420
- ),
421
- showStrengthIndicator && passwordValue && strength && strength.label && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2", children: [
422
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
423
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-primary-500 dark:text-primary-400", children: "Password strength:" }),
424
- /* @__PURE__ */ jsxRuntime.jsx(
425
- "span",
426
- {
427
- className: utils_index.cn(
428
- "text-xs font-medium",
429
- strength.label === "Weak" && "text-error",
430
- strength.label === "Medium" && "text-warning",
431
- strength.label === "Strong" && "text-success"
432
- ),
433
- children: strength.label
434
- }
435
- )
436
- ] }),
437
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-full bg-primary-200 dark:bg-primary-700 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
438
- "div",
439
- {
440
- className: utils_index.cn("h-full transition-all duration-300", strength.color),
441
- style: { width: `${strength.strength}%` }
442
- }
443
- ) })
444
- ] })
445
- ] });
446
- }
447
- );
448
- PasswordInput.displayName = "PasswordInput";
449
- const Textarea = React.forwardRef(
450
- ({
451
- label,
452
- error,
453
- helperText,
454
- fullWidth = false,
455
- rows = 4,
456
- showCharCount = false,
457
- autoResize = false,
458
- className,
459
- id,
460
- required,
461
- disabled,
462
- maxLength,
463
- value,
464
- defaultValue,
465
- onChange,
466
- isLoading = false,
467
- testId,
468
- ...props
469
- }, ref) => {
470
- const textareaId = id || label?.toLowerCase().replace(/\s+/g, "-");
471
- const hasError = !!error;
472
- const errorId = hasError ? `${textareaId}-error` : void 0;
473
- const internalRef = React.useRef(null);
474
- const combinedRef = React.useCallback(
475
- (node) => {
476
- internalRef.current = node;
477
- if (typeof ref === "function") {
478
- ref(node);
479
- } else if (ref) {
480
- ref.current = node;
481
- }
482
- },
483
- [ref]
484
- );
485
- const currentValue = value !== void 0 ? String(value) : "";
486
- const charCount = currentValue.length;
487
- const adjustHeight = React.useCallback(() => {
488
- const textarea = internalRef.current;
489
- if (textarea && autoResize) {
490
- textarea.style.height = "auto";
491
- textarea.style.height = `${textarea.scrollHeight}px`;
492
- }
493
- }, [autoResize]);
494
- const handleChange = React.useCallback(
495
- (e2) => {
496
- onChange?.(e2);
497
- if (autoResize) {
498
- adjustHeight();
499
- }
500
- },
501
- [onChange, autoResize, adjustHeight]
502
- );
503
- React.useEffect(() => {
504
- if (autoResize) {
505
- adjustHeight();
506
- }
507
- }, [autoResize, adjustHeight, value, defaultValue]);
508
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn(fullWidth ? "w-full" : "w-auto"), "data-testid": testId, children: [
509
- label && /* @__PURE__ */ jsxRuntime.jsxs(
510
- "label",
511
- {
512
- htmlFor: textareaId,
513
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
514
- "data-testid": testId ? `${testId}-label` : void 0,
515
- children: [
516
- label,
517
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
518
- ]
519
- }
520
- ),
521
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
522
- /* @__PURE__ */ jsxRuntime.jsx(
523
- "textarea",
524
- {
525
- ref: combinedRef,
526
- id: textareaId,
527
- rows: autoResize ? 1 : rows,
528
- required,
529
- disabled,
530
- maxLength,
531
- value,
532
- defaultValue,
533
- "aria-label": !label ? props.placeholder || "Text area" : void 0,
534
- "aria-invalid": hasError ? "true" : void 0,
535
- "aria-describedby": errorId,
536
- onChange: handleChange,
537
- "data-testid": testId ? `${testId}-textarea` : void 0,
538
- className: utils_index.cn(
539
- // Base styles - Light mode
540
- "block w-full rounded-md border bg-white px-4 py-2.5 text-sm text-primary-900",
541
- "transition-colors duration-normal",
542
- "placeholder:text-primary-400",
543
- "focus:outline-none focus:ring-2",
544
- "disabled:cursor-not-allowed disabled:bg-primary-50 disabled:text-primary-500",
545
- "resize-none",
546
- // Base styles - Dark mode
547
- "dark:bg-primary-800 dark:text-primary-100",
548
- "dark:placeholder:text-primary-500",
549
- "dark:disabled:bg-primary-900 dark:disabled:text-primary-600",
550
- // Auto-resize specific
551
- autoResize && "overflow-hidden",
552
- // Border and focus styles
553
- hasError ? "border-error focus:border-error focus:ring-error/20 dark:border-error/70 dark:focus:ring-error/30" : "border-primary-300 focus:border-gold-500 focus:ring-gold-500/20 dark:border-primary-600 dark:focus:border-gold-400 dark:focus:ring-gold-400/30",
554
- // Custom className
555
- className
556
- ),
557
- ...props
558
- }
559
- ),
560
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-2.5 right-2.5", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary", label: "Saving..." }) })
561
- ] }),
562
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 flex justify-between", children: [
563
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
564
- "p",
565
- {
566
- id: errorId,
567
- role: hasError ? "alert" : void 0,
568
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
569
- className: utils_index.cn(
570
- "text-sm",
571
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
572
- ),
573
- children: error || helperText
574
- }
575
- ),
576
- !error && !helperText && /* @__PURE__ */ jsxRuntime.jsx("span", {}),
577
- showCharCount && maxLength && /* @__PURE__ */ jsxRuntime.jsxs(
578
- "span",
579
- {
580
- className: utils_index.cn(
581
- "text-sm",
582
- charCount >= maxLength ? "text-error" : "text-primary-400 dark:text-primary-500"
583
- ),
584
- children: [
585
- charCount,
586
- "/",
587
- maxLength
588
- ]
589
- }
590
- )
591
- ] })
592
- ] });
593
- }
594
- );
595
- Textarea.displayName = "Textarea";
596
- let e = React.createContext(() => {
597
- });
598
- function C$1({ value: t, children: o }) {
599
- return React.createElement(e.Provider, { value: t }, o);
600
- }
601
- function a$2(o, r = typeof document != "undefined" ? document.defaultView : null, t) {
602
- let n = style.I(o, "escape");
603
- style.E(r, "keydown", (e2) => {
604
- n && (e2.defaultPrevented || e2.key === style.o.Escape && t(e2));
605
- });
606
- }
607
- function f$1() {
608
- var t;
609
- let [e2] = React.useState(() => typeof window != "undefined" && typeof window.matchMedia == "function" ? window.matchMedia("(pointer: coarse)") : null), [o, c2] = React.useState((t = e2 == null ? void 0 : e2.matches) != null ? t : false);
610
- return style.n(() => {
611
- if (!e2) return;
612
- function n(r) {
613
- c2(r.matches);
614
- }
615
- return e2.addEventListener("change", n), () => e2.removeEventListener("change", n);
616
- }, [e2]), o;
617
- }
618
- function S({ defaultContainers: l = [], portals: n, mainTreeNode: o } = {}) {
619
- let c2 = style.o$1(() => {
620
- var r, u2;
621
- let i = style.l(o), t = [];
622
- for (let e2 of l) e2 !== null && (style.t(e2) ? t.push(e2) : "current" in e2 && style.t(e2.current) && t.push(e2.current));
623
- if (n != null && n.current) for (let e2 of n.current) t.push(e2);
624
- for (let e2 of (r = i == null ? void 0 : i.querySelectorAll("html > *, body > *")) != null ? r : []) e2 !== document.body && e2 !== document.head && style.t(e2) && e2.id !== "headlessui-portal-root" && (o && (e2.contains(o) || e2.contains((u2 = o == null ? void 0 : o.getRootNode()) == null ? void 0 : u2.host)) || t.some((E2) => e2.contains(E2)) || t.push(e2));
625
- return t;
626
- });
627
- return { resolveContainers: c2, contains: style.o$1((i) => c2().some((t) => t.contains(i))) };
628
- }
629
- let d = React.createContext(null);
630
- function j({ children: l, node: n }) {
631
- let [o, c2] = React.useState(null), i = x$1(n != null ? n : o);
632
- return React.createElement(d.Provider, { value: i }, l, i === null && React.createElement(style.f, { features: style.s.Hidden, ref: (t) => {
633
- var r, u2;
634
- if (t) {
635
- for (let e2 of (u2 = (r = style.l(t)) == null ? void 0 : r.querySelectorAll("html > *, body > *")) != null ? u2 : []) if (e2 !== document.body && e2 !== document.head && style.t(e2) && e2 != null && e2.contains(t)) {
636
- c2(e2);
637
- break;
638
- }
639
- }
640
- } }));
641
- }
642
- function x$1(l = null) {
643
- var n;
644
- return (n = React.useContext(d)) != null ? n : l;
645
- }
646
- var a$1 = ((r) => (r[r.Forwards = 0] = "Forwards", r[r.Backwards = 1] = "Backwards", r))(a$1 || {});
647
- function u() {
648
- let e2 = React.useRef(0);
649
- return style.s$1(true, "keydown", (r) => {
650
- r.key === "Tab" && (e2.current = r.shiftKey ? 1 : 0);
651
- }, true), e2;
652
- }
653
- function x(o) {
654
- if (!o) return /* @__PURE__ */ new Set();
655
- if (typeof o == "function") return new Set(o());
656
- let t = /* @__PURE__ */ new Set();
657
- for (let e2 of o.current) style.t(e2.current) && t.add(e2.current);
658
- return t;
659
- }
660
- let $ = "div";
661
- var G = ((n) => (n[n.None = 0] = "None", n[n.InitialFocus = 1] = "InitialFocus", n[n.TabLock = 2] = "TabLock", n[n.FocusLock = 4] = "FocusLock", n[n.RestoreFocus = 8] = "RestoreFocus", n[n.AutoFocus = 16] = "AutoFocus", n))(G || {});
662
- function w$1(o, t) {
663
- let e2 = React.useRef(null), r = style.y(e2, t), { initialFocus: u$1, initialFocusFallback: a2, containers: n, features: s2 = 15, ...f2 } = o;
664
- style.l$1() || (s2 = 0);
665
- let l = style.u(e2.current);
666
- re(s2, { ownerDocument: l });
667
- let T = ne(s2, { ownerDocument: l, container: e2, initialFocus: u$1, initialFocusFallback: a2 });
668
- oe(s2, { ownerDocument: l, container: e2, containers: n, previousActiveElement: T });
669
- let g = u(), A = style.o$1((c2) => {
670
- if (!style.n$1(e2.current)) return;
671
- let E2 = e2.current;
672
- ((V2) => V2())(() => {
673
- style.u$1(g.current, { [a$1.Forwards]: () => {
674
- style.v(E2, style.T.First, { skipElements: [c2.relatedTarget, a2] });
675
- }, [a$1.Backwards]: () => {
676
- style.v(E2, style.T.Last, { skipElements: [c2.relatedTarget, a2] });
677
- } });
678
- });
679
- }), v = style.I(!!(s2 & 2), "focus-trap#tab-lock"), N = style.p(), b2 = React.useRef(false), k = { ref: r, onKeyDown(c2) {
680
- c2.key == "Tab" && (b2.current = true, N.requestAnimationFrame(() => {
681
- b2.current = false;
682
- }));
683
- }, onBlur(c2) {
684
- if (!(s2 & 4)) return;
685
- let E2 = x(n);
686
- style.n$1(e2.current) && E2.add(e2.current);
687
- let L = c2.relatedTarget;
688
- style.i(L) && L.dataset.headlessuiFocusGuard !== "true" && (I(E2, L) || (b2.current ? style.v(e2.current, style.u$1(g.current, { [a$1.Forwards]: () => style.T.Next, [a$1.Backwards]: () => style.T.Previous }) | style.T.WrapAround, { relativeTo: c2.target }) : style.i(c2.target) && style.w(c2.target)));
689
- } }, B = style.K();
690
- return React.createElement(React.Fragment, null, v && React.createElement(style.f, { as: "button", type: "button", "data-headlessui-focus-guard": true, onFocus: A, features: style.s.Focusable }), B({ ourProps: k, theirProps: f2, defaultTag: $, name: "FocusTrap" }), v && React.createElement(style.f, { as: "button", type: "button", "data-headlessui-focus-guard": true, onFocus: A, features: style.s.Focusable }));
691
- }
692
- let ee = style.Y(w$1), ge = Object.assign(ee, { features: G });
693
- function te(o = true) {
694
- let t = React.useRef(style.n$2.slice());
695
- return style.m(([e2], [r]) => {
696
- r === true && e2 === false && style.t$1(() => {
697
- t.current.splice(0);
698
- }), r === false && e2 === true && (t.current = style.n$2.slice());
699
- }, [o, style.n$2, t]), style.o$1(() => {
700
- var e2;
701
- return (e2 = t.current.find((r) => r != null && r.isConnected)) != null ? e2 : null;
702
- });
703
- }
704
- function re(o, { ownerDocument: t }) {
705
- let e2 = !!(o & 8), r = te(e2);
706
- style.m(() => {
707
- e2 || style.d(t == null ? void 0 : t.body) && style.w(r());
708
- }, [e2]), style.c(() => {
709
- e2 && style.w(r());
710
- });
711
- }
712
- function ne(o, { ownerDocument: t, container: e2, initialFocus: r, initialFocusFallback: u2 }) {
713
- let a2 = React.useRef(null), n = style.I(!!(o & 1), "focus-trap#initial-focus"), s2 = style.f$1();
714
- return style.m(() => {
715
- if (o === 0) return;
716
- if (!n) {
717
- u2 != null && u2.current && style.w(u2.current);
718
- return;
719
- }
720
- let f2 = e2.current;
721
- f2 && style.t$1(() => {
722
- if (!s2.current) return;
723
- let l = t == null ? void 0 : t.activeElement;
724
- if (r != null && r.current) {
725
- if ((r == null ? void 0 : r.current) === l) {
726
- a2.current = l;
727
- return;
728
- }
729
- } else if (f2.contains(l)) {
730
- a2.current = l;
731
- return;
732
- }
733
- if (r != null && r.current) style.w(r.current);
734
- else {
735
- if (o & 16) {
736
- if (style.v(f2, style.T.First | style.T.AutoFocus) !== style.A.Error) return;
737
- } else if (style.v(f2, style.T.First) !== style.A.Error) return;
738
- if (u2 != null && u2.current && (style.w(u2.current), (t == null ? void 0 : t.activeElement) === u2.current)) return;
739
- console.warn("There are no focusable elements inside the <FocusTrap />");
740
- }
741
- a2.current = t == null ? void 0 : t.activeElement;
742
- });
743
- }, [u2, n, o]), a2;
744
- }
745
- function oe(o, { ownerDocument: t, container: e2, containers: r, previousActiveElement: u2 }) {
746
- let a2 = style.f$1(), n = !!(o & 4);
747
- style.E(t == null ? void 0 : t.defaultView, "focus", (s2) => {
748
- if (!n || !a2.current) return;
749
- let f2 = x(r);
750
- style.n$1(e2.current) && f2.add(e2.current);
751
- let l = u2.current;
752
- if (!l) return;
753
- let T = s2.target;
754
- style.n$1(T) ? I(f2, T) ? (u2.current = T, style.w(T)) : (s2.preventDefault(), s2.stopPropagation(), style.w(l)) : style.w(u2.current);
755
- }, true);
756
- }
757
- function I(o, t) {
758
- for (let e2 of o) if (e2.contains(t)) return true;
759
- return false;
760
- }
761
- var we$1 = ((o) => (o[o.Open = 0] = "Open", o[o.Closed = 1] = "Closed", o))(we$1 || {}), Be$1 = ((t) => (t[t.SetTitleId = 0] = "SetTitleId", t))(Be$1 || {});
762
- let Ue$1 = { [0](e2, t) {
763
- return e2.titleId === t.id ? e2 : { ...e2, titleId: t.id };
764
- } }, w = React.createContext(null);
765
- w.displayName = "DialogContext";
766
- function O(e2) {
767
- let t = React.useContext(w);
768
- if (t === null) {
769
- let o = new Error(`<${e2} /> is missing a parent <Dialog /> component.`);
770
- throw Error.captureStackTrace && Error.captureStackTrace(o, O), o;
771
- }
772
- return t;
773
- }
774
- function He$1(e2, t) {
775
- return style.u$1(t.type, Ue$1, e2, t);
776
- }
777
- let z$1 = style.Y(function(t, o) {
778
- let a2 = React.useId(), { id: n = `headlessui-dialog-${a2}`, open: i, onClose: p, initialFocus: d2, role: s2 = "dialog", autoFocus: f2 = true, __demoMode: u2 = false, unmount: y = false, ...S$1 } = t, R = React.useRef(false);
779
- s2 = (function() {
780
- return s2 === "dialog" || s2 === "alertdialog" ? s2 : (R.current || (R.current = true, console.warn(`Invalid role [${s2}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`)), "dialog");
781
- })();
782
- let g = style.u$2();
783
- i === void 0 && g !== null && (i = (g & style.i$1.Open) === style.i$1.Open);
784
- let T = React.useRef(null), I2 = style.y(T, o), F = style.u(T.current), c2 = i ? 0 : 1, [b2, Q2] = React.useReducer(He$1, { titleId: null, descriptionId: null, panelRef: React.createRef() }), m = style.o$1(() => p(false)), B = style.o$1((r) => Q2({ type: 0, id: r })), D = style.l$1() ? c2 === 0 : false, [Z, ee2] = style.ee(), te2 = { get current() {
785
- var r;
786
- return (r = b2.panelRef.current) != null ? r : T.current;
787
- } }, v = x$1(), { resolveContainers: M } = S({ mainTreeNode: v, portals: Z, defaultContainers: [te2] }), U = g !== null ? (g & style.i$1.Closing) === style.i$1.Closing : false;
788
- style.y$1(u2 || U ? false : D, { allowed: style.o$1(() => {
789
- var r, W2;
790
- return [(W2 = (r = T.current) == null ? void 0 : r.closest("[data-headlessui-portal]")) != null ? W2 : null];
791
- }), disallowed: style.o$1(() => {
792
- var r;
793
- return [(r = v == null ? void 0 : v.closest("body > *:not(#headlessui-portal-root)")) != null ? r : null];
794
- }) });
795
- let P = style.x.get(null);
796
- style.n(() => {
797
- if (D) return P.actions.push(n), () => P.actions.pop(n);
798
- }, [P, n, D]);
799
- let H = style.S(P, React.useCallback((r) => P.selectors.isTop(r, n), [P, n]));
800
- style.k(H, M, (r) => {
801
- r.preventDefault(), m();
802
- }), a$2(H, F == null ? void 0 : F.defaultView, (r) => {
803
- r.preventDefault(), r.stopPropagation(), document.activeElement && "blur" in document.activeElement && typeof document.activeElement.blur == "function" && document.activeElement.blur(), m();
804
- }), style.f$2(u2 || U ? false : D, F, M), style.p$1(D, T, m);
805
- let [oe2, ne2] = style.H(), re2 = React.useMemo(() => [{ dialogState: c2, close: m, setTitleId: B, unmount: y }, b2], [c2, m, B, y, b2]), N = style.n$3({ open: c2 === 0 }), le = { ref: I2, id: n, role: s2, tabIndex: -1, "aria-modal": u2 ? void 0 : c2 === 0 ? true : void 0, "aria-labelledby": b2.titleId, "aria-describedby": oe2, unmount: y }, ae = !f$1(), E2 = G.None;
806
- D && !u2 && (E2 |= G.RestoreFocus, E2 |= G.TabLock, f2 && (E2 |= G.AutoFocus), ae && (E2 |= G.InitialFocus));
807
- let ie = style.K();
808
- return React.createElement(style.s$2, null, React.createElement(style.l$2, { force: true }, React.createElement(style.te, null, React.createElement(w.Provider, { value: re2 }, React.createElement(style.X, { target: T }, React.createElement(style.l$2, { force: false }, React.createElement(ne2, { slot: N }, React.createElement(ee2, null, React.createElement(ge, { initialFocus: d2, initialFocusFallback: T, containers: M, features: E2 }, React.createElement(C$1, { value: m }, ie({ ourProps: le, theirProps: S$1, slot: N, defaultTag: Ne$1, features: We$1, visible: c2 === 0, name: "Dialog" })))))))))));
809
- }), Ne$1 = "div", We$1 = style.A$1.RenderStrategy | style.A$1.Static;
810
- function $e(e2, t) {
811
- let { transition: o = false, open: a2, ...n } = e2, i = style.u$2(), p = e2.hasOwnProperty("open") || i !== null, d2 = e2.hasOwnProperty("onClose");
812
- if (!p && !d2) throw new Error("You have to provide an `open` and an `onClose` prop to the `Dialog` component.");
813
- if (!p) throw new Error("You provided an `onClose` prop to the `Dialog`, but forgot an `open` prop.");
814
- if (!d2) throw new Error("You provided an `open` prop to the `Dialog`, but forgot an `onClose` prop.");
815
- if (!i && typeof e2.open != "boolean") throw new Error(`You provided an \`open\` prop to the \`Dialog\`, but the value is not a boolean. Received: ${e2.open}`);
816
- if (typeof e2.onClose != "function") throw new Error(`You provided an \`onClose\` prop to the \`Dialog\`, but the value is not a function. Received: ${e2.onClose}`);
817
- return (a2 !== void 0 || o) && !n.static ? React.createElement(j, null, React.createElement(style.Ke, { show: a2, transition: o, unmount: n.unmount }, React.createElement(z$1, { ref: t, ...n }))) : React.createElement(j, null, React.createElement(z$1, { ref: t, open: a2, ...n }));
818
- }
819
- let je$1 = "div";
820
- function Ye(e2, t) {
821
- let o = React.useId(), { id: a2 = `headlessui-dialog-panel-${o}`, transition: n = false, ...i } = e2, [{ dialogState: p, unmount: d2 }, s2] = O("Dialog.Panel"), f2 = style.y(t, s2.panelRef), u2 = style.n$3({ open: p === 0 }), y = style.o$1((I2) => {
822
- I2.stopPropagation();
823
- }), S2 = { ref: f2, id: a2, onClick: y }, R = n ? style.Oe : React.Fragment, g = n ? { unmount: d2 } : {}, T = style.K();
824
- return React.createElement(R, { ...g }, T({ ourProps: S2, theirProps: i, slot: u2, defaultTag: je$1, name: "Dialog.Panel" }));
825
- }
826
- let Je = "div";
827
- function Ke$1(e2, t) {
828
- let { transition: o = false, ...a2 } = e2, [{ dialogState: n, unmount: i }] = O("Dialog.Backdrop"), p = style.n$3({ open: n === 0 }), d2 = { ref: t, "aria-hidden": true }, s2 = o ? style.Oe : React.Fragment, f2 = o ? { unmount: i } : {}, u2 = style.K();
829
- return React.createElement(s2, { ...f2 }, u2({ ourProps: d2, theirProps: a2, slot: p, defaultTag: Je, name: "Dialog.Backdrop" }));
830
- }
831
- let Xe = "h2";
832
- function Ve(e2, t) {
833
- let o = React.useId(), { id: a2 = `headlessui-dialog-title-${o}`, ...n } = e2, [{ dialogState: i, setTitleId: p }] = O("Dialog.Title"), d2 = style.y(t);
834
- React.useEffect(() => (p(a2), () => p(null)), [a2, p]);
835
- let s2 = style.n$3({ open: i === 0 }), f2 = { ref: d2, id: a2 };
836
- return style.K()({ ourProps: f2, theirProps: n, slot: s2, defaultTag: Xe, name: "Dialog.Title" });
837
- }
838
- let qe = style.Y($e), ze = style.Y(Ye);
839
- style.Y(Ke$1);
840
- let Qe = style.Y(Ve), ht = Object.assign(qe, { Panel: ze, Title: Qe, Description: style.M });
841
- let _ = "div";
842
- function c(d2, l) {
843
- let t = `headlessui-control-${React.useId()}`, [p, s2] = style.V(), [n, a2] = style.H(), m = style.a(), { disabled: r = m || false, ...o } = d2, i = style.n$3({ disabled: r }), F = { ref: l, disabled: r || void 0, "aria-disabled": r || void 0 }, T = style.K();
844
- return React.createElement(style.l$3, { value: r }, React.createElement(s2, { value: p }, React.createElement(a2, { value: n }, React.createElement(style.f$3, { id: t }, T({ ourProps: F, theirProps: { ...o, children: React.createElement(style.W, null, typeof o.children == "function" ? o.children(i) : o.children) }, slot: i, defaultTag: _, name: "Field" })))));
845
- }
846
- let W = style.Y(c);
847
- let E = React.createContext(null);
848
- E.displayName = "GroupContext";
849
- let ve$1 = React.Fragment;
850
- function xe(n) {
851
- var c2;
852
- let [t, a2] = React.useState(null), [f2, h2] = style.V(), [b2, o] = style.H(), s2 = React.useMemo(() => ({ switch: t, setSwitch: a2 }), [t, a2]), T = {}, y = n, p = style.K();
853
- return React.createElement(o, { name: "Switch.Description", value: b2 }, React.createElement(h2, { name: "Switch.Label", value: f2, props: { htmlFor: (c2 = s2.switch) == null ? void 0 : c2.id, onClick(u2) {
854
- t && (style.m$1(u2.currentTarget) && u2.preventDefault(), t.click(), t.focus({ preventScroll: true }));
855
- } } }, React.createElement(E.Provider, { value: s2 }, p({ ourProps: T, theirProps: y, slot: {}, defaultTag: ve$1, name: "Switch.Group" }))));
856
- }
857
- let Ce$1 = "button";
858
- function Le$1(n, t) {
859
- var g;
860
- let a2 = React.useId(), f2 = style.u$3(), h2 = style.a(), { id: b2 = f2 || `headlessui-switch-${a2}`, disabled: o = h2 || false, checked: s2, defaultChecked: T, onChange: y, name: p, value: c2, form: u2, autoFocus: S2 = false, ...C2 } = n, _2 = React.useContext(E), [L, R] = React.useState(null), G2 = React.useRef(null), A = style.y(G2, t, _2 === null ? null : _2.setSwitch, R), l = style.l$4(T), [d2, r] = style.b(s2, y, l != null ? l : false), F = style.p(), [H, P] = React.useState(false), D = style.o$1(() => {
861
- P(true), r == null || r(!d2), F.nextFrame(() => {
862
- P(false);
863
- });
864
- }), k = style.o$1((e2) => {
865
- if (style.s$3(e2.currentTarget)) return e2.preventDefault();
866
- e2.preventDefault(), D();
867
- }), M = style.o$1((e2) => {
868
- e2.key === style.o.Space ? (e2.preventDefault(), D()) : e2.key === style.o.Enter && style.g(e2.currentTarget);
869
- }), U = style.o$1((e2) => e2.preventDefault()), I2 = style.N(), B = style.w$1(), { isFocusVisible: K, focusProps: O2 } = style.$f7dceffc5ad7768b$export$4e328f61c538687f({ autoFocus: S2 }), { isHovered: W2, hoverProps: N } = style.$6179b936705e76d3$export$ae780daf29e6d456({ isDisabled: o }), { pressed: J, pressProps: V2 } = style.w$2({ disabled: o }), X = style.n$3({ checked: d2, disabled: o, hover: W2, focus: K, active: J, autofocus: S2, changing: H }), j2 = style.V$1({ id: b2, ref: A, role: "switch", type: style.e(n, L), tabIndex: n.tabIndex === -1 ? 0 : (g = n.tabIndex) != null ? g : 0, "aria-checked": d2, "aria-labelledby": I2, "aria-describedby": B, disabled: o || void 0, autoFocus: S2, onClick: k, onKeyUp: M, onKeyPress: U }, O2, N, V2), $2 = React.useCallback(() => {
870
- if (l !== void 0) return r == null ? void 0 : r(l);
871
- }, [r, l]), q = style.K();
872
- return React.createElement(React.Fragment, null, p != null && React.createElement(style.j, { disabled: o, data: { [p]: c2 || "on" }, overrides: { type: "checkbox", checked: d2 }, form: u2, onReset: $2 }), q({ ourProps: j2, theirProps: C2, slot: X, defaultTag: Ce$1, name: "Switch" }));
873
- }
874
- let Re = style.Y(Le$1), Ge$1 = xe, Ae = style.Z, Fe$1 = style.M, tt = Object.assign(Re, { Group: Ge$1, Label: Ae, Description: Fe$1 });
875
- function b({ onFocus: n }) {
876
- let [r, o] = React.useState(true), u2 = style.f$1();
877
- return r ? React.createElement(style.f, { as: "button", type: "button", features: style.s.Focusable, onFocus: (a2) => {
878
- a2.preventDefault();
879
- let e2, i = 50;
880
- function t() {
881
- if (i-- <= 0) {
882
- e2 && cancelAnimationFrame(e2);
883
- return;
884
- }
885
- if (n()) {
886
- if (cancelAnimationFrame(e2), !u2.current) return;
887
- o(false);
888
- return;
889
- }
890
- e2 = requestAnimationFrame(t);
891
- }
892
- e2 = requestAnimationFrame(t);
893
- } }) : null;
894
- }
895
- const s = React__namespace.createContext(null);
896
- function a() {
897
- return { groups: /* @__PURE__ */ new Map(), get(o, e2) {
898
- var i;
899
- let t = this.groups.get(o);
900
- t || (t = /* @__PURE__ */ new Map(), this.groups.set(o, t));
901
- let n = (i = t.get(e2)) != null ? i : 0;
902
- t.set(e2, n + 1);
903
- let r = Array.from(t.keys()).indexOf(e2);
904
- function u2() {
905
- let c2 = t.get(e2);
906
- c2 > 1 ? t.set(e2, c2 - 1) : t.delete(e2);
907
- }
908
- return [r, u2];
909
- } };
910
- }
911
- function f({ children: o }) {
912
- let e2 = React__namespace.useRef(a());
913
- return React__namespace.createElement(s.Provider, { value: e2 }, o);
914
- }
915
- function C(o) {
916
- let e2 = React__namespace.useContext(s);
917
- if (!e2) throw new Error("You must wrap your component in a <StableCollection>");
918
- let t = React__namespace.useId(), [n, r] = e2.current.get(o, t);
919
- return React__namespace.useEffect(() => r, []), n;
920
- }
921
- var Le = ((t) => (t[t.Forwards = 0] = "Forwards", t[t.Backwards = 1] = "Backwards", t))(Le || {}), _e = ((l) => (l[l.Less = -1] = "Less", l[l.Equal = 0] = "Equal", l[l.Greater = 1] = "Greater", l))(_e || {}), Se = ((n) => (n[n.SetSelectedIndex = 0] = "SetSelectedIndex", n[n.RegisterTab = 1] = "RegisterTab", n[n.UnregisterTab = 2] = "UnregisterTab", n[n.RegisterPanel = 3] = "RegisterPanel", n[n.UnregisterPanel = 4] = "UnregisterPanel", n))(Se || {});
922
- let De = { [0](e2, r) {
923
- var d2;
924
- let t = style.G(e2.tabs, (u2) => u2.current), l = style.G(e2.panels, (u2) => u2.current), a2 = t.filter((u2) => {
925
- var T;
926
- return !((T = u2.current) != null && T.hasAttribute("disabled"));
927
- }), n = { ...e2, tabs: t, panels: l };
928
- if (r.index < 0 || r.index > t.length - 1) {
929
- let u2 = style.u$1(Math.sign(r.index - e2.selectedIndex), { [-1]: () => 1, [0]: () => style.u$1(Math.sign(r.index), { [-1]: () => 0, [0]: () => 0, [1]: () => 1 }), [1]: () => 0 });
930
- if (a2.length === 0) return n;
931
- let T = style.u$1(u2, { [0]: () => t.indexOf(a2[0]), [1]: () => t.indexOf(a2[a2.length - 1]) });
932
- return { ...n, selectedIndex: T === -1 ? e2.selectedIndex : T };
933
- }
934
- let s2 = t.slice(0, r.index), f2 = [...t.slice(r.index), ...s2].find((u2) => a2.includes(u2));
935
- if (!f2) return n;
936
- let b2 = (d2 = t.indexOf(f2)) != null ? d2 : e2.selectedIndex;
937
- return b2 === -1 && (b2 = e2.selectedIndex), { ...n, selectedIndex: b2 };
938
- }, [1](e2, r) {
939
- if (e2.tabs.includes(r.tab)) return e2;
940
- let t = e2.tabs[e2.selectedIndex], l = style.G([...e2.tabs, r.tab], (n) => n.current), a2 = e2.selectedIndex;
941
- return e2.info.current.isControlled || (a2 = l.indexOf(t), a2 === -1 && (a2 = e2.selectedIndex)), { ...e2, tabs: l, selectedIndex: a2 };
942
- }, [2](e2, r) {
943
- return { ...e2, tabs: e2.tabs.filter((t) => t !== r.tab) };
944
- }, [3](e2, r) {
945
- return e2.panels.includes(r.panel) ? e2 : { ...e2, panels: style.G([...e2.panels, r.panel], (t) => t.current) };
946
- }, [4](e2, r) {
947
- return { ...e2, panels: e2.panels.filter((t) => t !== r.panel) };
948
- } }, z = React.createContext(null);
949
- z.displayName = "TabsDataContext";
950
- function h(e2) {
951
- let r = React.useContext(z);
952
- if (r === null) {
953
- let t = new Error(`<${e2} /> is missing a parent <Tab.Group /> component.`);
954
- throw Error.captureStackTrace && Error.captureStackTrace(t, h), t;
955
- }
956
- return r;
957
- }
958
- let V = React.createContext(null);
959
- V.displayName = "TabsActionsContext";
960
- function Q(e2) {
961
- let r = React.useContext(V);
962
- if (r === null) {
963
- let t = new Error(`<${e2} /> is missing a parent <Tab.Group /> component.`);
964
- throw Error.captureStackTrace && Error.captureStackTrace(t, Q), t;
965
- }
966
- return r;
967
- }
968
- function Fe(e2, r) {
969
- return style.u$1(r.type, De, e2, r);
970
- }
971
- let Ie = "div";
972
- function he(e2, r) {
973
- let { defaultIndex: t = 0, vertical: l = false, manual: a2 = false, onChange: n, selectedIndex: s2 = null, ...g } = e2;
974
- const f$12 = l ? "vertical" : "horizontal", b$1 = a2 ? "manual" : "auto";
975
- let d2 = s2 !== null, u2 = style.s$4({ isControlled: d2 }), T = style.y(r), [p, c2] = React.useReducer(Fe, { info: u2, selectedIndex: s2 != null ? s2 : t, tabs: [], panels: [] }), v = style.n$3({ selectedIndex: p.selectedIndex }), m = style.s$4(n || (() => {
976
- })), C2 = style.s$4(p.tabs), D = React.useMemo(() => ({ orientation: f$12, activation: b$1, ...p }), [f$12, b$1, p]), P = style.o$1((i) => (c2({ type: 1, tab: i }), () => c2({ type: 2, tab: i }))), R = style.o$1((i) => (c2({ type: 3, panel: i }), () => c2({ type: 4, panel: i }))), A = style.o$1((i) => {
977
- L.current !== i && m.current(i), d2 || c2({ type: 0, index: i });
978
- }), L = style.s$4(d2 ? e2.selectedIndex : p.selectedIndex), _2 = React.useMemo(() => ({ registerTab: P, registerPanel: R, change: A }), []);
979
- style.n(() => {
980
- c2({ type: 0, index: s2 != null ? s2 : t });
981
- }, [s2]), style.n(() => {
982
- if (L.current === void 0 || p.tabs.length <= 0) return;
983
- let i = style.G(p.tabs, (S2) => S2.current);
984
- i.some((S2, $2) => p.tabs[$2] !== S2) && A(i.indexOf(p.tabs[L.current]));
985
- });
986
- let J = { ref: T }, X = style.K();
987
- return React.createElement(f, null, React.createElement(V.Provider, { value: _2 }, React.createElement(z.Provider, { value: D }, D.tabs.length <= 0 && React.createElement(b, { onFocus: () => {
988
- var i, M;
989
- for (let S2 of C2.current) if (((i = S2.current) == null ? void 0 : i.tabIndex) === 0) return (M = S2.current) == null || M.focus(), true;
990
- return false;
991
- } }), X({ ourProps: J, theirProps: g, slot: v, defaultTag: Ie, name: "Tabs" }))));
992
- }
993
- let ve = "div";
994
- function Ce(e2, r) {
995
- let { orientation: t, selectedIndex: l } = h("Tab.List"), a2 = style.y(r), n = style.n$3({ selectedIndex: l }), s2 = e2, g = { ref: a2, role: "tablist", "aria-orientation": t };
996
- return style.K()({ ourProps: g, theirProps: s2, slot: n, defaultTag: ve, name: "Tabs.List" });
997
- }
998
- let Me = "button";
999
- function Ge(e2, r) {
1000
- var Y, Z;
1001
- let t = React.useId(), { id: l = `headlessui-tabs-tab-${t}`, disabled: a2 = false, autoFocus: n = false, ...s2 } = e2, { orientation: g, activation: f2, selectedIndex: b2, tabs: d2, panels: u2 } = h("Tab"), T = Q("Tab"), p = h("Tab"), [c2, v] = React.useState(null), m = React.useRef(null), C$12 = style.y(m, r, v);
1002
- style.n(() => T.registerTab(m), [T, m]);
1003
- let D = C("tabs"), P = d2.indexOf(m);
1004
- P === -1 && (P = D);
1005
- let R = P === b2, A = style.o$1((o) => {
1006
- let E2 = o();
1007
- if (E2 === style.A.Success && f2 === "auto") {
1008
- let ee2 = style.e$1(m.current), B = p.tabs.findIndex((ce) => ce.current === ee2);
1009
- B !== -1 && T.change(B);
1010
- }
1011
- return E2;
1012
- }), L = style.o$1((o) => {
1013
- let E2 = d2.map((B) => B.current).filter(Boolean);
1014
- if (o.key === style.o.Space || o.key === style.o.Enter) {
1015
- o.preventDefault(), o.stopPropagation(), T.change(P);
1016
- return;
1017
- }
1018
- switch (o.key) {
1019
- case style.o.Home:
1020
- case style.o.PageUp:
1021
- return o.preventDefault(), o.stopPropagation(), A(() => style.v(E2, style.T.First));
1022
- case style.o.End:
1023
- case style.o.PageDown:
1024
- return o.preventDefault(), o.stopPropagation(), A(() => style.v(E2, style.T.Last));
1025
- }
1026
- if (A(() => style.u$1(g, { vertical() {
1027
- return o.key === style.o.ArrowUp ? style.v(E2, style.T.Previous | style.T.WrapAround) : o.key === style.o.ArrowDown ? style.v(E2, style.T.Next | style.T.WrapAround) : style.A.Error;
1028
- }, horizontal() {
1029
- return o.key === style.o.ArrowLeft ? style.v(E2, style.T.Previous | style.T.WrapAround) : o.key === style.o.ArrowRight ? style.v(E2, style.T.Next | style.T.WrapAround) : style.A.Error;
1030
- } })) === style.A.Success) return o.preventDefault();
1031
- }), _2 = React.useRef(false), J = style.o$1(() => {
1032
- var o;
1033
- _2.current || (_2.current = true, (o = m.current) == null || o.focus({ preventScroll: true }), T.change(P), style.t$1(() => {
1034
- _2.current = false;
1035
- }));
1036
- }), X = style.o$1((o) => {
1037
- o.preventDefault();
1038
- }), { isFocusVisible: i, focusProps: M } = style.$f7dceffc5ad7768b$export$4e328f61c538687f({ autoFocus: n }), { isHovered: S2, hoverProps: $2 } = style.$6179b936705e76d3$export$ae780daf29e6d456({ isDisabled: a2 }), { pressed: pe, pressProps: ue } = style.w$2({ disabled: a2 }), Te = style.n$3({ selected: R, hover: S2, active: pe, focus: i, autofocus: n, disabled: a2 }), de = style.V$1({ ref: C$12, onKeyDown: L, onMouseDown: X, onClick: J, id: l, role: "tab", type: style.e(e2, c2), "aria-controls": (Z = (Y = u2[P]) == null ? void 0 : Y.current) == null ? void 0 : Z.id, "aria-selected": R, tabIndex: R ? 0 : -1, disabled: a2 || void 0, autoFocus: n }, M, $2, ue);
1039
- return style.K()({ ourProps: de, theirProps: s2, slot: Te, defaultTag: Me, name: "Tabs.Tab" });
1040
- }
1041
- let Ue = "div";
1042
- function He(e2, r) {
1043
- let { selectedIndex: t } = h("Tab.Panels"), l = style.y(r), a2 = style.n$3({ selectedIndex: t }), n = e2, s2 = { ref: l };
1044
- return style.K()({ ourProps: s2, theirProps: n, slot: a2, defaultTag: Ue, name: "Tabs.Panels" });
1045
- }
1046
- let we = "div", Oe = style.A$1.RenderStrategy | style.A$1.Static;
1047
- function Ne(e2, r) {
1048
- var R, A, L, _2;
1049
- let t = React.useId(), { id: l = `headlessui-tabs-panel-${t}`, tabIndex: a2 = 0, ...n } = e2, { selectedIndex: s2, tabs: g, panels: f2 } = h("Tab.Panel"), b2 = Q("Tab.Panel"), d2 = React.useRef(null), u2 = style.y(d2, r);
1050
- style.n(() => b2.registerPanel(d2), [b2, d2]);
1051
- let T = C("panels"), p = f2.indexOf(d2);
1052
- p === -1 && (p = T);
1053
- let c2 = p === s2, { isFocusVisible: v, focusProps: m } = style.$f7dceffc5ad7768b$export$4e328f61c538687f(), C$12 = style.n$3({ selected: c2, focus: v }), D = style.V$1({ ref: u2, id: l, role: "tabpanel", "aria-labelledby": (A = (R = g[p]) == null ? void 0 : R.current) == null ? void 0 : A.id, tabIndex: c2 ? a2 : -1 }, m), P = style.K();
1054
- return !c2 && ((L = n.unmount) == null || L) && !((_2 = n.static) != null && _2) ? React.createElement(style.f, { "aria-hidden": "true", ...D }) : P({ ourProps: D, theirProps: n, slot: C$12, defaultTag: we, features: Oe, visible: c2, name: "Tabs.Panel" });
1055
- }
1056
- let ke = style.Y(Ge), Be = style.Y(he), We = style.Y(Ce), je = style.Y(He), Ke = style.Y(Ne), dt = Object.assign(ke, { Group: Be, List: We, Panels: je, Panel: Ke });
1057
- function Select({
1058
- options,
1059
- value,
1060
- onChange,
1061
- placeholder = "Select...",
1062
- label,
1063
- error,
1064
- helperText,
1065
- disabled = false,
1066
- required = false,
1067
- fullWidth = false,
1068
- className,
1069
- isLoading = false,
1070
- loadingText = "Loading...",
1071
- placement = "bottom",
1072
- testId
1073
- }) {
1074
- const selectedOption = options.find((opt) => opt.value === value);
1075
- const hasError = !!error;
1076
- const isDisabled = disabled || isLoading;
1077
- const labelId = React.useId();
1078
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn(fullWidth ? "w-full" : "w-auto", className), "data-testid": testId, children: [
1079
- label && /* @__PURE__ */ jsxRuntime.jsxs(
1080
- "label",
1081
- {
1082
- id: labelId,
1083
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
1084
- "data-testid": testId ? `${testId}-label` : void 0,
1085
- children: [
1086
- label,
1087
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
1088
- ]
1089
- }
1090
- ),
1091
- /* @__PURE__ */ jsxRuntime.jsx(style.Mo, { disabled: isDisabled, value: value ?? void 0, onChange, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1092
- /* @__PURE__ */ jsxRuntime.jsxs(
1093
- style.Mt,
1094
- {
1095
- "aria-label": !label ? placeholder : void 0,
1096
- "aria-labelledby": label ? labelId : void 0,
1097
- "data-testid": testId ? `${testId}-button` : void 0,
1098
- className: utils_index.cn(
1099
- // Base styles - Light mode
1100
- "relative w-full rounded-md border bg-white px-4 py-2.5 text-left text-sm",
1101
- "transition-colors duration-normal",
1102
- "focus:outline-none focus:ring-2",
1103
- "disabled:cursor-not-allowed disabled:bg-primary-50 disabled:text-primary-500",
1104
- // Base styles - Dark mode
1105
- "dark:bg-primary-800",
1106
- "dark:disabled:bg-primary-900 dark:disabled:text-primary-600",
1107
- // Border and focus styles
1108
- hasError ? "border-error focus:border-error focus:ring-error/20 dark:border-error/70 dark:focus:ring-error/30" : "border-primary-300 focus:border-gold-500 focus:ring-gold-500/20 dark:border-primary-600 dark:focus:border-gold-400 dark:focus:ring-gold-400/30"
1109
- ),
1110
- children: [
1111
- /* @__PURE__ */ jsxRuntime.jsx(
1112
- "span",
1113
- {
1114
- className: utils_index.cn(
1115
- "block truncate",
1116
- selectedOption ? "text-primary-900 dark:text-primary-100" : "text-primary-400 dark:text-primary-500"
1117
- ),
1118
- children: selectedOption?.label || placeholder
1119
- }
1120
- ),
1121
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary", label: loadingText }) : /* @__PURE__ */ jsxRuntime.jsx(
1122
- "svg",
1123
- {
1124
- className: "h-5 w-5 text-primary-400 dark:text-primary-500",
1125
- fill: "currentColor",
1126
- viewBox: "0 0 20 20",
1127
- "aria-hidden": "true",
1128
- children: /* @__PURE__ */ jsxRuntime.jsx(
1129
- "path",
1130
- {
1131
- clipRule: "evenodd",
1132
- d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
1133
- fillRule: "evenodd"
1134
- }
1135
- )
1136
- }
1137
- ) })
1138
- ]
1139
- }
1140
- ),
1141
- /* @__PURE__ */ jsxRuntime.jsx(
1142
- style.Ke,
1143
- {
1144
- as: React.Fragment,
1145
- leave: "transition ease-in duration-100",
1146
- leaveFrom: "opacity-100",
1147
- leaveTo: "opacity-0",
1148
- children: /* @__PURE__ */ jsxRuntime.jsx(
1149
- style.Bt,
1150
- {
1151
- className: utils_index.cn(
1152
- "absolute z-dropdown max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-primary-800 dark:ring-primary-700",
1153
- placement === "top" ? "bottom-full mb-1" : "top-full mt-1"
1154
- ),
1155
- "data-testid": testId ? `${testId}-options` : void 0,
1156
- children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
1157
- style.It,
1158
- {
1159
- disabled: option.disabled,
1160
- value: option.value,
1161
- "data-testid": testId ? `${testId}-option-${index}` : void 0,
1162
- className: ({ active, selected }) => utils_index.cn(
1163
- "relative cursor-pointer select-none py-2.5 pl-10 pr-4",
1164
- // Light mode
1165
- active ? "bg-gold-50 text-primary-900" : "text-primary-900",
1166
- // Dark mode
1167
- active ? "dark:bg-primary-700 dark:text-primary-100" : "dark:text-primary-200",
1168
- option.disabled && "cursor-not-allowed opacity-50",
1169
- selected && "font-medium"
1170
- ),
1171
- children: ({ selected }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1172
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate", children: option.label }),
1173
- selected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-y-0 left-0 flex items-center pl-3 text-gold-600 dark:text-gold-400", children: /* @__PURE__ */ jsxRuntime.jsx(
1174
- "svg",
1175
- {
1176
- className: "h-5 w-5",
1177
- fill: "currentColor",
1178
- viewBox: "0 0 20 20",
1179
- "aria-hidden": "true",
1180
- children: /* @__PURE__ */ jsxRuntime.jsx(
1181
- "path",
1182
- {
1183
- clipRule: "evenodd",
1184
- d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z",
1185
- fillRule: "evenodd"
1186
- }
1187
- )
1188
- }
1189
- ) })
1190
- ] })
1191
- },
1192
- option.value
1193
- ))
1194
- }
1195
- )
1196
- }
1197
- )
1198
- ] }) }),
1199
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
1200
- "p",
1201
- {
1202
- role: hasError ? "alert" : void 0,
1203
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
1204
- className: utils_index.cn(
1205
- "mt-1.5 text-sm",
1206
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
1207
- ),
1208
- children: error || helperText
1209
- }
1210
- )
1211
- ] });
1212
- }
1213
- Select.displayName = "Select";
1214
- const CloseIcon$2 = () => /* @__PURE__ */ jsxRuntime.jsx(
1215
- "svg",
1216
- {
1217
- className: "h-5 w-5",
1218
- fill: "none",
1219
- stroke: "currentColor",
1220
- viewBox: "0 0 24 24",
1221
- "aria-hidden": "true",
1222
- children: /* @__PURE__ */ jsxRuntime.jsx(
1223
- "path",
1224
- {
1225
- strokeLinecap: "round",
1226
- strokeLinejoin: "round",
1227
- strokeWidth: 2,
1228
- d: "M6 18L18 6M6 6l12 12"
1229
- }
1230
- )
1231
- }
1232
- );
1233
- const sizeStyles$b = {
1234
- sm: "max-w-[400px]",
1235
- md: "max-w-[560px]",
1236
- lg: "max-w-[720px]"
1237
- };
1238
- function Modal({
1239
- isOpen,
1240
- onClose,
1241
- title,
1242
- description,
1243
- children,
1244
- size = "md",
1245
- showCloseButton = true,
1246
- footer,
1247
- closeOnOverlay = true,
1248
- className,
1249
- isLoading = false,
1250
- testId
1251
- }) {
1252
- const handleClose = closeOnOverlay ? onClose : () => {
1253
- };
1254
- return /* @__PURE__ */ jsxRuntime.jsx(style.Ke, { show: isOpen, as: React.Fragment, children: /* @__PURE__ */ jsxRuntime.jsxs(ht, { className: "relative z-50", onClose: handleClose, children: [
1255
- /* @__PURE__ */ jsxRuntime.jsx(
1256
- style.Oe,
1257
- {
1258
- as: React.Fragment,
1259
- enter: "ease-out duration-150",
1260
- enterFrom: "opacity-0",
1261
- enterTo: "opacity-100",
1262
- leave: "ease-in duration-100",
1263
- leaveFrom: "opacity-100",
1264
- leaveTo: "opacity-0",
1265
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 bg-black/40 backdrop-blur-sm", "data-testid": testId ? `${testId}-overlay` : void 0 })
1266
- }
1267
- ),
1268
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
1269
- style.Oe,
1270
- {
1271
- as: React.Fragment,
1272
- enter: "ease-out duration-150",
1273
- enterFrom: "opacity-0 scale-95",
1274
- enterTo: "opacity-100 scale-100",
1275
- leave: "ease-in duration-100",
1276
- leaveFrom: "opacity-100 scale-100",
1277
- leaveTo: "opacity-0 scale-95",
1278
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1279
- ze,
1280
- {
1281
- className: utils_index.cn(
1282
- "w-full rounded-lg shadow-xl",
1283
- // Light mode
1284
- "bg-white border border-primary-200",
1285
- // Dark mode
1286
- "dark:bg-primary-800 dark:border-primary-700",
1287
- sizeStyles$b[size],
1288
- className
1289
- ),
1290
- "data-testid": testId,
1291
- children: [
1292
- (title || showCloseButton) && /* @__PURE__ */ jsxRuntime.jsxs(
1293
- "div",
1294
- {
1295
- className: utils_index.cn(
1296
- "flex items-start justify-between px-6 py-4",
1297
- (children || footer) && "border-b border-primary-200 dark:border-primary-700"
1298
- ),
1299
- "data-testid": testId ? `${testId}-header` : void 0,
1300
- children: [
1301
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
1302
- title && /* @__PURE__ */ jsxRuntime.jsx(Qe, { className: "text-lg font-semibold text-primary-900 dark:text-white", children: title }),
1303
- description && /* @__PURE__ */ jsxRuntime.jsx(style.M, { className: "mt-1 text-sm text-primary-500 dark:text-primary-400", children: description })
1304
- ] }),
1305
- showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
1306
- "button",
1307
- {
1308
- type: "button",
1309
- "aria-label": "Close modal",
1310
- onClick: onClose,
1311
- className: utils_index.cn(
1312
- "ml-4 flex-shrink-0 rounded-md p-1",
1313
- "text-primary-400 hover:text-primary-600",
1314
- "dark:text-primary-500 dark:hover:text-primary-300",
1315
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
1316
- "transition-colors"
1317
- ),
1318
- "data-testid": testId ? `${testId}-close-button` : void 0,
1319
- children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon$2, {})
1320
- }
1321
- )
1322
- ]
1323
- }
1324
- ),
1325
- children && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative px-6 py-4 text-primary-700 dark:text-primary-300", "data-testid": testId ? `${testId}-body` : void 0, children: [
1326
- children,
1327
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-white/60 dark:bg-primary-800/60", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "md", color: "primary" }) })
1328
- ] }),
1329
- footer && /* @__PURE__ */ jsxRuntime.jsx(
1330
- "div",
1331
- {
1332
- className: utils_index.cn(
1333
- "px-6 py-4 border-t",
1334
- "border-primary-200 dark:border-primary-700",
1335
- "bg-primary-50 dark:bg-primary-900/50",
1336
- "rounded-b-lg"
1337
- ),
1338
- "data-testid": testId ? `${testId}-footer` : void 0,
1339
- children: footer
1340
- }
1341
- )
1342
- ]
1343
- }
1344
- )
1345
- }
1346
- ) })
1347
- ] }) });
1348
- }
1349
- Modal.displayName = "Modal";
1350
- const CloseIcon$1 = () => /* @__PURE__ */ jsxRuntime.jsx(
1351
- "svg",
1352
- {
1353
- className: "h-5 w-5",
1354
- fill: "none",
1355
- stroke: "currentColor",
1356
- viewBox: "0 0 24 24",
1357
- "aria-hidden": "true",
1358
- children: /* @__PURE__ */ jsxRuntime.jsx(
1359
- "path",
1360
- {
1361
- strokeLinecap: "round",
1362
- strokeLinejoin: "round",
1363
- strokeWidth: 2,
1364
- d: "M6 18L18 6M6 6l12 12"
1365
- }
1366
- )
1367
- }
1368
- );
1369
- const sizeStyles$a = {
1370
- sm: "max-w-[400px]",
1371
- md: "max-w-[560px]",
1372
- lg: "max-w-[720px]"
1373
- };
1374
- function Drawer({
1375
- isOpen,
1376
- onClose,
1377
- title,
1378
- children,
1379
- size = "md",
1380
- showCloseButton = true,
1381
- footer,
1382
- className,
1383
- isLoading = false,
1384
- testId
1385
- }) {
1386
- return /* @__PURE__ */ jsxRuntime.jsx(style.Ke, { show: isOpen, as: React.Fragment, children: /* @__PURE__ */ jsxRuntime.jsxs(ht, { className: "relative z-50", onClose, children: [
1387
- /* @__PURE__ */ jsxRuntime.jsx(
1388
- style.Oe,
1389
- {
1390
- as: React.Fragment,
1391
- enter: "ease-out duration-300",
1392
- enterFrom: "opacity-0",
1393
- enterTo: "opacity-100",
1394
- leave: "ease-in duration-200",
1395
- leaveFrom: "opacity-100",
1396
- leaveTo: "opacity-0",
1397
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 bg-black/40 backdrop-blur-sm", "data-testid": testId ? `${testId}-overlay` : void 0 })
1398
- }
1399
- ),
1400
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1401
- style.Oe,
1402
- {
1403
- as: React.Fragment,
1404
- enter: "transform transition ease-out duration-300",
1405
- enterFrom: "translate-x-full",
1406
- enterTo: "translate-x-0",
1407
- leave: "transform transition ease-in duration-200",
1408
- leaveFrom: "translate-x-0",
1409
- leaveTo: "translate-x-full",
1410
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1411
- ze,
1412
- {
1413
- className: utils_index.cn(
1414
- "w-full h-full flex flex-col shadow-xl",
1415
- // Light mode
1416
- "bg-white border-l border-primary-200",
1417
- // Dark mode
1418
- "dark:bg-primary-800 dark:border-primary-700",
1419
- sizeStyles$a[size],
1420
- className
1421
- ),
1422
- "data-testid": testId,
1423
- children: [
1424
- (title || showCloseButton) && /* @__PURE__ */ jsxRuntime.jsxs(
1425
- "div",
1426
- {
1427
- className: utils_index.cn(
1428
- "flex items-center justify-between px-6 py-4 flex-shrink-0",
1429
- "border-b border-primary-200 dark:border-primary-700"
1430
- ),
1431
- children: [
1432
- title && /* @__PURE__ */ jsxRuntime.jsx(Qe, { className: "text-lg font-semibold text-primary-900 dark:text-white", children: title }),
1433
- showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
1434
- "button",
1435
- {
1436
- type: "button",
1437
- "aria-label": "Close drawer",
1438
- onClick: onClose,
1439
- className: utils_index.cn(
1440
- "ml-auto flex-shrink-0 rounded-md p-1",
1441
- "text-primary-400 hover:text-primary-600",
1442
- "dark:text-primary-500 dark:hover:text-primary-300",
1443
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
1444
- "transition-colors"
1445
- ),
1446
- "data-testid": testId ? `${testId}-close-button` : void 0,
1447
- children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon$1, {})
1448
- }
1449
- )
1450
- ]
1451
- }
1452
- ),
1453
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 overflow-y-auto px-6 py-4 text-primary-700 dark:text-primary-300", "data-testid": testId ? `${testId}-content` : void 0, children: [
1454
- children,
1455
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-white/60 dark:bg-primary-800/60", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "md", color: "primary" }) })
1456
- ] }),
1457
- footer && /* @__PURE__ */ jsxRuntime.jsx(
1458
- "div",
1459
- {
1460
- className: utils_index.cn(
1461
- "flex-shrink-0 px-6 py-4 border-t",
1462
- "border-primary-200 dark:border-primary-700",
1463
- "bg-primary-50 dark:bg-primary-900/50"
1464
- ),
1465
- children: footer
1466
- }
1467
- )
1468
- ]
1469
- }
1470
- )
1471
- }
1472
- ) })
1473
- ] }) });
1474
- }
1475
- Drawer.displayName = "Drawer";
1476
- const variantToButton = {
1477
- destructive: "danger",
1478
- neutral: "primary",
1479
- caution: "primary"
1480
- // Using primary with warning styling could be added later
1481
- };
1482
- function ConfirmDialog({
1483
- isOpen,
1484
- onClose,
1485
- onConfirm,
1486
- title,
1487
- description,
1488
- variant = "neutral",
1489
- cancelText = "Cancel",
1490
- confirmText = "Confirm",
1491
- loading = false,
1492
- testId
1493
- }) {
1494
- const buttonVariant = variantToButton[variant];
1495
- const handleConfirm = () => {
1496
- onConfirm();
1497
- };
1498
- return /* @__PURE__ */ jsxRuntime.jsx(
1499
- Modal,
1500
- {
1501
- isOpen,
1502
- onClose,
1503
- title,
1504
- description,
1505
- size: "sm",
1506
- showCloseButton: false,
1507
- closeOnOverlay: !loading,
1508
- testId,
1509
- footer: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3", children: [
1510
- /* @__PURE__ */ jsxRuntime.jsx(
1511
- Button,
1512
- {
1513
- variant: "secondary",
1514
- onClick: onClose,
1515
- disabled: loading,
1516
- "data-testid": testId ? `${testId}-cancel-button` : void 0,
1517
- children: cancelText
1518
- }
1519
- ),
1520
- /* @__PURE__ */ jsxRuntime.jsx(
1521
- Button,
1522
- {
1523
- variant: buttonVariant,
1524
- onClick: handleConfirm,
1525
- disabled: loading,
1526
- "data-testid": testId ? `${testId}-confirm-button` : void 0,
1527
- children: loading ? "Loading..." : confirmText
1528
- }
1529
- )
1530
- ] })
1531
- }
1532
- );
1533
- }
1534
- ConfirmDialog.displayName = "ConfirmDialog";
1535
- const paddingStyles = {
1536
- none: "",
1537
- sm: "p-4",
1538
- md: "p-6",
1539
- lg: "p-8"
1540
- };
1541
- const variantStyles$4 = {
1542
- default: [
1543
- "shadow-sm border border-primary-200",
1544
- "dark:border-primary-700"
1545
- ].join(" "),
1546
- bordered: [
1547
- "border-2 border-primary-300",
1548
- "dark:border-primary-600"
1549
- ].join(" "),
1550
- elevated: [
1551
- "shadow-md border border-primary-100",
1552
- "dark:shadow-lg dark:shadow-black/20 dark:border-primary-700"
1553
- ].join(" "),
1554
- "gold-accent": [
1555
- "shadow border border-gold-500/20",
1556
- "dark:border-gold-500/30"
1557
- ].join(" ")
1558
- };
1559
- const Card = React.forwardRef(
1560
- ({
1561
- padding = "md",
1562
- variant = "default",
1563
- hoverable = false,
1564
- children,
1565
- className,
1566
- testId,
1567
- ...props
1568
- }, ref) => {
1569
- return /* @__PURE__ */ jsxRuntime.jsx(
1570
- "div",
1571
- {
1572
- ref,
1573
- className: utils_index.cn(
1574
- // Base styles
1575
- "rounded-lg transition-all",
1576
- // Light mode
1577
- "bg-white",
1578
- // Dark mode
1579
- "dark:bg-primary-800",
1580
- // Padding
1581
- paddingStyles[padding],
1582
- // Variant
1583
- variantStyles$4[variant],
1584
- // Hover effect
1585
- hoverable && [
1586
- "cursor-pointer",
1587
- "hover:shadow-md hover:border-gold-500/40",
1588
- "dark:hover:shadow-lg dark:hover:shadow-black/30 dark:hover:border-gold-500/50"
1589
- ],
1590
- className
1591
- ),
1592
- "data-testid": testId,
1593
- ...props,
1594
- children
1595
- }
1596
- );
1597
- }
1598
- );
1599
- Card.displayName = "Card";
1600
- const sizeStyles$9 = {
1601
- sm: "h-4 w-4",
1602
- md: "h-5 w-5",
1603
- lg: "h-6 w-6"
1604
- };
1605
- const labelSizeStyles$1 = {
1606
- sm: "text-xs",
1607
- md: "text-sm",
1608
- lg: "text-base"
1609
- };
1610
- const Checkbox = React.forwardRef(
1611
- ({
1612
- label,
1613
- checked,
1614
- onChange,
1615
- size = "md",
1616
- disabled = false,
1617
- error,
1618
- helperText,
1619
- indeterminate = false,
1620
- className,
1621
- id,
1622
- testId,
1623
- ...props
1624
- }, forwardedRef) => {
1625
- const checkboxId = id || label?.toLowerCase().replace(/\s+/g, "-");
1626
- const hasError = !!error;
1627
- const errorId = hasError ? `${checkboxId}-error` : void 0;
1628
- const internalRef = React.useRef(null);
1629
- React.useEffect(() => {
1630
- const checkbox = internalRef.current;
1631
- if (checkbox) {
1632
- checkbox.indeterminate = indeterminate;
1633
- }
1634
- }, [indeterminate]);
1635
- const setRefs = React.useCallback(
1636
- (element) => {
1637
- internalRef.current = element;
1638
- if (typeof forwardedRef === "function") {
1639
- forwardedRef(element);
1640
- } else if (forwardedRef) {
1641
- forwardedRef.current = element;
1642
- }
1643
- },
1644
- [forwardedRef]
1645
- );
1646
- const handleChange = (e2) => {
1647
- onChange?.(e2.target.checked);
1648
- };
1649
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-testid": testId, children: [
1650
- /* @__PURE__ */ jsxRuntime.jsxs(
1651
- "label",
1652
- {
1653
- htmlFor: checkboxId,
1654
- className: utils_index.cn(
1655
- "inline-flex items-center gap-2",
1656
- disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
1657
- ),
1658
- "data-testid": testId ? `${testId}-label` : void 0,
1659
- children: [
1660
- /* @__PURE__ */ jsxRuntime.jsx(
1661
- "input",
1662
- {
1663
- ref: setRefs,
1664
- type: "checkbox",
1665
- id: checkboxId,
1666
- checked,
1667
- disabled,
1668
- "aria-invalid": hasError ? "true" : void 0,
1669
- "aria-describedby": errorId,
1670
- onChange: handleChange,
1671
- "data-testid": testId ? `${testId}-checkbox` : void 0,
1672
- className: utils_index.cn(
1673
- sizeStyles$9[size],
1674
- "rounded border transition-colors",
1675
- "focus:ring-2 focus:ring-offset-0",
1676
- "disabled:cursor-not-allowed",
1677
- // Light mode
1678
- "border-primary-300 bg-white",
1679
- "checked:bg-gold-500 checked:border-gold-500",
1680
- "checked:hover:bg-gold-600 checked:hover:border-gold-600",
1681
- "indeterminate:bg-gold-500 indeterminate:border-gold-500",
1682
- "focus:ring-gold-500/20",
1683
- "disabled:bg-primary-100",
1684
- // Dark mode
1685
- "dark:border-primary-600 dark:bg-primary-800",
1686
- "dark:checked:bg-gold-500 dark:checked:border-gold-500",
1687
- "dark:checked:hover:bg-gold-400 dark:checked:hover:border-gold-400",
1688
- "dark:indeterminate:bg-gold-500 dark:indeterminate:border-gold-500",
1689
- "dark:focus:ring-gold-400/30",
1690
- "dark:disabled:bg-primary-700",
1691
- // Error state
1692
- hasError && "border-error dark:border-error/70"
1693
- ),
1694
- ...props
1695
- }
1696
- ),
1697
- label && /* @__PURE__ */ jsxRuntime.jsx(
1698
- "span",
1699
- {
1700
- className: utils_index.cn(
1701
- labelSizeStyles$1[size],
1702
- "text-primary-700 dark:text-primary-200",
1703
- hasError && "text-error"
1704
- ),
1705
- children: label
1706
- }
1707
- )
1708
- ]
1709
- }
1710
- ),
1711
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
1712
- "p",
1713
- {
1714
- id: errorId,
1715
- role: hasError ? "alert" : void 0,
1716
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
1717
- className: utils_index.cn(
1718
- "mt-1 text-sm",
1719
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
1720
- ),
1721
- children: error || helperText
1722
- }
1723
- )
1724
- ] });
1725
- }
1726
- );
1727
- Checkbox.displayName = "Checkbox";
1728
- const sizeStyles$8 = {
1729
- sm: "h-4 w-4",
1730
- md: "h-5 w-5",
1731
- lg: "h-6 w-6"
1732
- };
1733
- const labelSizeStyles = {
1734
- sm: "text-xs",
1735
- md: "text-sm",
1736
- lg: "text-base"
1737
- };
1738
- const Radio = React.forwardRef(
1739
- ({
1740
- label,
1741
- size = "md",
1742
- disabled = false,
1743
- error = false,
1744
- className,
1745
- id,
1746
- testId,
1747
- ...props
1748
- }, ref) => {
1749
- const radioId = id || (label ? `${props.name}-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
1750
- return /* @__PURE__ */ jsxRuntime.jsxs(
1751
- "label",
1752
- {
1753
- htmlFor: radioId,
1754
- className: utils_index.cn(
1755
- "inline-flex items-center gap-2",
1756
- disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
1757
- className
1758
- ),
1759
- "data-testid": testId,
1760
- children: [
1761
- /* @__PURE__ */ jsxRuntime.jsx(
1762
- "input",
1763
- {
1764
- ref,
1765
- type: "radio",
1766
- id: radioId,
1767
- disabled,
1768
- "data-testid": testId ? `${testId}-radio` : void 0,
1769
- className: utils_index.cn(
1770
- sizeStyles$8[size],
1771
- "border transition-colors",
1772
- "focus:ring-2 focus:ring-offset-0",
1773
- "disabled:cursor-not-allowed",
1774
- // Light mode
1775
- "border-primary-300 bg-white",
1776
- "checked:border-gold-500 checked:bg-gold-500",
1777
- "checked:hover:border-gold-600 checked:hover:bg-gold-600",
1778
- "focus:ring-gold-500/20",
1779
- "disabled:bg-primary-100",
1780
- // Dark mode
1781
- "dark:border-primary-600 dark:bg-primary-800",
1782
- "dark:checked:border-gold-500 dark:checked:bg-gold-500",
1783
- "dark:checked:hover:border-gold-400 dark:checked:hover:bg-gold-400",
1784
- "dark:focus:ring-gold-400/30",
1785
- "dark:disabled:bg-primary-700",
1786
- // Error state
1787
- error && "border-error dark:border-error/70"
1788
- ),
1789
- ...props
1790
- }
1791
- ),
1792
- label && /* @__PURE__ */ jsxRuntime.jsx(
1793
- "span",
1794
- {
1795
- className: utils_index.cn(
1796
- labelSizeStyles[size],
1797
- "text-primary-700 dark:text-primary-200",
1798
- error && "text-error"
1799
- ),
1800
- "data-testid": testId ? `${testId}-label` : void 0,
1801
- children: label
1802
- }
1803
- )
1804
- ]
1805
- }
1806
- );
1807
- }
1808
- );
1809
- Radio.displayName = "Radio";
1810
- function RadioGroup({
1811
- name,
1812
- options,
1813
- value,
1814
- onChange,
1815
- label,
1816
- size = "md",
1817
- error,
1818
- helperText,
1819
- disabled = false,
1820
- orientation = "vertical",
1821
- className,
1822
- isLoading = false,
1823
- testId
1824
- }) {
1825
- const hasError = !!error;
1826
- const groupId = `${name}-group`;
1827
- const isDisabled = disabled || isLoading;
1828
- const handleChange = (e2) => {
1829
- onChange?.(e2.target.value);
1830
- };
1831
- return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className, role: "radiogroup", "aria-labelledby": label ? groupId : void 0, "data-testid": testId, children: [
1832
- label && /* @__PURE__ */ jsxRuntime.jsxs(
1833
- "legend",
1834
- {
1835
- id: groupId,
1836
- className: "mb-3 flex items-center gap-2 text-sm font-medium text-primary-700 dark:text-white",
1837
- children: [
1838
- label,
1839
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "xs", color: "primary" })
1840
- ]
1841
- }
1842
- ),
1843
- /* @__PURE__ */ jsxRuntime.jsx(
1844
- "div",
1845
- {
1846
- className: utils_index.cn(
1847
- orientation === "vertical" ? "space-y-2" : "flex flex-wrap gap-4"
1848
- ),
1849
- children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
1850
- Radio,
1851
- {
1852
- name,
1853
- value: option.value,
1854
- label: option.label,
1855
- size,
1856
- disabled: isDisabled || option.disabled,
1857
- error: hasError,
1858
- checked: value === option.value,
1859
- onChange: handleChange,
1860
- testId: testId ? `${testId}-option-${index}` : void 0
1861
- },
1862
- option.value
1863
- ))
1864
- }
1865
- ),
1866
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
1867
- "p",
1868
- {
1869
- role: hasError ? "alert" : void 0,
1870
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
1871
- className: utils_index.cn(
1872
- "mt-2 text-sm",
1873
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
1874
- ),
1875
- children: error || helperText
1876
- }
1877
- )
1878
- ] });
1879
- }
1880
- RadioGroup.displayName = "RadioGroup";
1881
- const sizeStyles$7 = {
1882
- sm: {
1883
- switch: "h-5 w-9",
1884
- dot: "h-3 w-3",
1885
- translate: "translate-x-4"
1886
- },
1887
- md: {
1888
- switch: "h-6 w-11",
1889
- dot: "h-4 w-4",
1890
- translate: "translate-x-5"
1891
- },
1892
- lg: {
1893
- switch: "h-7 w-14",
1894
- dot: "h-5 w-5",
1895
- translate: "translate-x-7"
1896
- }
1897
- };
1898
- function Toggle({
1899
- enabled,
1900
- onChange,
1901
- label,
1902
- description,
1903
- disabled = false,
1904
- size = "md",
1905
- className,
1906
- isLoading = false,
1907
- testId
1908
- }) {
1909
- const currentSize = sizeStyles$7[size];
1910
- const isDisabled = disabled || isLoading;
1911
- return /* @__PURE__ */ jsxRuntime.jsx(W, { className, "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1912
- (label || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 mr-4", children: [
1913
- label && /* @__PURE__ */ jsxRuntime.jsx(
1914
- style.Z,
1915
- {
1916
- className: utils_index.cn(
1917
- "text-sm font-medium",
1918
- "text-primary-700 dark:text-white",
1919
- isDisabled ? "opacity-50" : "cursor-pointer"
1920
- ),
1921
- children: label
1922
- }
1923
- ),
1924
- description && /* @__PURE__ */ jsxRuntime.jsx(style.M, { className: "text-sm text-primary-500 dark:text-primary-400", children: description })
1925
- ] }),
1926
- /* @__PURE__ */ jsxRuntime.jsx(
1927
- tt,
1928
- {
1929
- checked: enabled,
1930
- disabled: isDisabled,
1931
- onChange,
1932
- "aria-label": !label ? "Toggle" : void 0,
1933
- "data-testid": testId ? `${testId}-toggle` : void 0,
1934
- className: utils_index.cn(
1935
- currentSize.switch,
1936
- "relative inline-flex shrink-0 cursor-pointer rounded-full",
1937
- "border-2 border-transparent",
1938
- "transition-colors duration-200 ease-in-out",
1939
- "focus:outline-none focus:ring-2 focus:ring-offset-2",
1940
- "disabled:cursor-not-allowed disabled:opacity-50",
1941
- // Light mode
1942
- enabled ? "bg-gold-500" : "bg-primary-200",
1943
- "focus:ring-gold-500/20",
1944
- // Dark mode
1945
- enabled ? "dark:bg-gold-500" : "dark:bg-primary-600",
1946
- "dark:focus:ring-gold-400/30",
1947
- "dark:focus:ring-offset-primary-900"
1948
- ),
1949
- children: /* @__PURE__ */ jsxRuntime.jsx(
1950
- "span",
1951
- {
1952
- "aria-hidden": "true",
1953
- className: utils_index.cn(
1954
- currentSize.dot,
1955
- "pointer-events-none inline-flex items-center justify-center transform rounded-full shadow ring-0",
1956
- "transition duration-200 ease-in-out",
1957
- // Light mode
1958
- "bg-white",
1959
- // Position
1960
- enabled ? currentSize.translate : "translate-x-0"
1961
- ),
1962
- children: isLoading && /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "xs", color: "primary" })
1963
- }
1964
- )
1965
- }
1966
- )
1967
- ] }) });
1968
- }
1969
- Toggle.displayName = "Toggle";
1970
- const ChevronIcon$2 = () => /* @__PURE__ */ jsxRuntime.jsx(
1971
- "svg",
1972
- {
1973
- className: "h-5 w-5 text-primary-400 dark:text-primary-500",
1974
- fill: "currentColor",
1975
- viewBox: "0 0 20 20",
1976
- "aria-hidden": "true",
1977
- children: /* @__PURE__ */ jsxRuntime.jsx(
1978
- "path",
1979
- {
1980
- fillRule: "evenodd",
1981
- clipRule: "evenodd",
1982
- d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
1983
- }
1984
- )
1985
- }
1986
- );
1987
- const CheckIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
1988
- "svg",
1989
- {
1990
- className: "h-5 w-5",
1991
- fill: "currentColor",
1992
- viewBox: "0 0 20 20",
1993
- "aria-hidden": "true",
1994
- children: /* @__PURE__ */ jsxRuntime.jsx(
1995
- "path",
1996
- {
1997
- fillRule: "evenodd",
1998
- clipRule: "evenodd",
1999
- d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
2000
- }
2001
- )
2002
- }
2003
- );
2004
- function Combobox({
2005
- options,
2006
- value,
2007
- onChange,
2008
- placeholder = "Search...",
2009
- label,
2010
- error,
2011
- helperText,
2012
- disabled = false,
2013
- required = false,
2014
- fullWidth = false,
2015
- className,
2016
- isLoading = false,
2017
- loadingText = "Loading...",
2018
- emptyText = "No results found",
2019
- onSearch,
2020
- testId
2021
- }) {
2022
- const [query, setQuery] = React.useState("");
2023
- const hasError = !!error;
2024
- const isDisabled = disabled || isLoading;
2025
- const labelId = React.useId();
2026
- const selectedOption = React.useMemo(
2027
- () => options.find((opt) => opt.value === value),
2028
- [options, value]
2029
- );
2030
- const filteredOptions = React.useMemo(
2031
- () => query === "" ? options : options.filter(
2032
- (option) => option.label.toLowerCase().includes(query.toLowerCase())
2033
- ),
2034
- [options, query]
2035
- );
2036
- const handleChange = (newValue) => {
2037
- onChange?.(newValue);
2038
- setQuery("");
2039
- };
2040
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn(fullWidth ? "w-full" : "w-auto", className), "data-testid": testId, children: [
2041
- label && /* @__PURE__ */ jsxRuntime.jsxs(
2042
- "label",
2043
- {
2044
- id: labelId,
2045
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
2046
- "data-testid": testId ? `${testId}-label` : void 0,
2047
- children: [
2048
- label,
2049
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
2050
- ]
2051
- }
2052
- ),
2053
- /* @__PURE__ */ jsxRuntime.jsx(
2054
- style.Ht,
2055
- {
2056
- value: value ?? null,
2057
- onChange: handleChange,
2058
- disabled: isDisabled,
2059
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
2060
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
2061
- /* @__PURE__ */ jsxRuntime.jsx(
2062
- style.ko,
2063
- {
2064
- "aria-label": !label ? placeholder : void 0,
2065
- "aria-labelledby": label ? labelId : void 0,
2066
- displayValue: () => selectedOption?.label || "",
2067
- onChange: (e2) => {
2068
- const newQuery = e2.target.value;
2069
- setQuery(newQuery);
2070
- onSearch?.(newQuery);
2071
- },
2072
- placeholder,
2073
- "data-testid": testId ? `${testId}-input` : void 0,
2074
- className: utils_index.cn(
2075
- // Base styles - Light mode
2076
- "w-full rounded-md border bg-white px-4 py-2.5 pr-10 text-sm text-primary-900",
2077
- "transition-colors duration-normal",
2078
- "placeholder:text-primary-400",
2079
- "focus:outline-none focus:ring-2",
2080
- "disabled:cursor-not-allowed disabled:bg-primary-50 disabled:text-primary-500",
2081
- // Base styles - Dark mode
2082
- "dark:bg-primary-800 dark:text-primary-100",
2083
- "dark:placeholder:text-primary-500",
2084
- "dark:disabled:bg-primary-900 dark:disabled:text-primary-600",
2085
- // Border and focus styles
2086
- hasError ? "border-error focus:border-error focus:ring-error/20 dark:border-error/70 dark:focus:ring-error/30" : "border-primary-300 focus:border-gold-500 focus:ring-gold-500/20 dark:border-primary-600 dark:focus:border-gold-400 dark:focus:ring-gold-400/30"
2087
- )
2088
- }
2089
- ),
2090
- /* @__PURE__ */ jsxRuntime.jsx(
2091
- style.Bo,
2092
- {
2093
- "aria-label": "Toggle options",
2094
- className: "absolute inset-y-0 right-0 flex items-center pr-3",
2095
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary", label: loadingText }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon$2, {})
2096
- }
2097
- )
2098
- ] }),
2099
- /* @__PURE__ */ jsxRuntime.jsx(
2100
- style.Ke,
2101
- {
2102
- as: React.Fragment,
2103
- leave: "transition ease-in duration-100",
2104
- leaveFrom: "opacity-100",
2105
- leaveTo: "opacity-0",
2106
- afterLeave: () => setQuery(""),
2107
- children: /* @__PURE__ */ jsxRuntime.jsx(
2108
- style.Uo,
2109
- {
2110
- anchor: "bottom start",
2111
- className: "z-dropdown max-h-60 w-[var(--input-width)] overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-primary-800 dark:ring-primary-700 [--anchor-gap:4px]",
2112
- "data-testid": testId ? `${testId}-options` : void 0,
2113
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 px-4 py-2.5 text-primary-500 dark:text-primary-400", children: [
2114
- /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary" }),
2115
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: loadingText })
2116
- ] }) : filteredOptions.length === 0 && query !== "" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative cursor-default select-none px-4 py-2.5 text-primary-500 dark:text-primary-400", children: emptyText }) : filteredOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsx(
2117
- style.Ho,
2118
- {
2119
- value: option.value,
2120
- disabled: option.disabled,
2121
- "data-testid": testId ? `${testId}-option-${index}` : void 0,
2122
- className: ({ active, selected }) => utils_index.cn(
2123
- "relative cursor-pointer select-none py-2.5 pl-10 pr-4",
2124
- // Light mode
2125
- active ? "bg-gold-50 text-primary-900" : "text-primary-900",
2126
- // Dark mode
2127
- active ? "dark:bg-primary-700 dark:text-primary-100" : "dark:text-primary-200",
2128
- option.disabled && "cursor-not-allowed opacity-50",
2129
- selected && "font-medium"
2130
- ),
2131
- children: ({ selected }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2132
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate", children: option.label }),
2133
- selected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-y-0 left-0 flex items-center pl-3 text-gold-600 dark:text-gold-400", children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) })
2134
- ] })
2135
- },
2136
- option.value
2137
- ))
2138
- }
2139
- )
2140
- }
2141
- )
2142
- ] })
2143
- }
2144
- ),
2145
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
2146
- "p",
2147
- {
2148
- role: hasError ? "alert" : void 0,
2149
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
2150
- className: utils_index.cn(
2151
- "mt-1.5 text-sm",
2152
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
2153
- ),
2154
- children: error || helperText
2155
- }
2156
- )
2157
- ] });
2158
- }
2159
- Combobox.displayName = "Combobox";
2160
- const variantStyles$3 = {
2161
- default: utils_index.cn(
2162
- "bg-primary-100 text-primary-700 border-primary-200",
2163
- "dark:bg-primary-800 dark:text-primary-200 dark:border-primary-700"
2164
- ),
2165
- success: utils_index.cn(
2166
- "bg-success-light text-[#166534] border-success/20",
2167
- "dark:bg-success/20 dark:text-[#86efac] dark:border-success/30"
2168
- ),
2169
- warning: utils_index.cn(
2170
- "bg-warning-light text-[#854d0e] border-warning/20",
2171
- "dark:bg-warning/20 dark:text-[#fde047] dark:border-warning/30"
2172
- ),
2173
- error: utils_index.cn(
2174
- "bg-error-light text-[#991b1b] border-error/20",
2175
- "dark:bg-error/20 dark:text-[#fca5a5] dark:border-error/30"
2176
- ),
2177
- info: utils_index.cn(
2178
- "bg-info-light text-[#1e40af] border-info/20",
2179
- "dark:bg-info/20 dark:text-[#93c5fd] dark:border-info/30"
2180
- ),
2181
- gold: utils_index.cn(
2182
- "bg-gold-100 text-gold-800 border-gold-200",
2183
- "dark:bg-gold-900/50 dark:text-gold-300 dark:border-gold-700"
2184
- )
2185
- };
2186
- const sizeStyles$6 = {
2187
- sm: "px-2 py-0.5 text-xs",
2188
- md: "px-2.5 py-1 text-sm",
2189
- lg: "px-3 py-1.5 text-base"
2190
- };
2191
- const Badge = React.forwardRef(
2192
- ({ variant = "default", size = "md", children, className, testId, ...props }, ref) => {
2193
- return /* @__PURE__ */ jsxRuntime.jsx(
2194
- "span",
2195
- {
2196
- ref,
2197
- className: utils_index.cn(
2198
- "inline-flex items-center justify-center font-medium rounded-full border",
2199
- variantStyles$3[variant],
2200
- sizeStyles$6[size],
2201
- className
2202
- ),
2203
- "data-testid": testId,
2204
- ...props,
2205
- children
2206
- }
2207
- );
2208
- }
2209
- );
2210
- Badge.displayName = "Badge";
2211
- const SortIcon = ({ direction }) => /* @__PURE__ */ jsxRuntime.jsx(
2212
- "svg",
2213
- {
2214
- className: utils_index.cn(
2215
- "ml-1 h-4 w-4 inline-block",
2216
- direction ? "text-gold-500" : "text-primary-400 dark:text-primary-500"
2217
- ),
2218
- fill: "none",
2219
- viewBox: "0 0 24 24",
2220
- stroke: "currentColor",
2221
- "aria-hidden": "true",
2222
- children: direction === "asc" ? /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) : direction === "desc" ? /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) : /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 9l4-4 4 4M16 15l-4 4-4-4" })
2223
- }
2224
- );
2225
- const Table = React.forwardRef(
2226
- ({ fullWidth = true, striped = false, hoverable = false, compact = false, className, children, ...props }, ref) => {
2227
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2228
- "table",
2229
- {
2230
- ref,
2231
- className: utils_index.cn(
2232
- "border-collapse text-sm",
2233
- fullWidth && "w-full",
2234
- className
2235
- ),
2236
- "data-striped": striped || void 0,
2237
- "data-hoverable": hoverable || void 0,
2238
- "data-compact": compact || void 0,
2239
- ...props,
2240
- children
2241
- }
2242
- ) });
2243
- }
2244
- );
2245
- Table.displayName = "Table";
2246
- const TableHeader = React.forwardRef(
2247
- ({ className, children, ...props }, ref) => {
2248
- return /* @__PURE__ */ jsxRuntime.jsx(
2249
- "thead",
2250
- {
2251
- ref,
2252
- className: utils_index.cn(
2253
- "bg-primary-50 dark:bg-primary-800",
2254
- className
2255
- ),
2256
- ...props,
2257
- children
2258
- }
2259
- );
2260
- }
2261
- );
2262
- TableHeader.displayName = "TableHeader";
2263
- const TableBody = React.forwardRef(
2264
- ({ className, children, ...props }, ref) => {
2265
- return /* @__PURE__ */ jsxRuntime.jsx(
2266
- "tbody",
2267
- {
2268
- ref,
2269
- className: utils_index.cn(
2270
- "divide-y divide-primary-200 dark:divide-primary-700",
2271
- className
2272
- ),
2273
- ...props,
2274
- children
2275
- }
2276
- );
2277
- }
2278
- );
2279
- TableBody.displayName = "TableBody";
2280
- const TableRow = React.forwardRef(
2281
- ({ selected = false, className, children, ...props }, ref) => {
2282
- return /* @__PURE__ */ jsxRuntime.jsx(
2283
- "tr",
2284
- {
2285
- ref,
2286
- className: utils_index.cn(
2287
- "border-b border-primary-200 dark:border-primary-700",
2288
- "transition-colors duration-normal",
2289
- // Striped rows (controlled by parent table data attribute)
2290
- "[table[data-striped]_&:nth-child(even)]:bg-primary-50 [table[data-striped]_&:nth-child(even)]:dark:bg-primary-800/50",
2291
- // Hoverable rows (controlled by parent table data attribute)
2292
- "[table[data-hoverable]_&]:hover:bg-primary-100 [table[data-hoverable]_&]:dark:hover:bg-primary-700/50",
2293
- selected && "bg-gold-50 dark:bg-gold-900/20",
2294
- className
2295
- ),
2296
- "data-selected": selected || void 0,
2297
- ...props,
2298
- children
2299
- }
2300
- );
2301
- }
2302
- );
2303
- TableRow.displayName = "TableRow";
2304
- const TableHead = React.forwardRef(
2305
- ({ sortable = false, sortDirection = null, onSort, align = "left", className, children, ...props }, ref) => {
2306
- const alignmentClass = {
2307
- left: "text-left",
2308
- center: "text-center",
2309
- right: "text-right"
2310
- }[align];
2311
- return /* @__PURE__ */ jsxRuntime.jsx(
2312
- "th",
2313
- {
2314
- ref,
2315
- scope: "col",
2316
- className: utils_index.cn(
2317
- "px-4 py-3 font-semibold text-primary-700 dark:text-primary-200",
2318
- "[table[data-compact]_&]:px-3 [table[data-compact]_&]:py-2",
2319
- alignmentClass,
2320
- sortable && "cursor-pointer select-none hover:text-primary-900 dark:hover:text-white",
2321
- className
2322
- ),
2323
- onClick: sortable ? onSort : void 0,
2324
- "aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : void 0,
2325
- ...props,
2326
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center", children: [
2327
- children,
2328
- sortable && /* @__PURE__ */ jsxRuntime.jsx(SortIcon, { direction: sortDirection })
2329
- ] })
2330
- }
2331
- );
2332
- }
2333
- );
2334
- TableHead.displayName = "TableHead";
2335
- const TableCell = React.forwardRef(
2336
- ({ align = "left", className, children, ...props }, ref) => {
2337
- const alignmentClass = {
2338
- left: "text-left",
2339
- center: "text-center",
2340
- right: "text-right"
2341
- }[align];
2342
- return /* @__PURE__ */ jsxRuntime.jsx(
2343
- "td",
2344
- {
2345
- ref,
2346
- className: utils_index.cn(
2347
- "px-4 py-3 text-primary-900 dark:text-primary-100",
2348
- "[table[data-compact]_&]:px-3 [table[data-compact]_&]:py-2",
2349
- alignmentClass,
2350
- className
2351
- ),
2352
- ...props,
2353
- children
2354
- }
2355
- );
2356
- }
2357
- );
2358
- TableCell.displayName = "TableCell";
2359
- const sizeStyles$5 = {
2360
- sm: "px-3 py-1.5 text-sm",
2361
- md: "px-4 py-2 text-sm",
2362
- lg: "px-5 py-2.5 text-base"
2363
- };
2364
- function Tabs({
2365
- tabs,
2366
- activeTab,
2367
- onChange,
2368
- fullWidth = false,
2369
- variant = "default",
2370
- size = "md",
2371
- className,
2372
- "aria-label": ariaLabel = "Navigation tabs",
2373
- testId,
2374
- ...props
2375
- }) {
2376
- const selectedIndex = React.useMemo(
2377
- () => tabs.findIndex((tab) => tab.key === activeTab),
2378
- [tabs, activeTab]
2379
- );
2380
- const handleChange = (index) => {
2381
- if (onChange && tabs[index]) {
2382
- onChange(tabs[index].key);
2383
- }
2384
- };
2385
- return /* @__PURE__ */ jsxRuntime.jsx(
2386
- Be,
2387
- {
2388
- selectedIndex: selectedIndex >= 0 ? selectedIndex : 0,
2389
- onChange: handleChange,
2390
- children: /* @__PURE__ */ jsxRuntime.jsx(
2391
- We,
2392
- {
2393
- "aria-label": ariaLabel,
2394
- className: utils_index.cn(
2395
- "flex",
2396
- variant === "default" && "border-b border-primary-200 dark:border-primary-700",
2397
- variant === "pills" && "gap-1 p-1 rounded-lg bg-primary-100 dark:bg-primary-800",
2398
- fullWidth && "w-full",
2399
- className
2400
- ),
2401
- "data-testid": testId,
2402
- ...props,
2403
- children: tabs.map((tab, index) => /* @__PURE__ */ jsxRuntime.jsx(
2404
- dt,
2405
- {
2406
- disabled: tab.disabled,
2407
- "data-testid": testId ? `${testId}-tab-${index}` : void 0,
2408
- className: ({ selected }) => utils_index.cn(
2409
- "relative outline-none transition-colors duration-normal",
2410
- "focus-visible:ring-2 focus-visible:ring-gold-500/50",
2411
- sizeStyles$5[size],
2412
- fullWidth && "flex-1",
2413
- // Default variant styles
2414
- variant === "default" && [
2415
- "border-b-2 -mb-px",
2416
- selected ? "border-gold-500 text-gold-600 dark:text-gold-400 font-medium" : "border-transparent text-primary-500 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-200 hover:border-primary-300 dark:hover:border-primary-600",
2417
- tab.disabled && "cursor-not-allowed opacity-50 hover:border-transparent hover:text-primary-500"
2418
- ],
2419
- // Pills variant styles
2420
- variant === "pills" && [
2421
- "rounded-md",
2422
- selected ? "bg-white dark:bg-primary-700 text-primary-900 dark:text-white shadow-sm font-medium" : "text-primary-600 dark:text-primary-300 hover:text-primary-900 dark:hover:text-white",
2423
- tab.disabled && "cursor-not-allowed opacity-50"
2424
- ]
2425
- ),
2426
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
2427
- tab.label,
2428
- tab.count !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
2429
- "span",
2430
- {
2431
- className: utils_index.cn(
2432
- "inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1.5 rounded-full text-xs font-medium",
2433
- "bg-primary-200 text-primary-600 dark:bg-primary-700 dark:text-primary-300"
2434
- ),
2435
- children: tab.count
2436
- }
2437
- )
2438
- ] })
2439
- },
2440
- tab.key
2441
- ))
2442
- }
2443
- )
2444
- }
2445
- );
2446
- }
2447
- Tabs.displayName = "Tabs";
2448
- function TabContentPanels({
2449
- tabs: _tabs,
2450
- activeTab,
2451
- children,
2452
- className,
2453
- isLoading = false,
2454
- testId,
2455
- ...props
2456
- }) {
2457
- const activeContent = activeTab && children[activeTab];
2458
- return /* @__PURE__ */ jsxRuntime.jsxs(
2459
- "div",
2460
- {
2461
- role: "tabpanel",
2462
- className: utils_index.cn("relative mt-4", className),
2463
- "data-testid": testId,
2464
- ...props,
2465
- children: [
2466
- activeContent,
2467
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-white/60 dark:bg-primary-800/60", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "md", color: "primary" }) })
2468
- ]
2469
- }
2470
- );
2471
- }
2472
- TabContentPanels.displayName = "TabContentPanels";
2473
- const ChevronIcon$1 = () => /* @__PURE__ */ jsxRuntime.jsx(
2474
- "svg",
2475
- {
2476
- className: "h-4 w-4 text-primary-400 dark:text-primary-500 flex-shrink-0",
2477
- fill: "currentColor",
2478
- viewBox: "0 0 20 20",
2479
- "aria-hidden": "true",
2480
- children: /* @__PURE__ */ jsxRuntime.jsx(
2481
- "path",
2482
- {
2483
- fillRule: "evenodd",
2484
- clipRule: "evenodd",
2485
- d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
2486
- }
2487
- )
2488
- }
2489
- );
2490
- const HomeIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
2491
- "svg",
2492
- {
2493
- className: "h-4 w-4 flex-shrink-0",
2494
- fill: "currentColor",
2495
- viewBox: "0 0 20 20",
2496
- "aria-hidden": "true",
2497
- children: /* @__PURE__ */ jsxRuntime.jsx(
2498
- "path",
2499
- {
2500
- fillRule: "evenodd",
2501
- clipRule: "evenodd",
2502
- d: "M9.293 2.293a1 1 0 011.414 0l7 7A1 1 0 0117 11h-1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-3a1 1 0 00-1-1H9a1 1 0 00-1 1v3a1 1 0 01-1 1H5a1 1 0 01-1-1v-6H3a1 1 0 01-.707-1.707l7-7z"
2503
- }
2504
- )
2505
- }
2506
- );
2507
- const EllipsisButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx(
2508
- "button",
2509
- {
2510
- type: "button",
2511
- onClick,
2512
- className: utils_index.cn(
2513
- "px-1.5 py-0.5 rounded text-primary-500 dark:text-primary-400",
2514
- "hover:bg-primary-100 dark:hover:bg-primary-800",
2515
- "focus:outline-none focus:ring-2 focus:ring-gold-500/50"
2516
- ),
2517
- "aria-label": "Show more breadcrumbs",
2518
- children: "..."
2519
- }
2520
- );
2521
- const Breadcrumbs = React.forwardRef(
2522
- ({
2523
- items,
2524
- separator,
2525
- maxItems = 0,
2526
- renderLink,
2527
- className,
2528
- testId,
2529
- ...props
2530
- }, ref) => {
2531
- const [isExpanded, setIsExpanded] = React.useState(false);
2532
- const defaultRenderLink = (item, children) => /* @__PURE__ */ jsxRuntime.jsx(
2533
- "a",
2534
- {
2535
- href: item.href,
2536
- className: utils_index.cn(
2537
- "text-primary-500 dark:text-primary-400",
2538
- "hover:text-primary-700 dark:hover:text-primary-200",
2539
- "transition-colors duration-normal"
2540
- ),
2541
- children
2542
- }
2543
- );
2544
- const linkRenderer = renderLink || defaultRenderLink;
2545
- let displayItems = items;
2546
- const shouldCollapse = maxItems > 0 && items.length > maxItems && !isExpanded;
2547
- if (shouldCollapse) {
2548
- const firstItem = items[0];
2549
- const lastItems = items.slice(-(maxItems - 1));
2550
- displayItems = [firstItem, ...lastItems];
2551
- }
2552
- const renderItem = (item, index, isLast) => {
2553
- const content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
2554
- index === 0 && !item.icon && /* @__PURE__ */ jsxRuntime.jsx(HomeIcon, {}),
2555
- item.icon,
2556
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: isLast ? "font-medium" : "", children: item.label })
2557
- ] });
2558
- if (isLast || !item.href) {
2559
- return /* @__PURE__ */ jsxRuntime.jsx(
2560
- "span",
2561
- {
2562
- className: utils_index.cn(
2563
- "text-primary-900 dark:text-white",
2564
- isLast && "font-medium"
2565
- ),
2566
- "aria-current": isLast ? "page" : void 0,
2567
- children: content
2568
- }
2569
- );
2570
- }
2571
- return linkRenderer(item, content);
2572
- };
2573
- const separatorElement = separator || /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon$1, {});
2574
- return /* @__PURE__ */ jsxRuntime.jsx(
2575
- "nav",
2576
- {
2577
- ref,
2578
- "aria-label": "Breadcrumb",
2579
- className: utils_index.cn("text-sm", className),
2580
- "data-testid": testId,
2581
- ...props,
2582
- children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex items-center flex-wrap gap-1", children: displayItems.map((item, index) => {
2583
- const isLast = index === displayItems.length - 1;
2584
- const showEllipsis = shouldCollapse && index === 0;
2585
- return /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
2586
- /* @__PURE__ */ jsxRuntime.jsx(
2587
- "li",
2588
- {
2589
- className: "inline-flex items-center",
2590
- "data-testid": testId ? `${testId}-item-${index}` : void 0,
2591
- children: renderItem(item, index, isLast)
2592
- }
2593
- ),
2594
- showEllipsis && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2595
- /* @__PURE__ */ jsxRuntime.jsx("li", { className: "inline-flex items-center", "aria-hidden": "true", children: separatorElement }),
2596
- /* @__PURE__ */ jsxRuntime.jsx("li", { className: "inline-flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(EllipsisButton, { onClick: () => setIsExpanded(true) }) })
2597
- ] }),
2598
- !isLast && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "inline-flex items-center", "aria-hidden": "true", children: separatorElement })
2599
- ] }, item.label + index);
2600
- }) })
2601
- }
2602
- );
2603
- }
2604
- );
2605
- Breadcrumbs.displayName = "Breadcrumbs";
2606
- const variantStyles$2 = {
2607
- text: "rounded",
2608
- circular: "rounded-full",
2609
- rectangular: "rounded-md"
2610
- };
2611
- const Skeleton = React.forwardRef(
2612
- ({
2613
- variant = "text",
2614
- width,
2615
- height,
2616
- animate = true,
2617
- lines = 1,
2618
- label = "Loading...",
2619
- className,
2620
- style: style2,
2621
- testId,
2622
- ...props
2623
- }, ref) => {
2624
- const widthValue = typeof width === "number" ? `${width}px` : width;
2625
- const heightValue = typeof height === "number" ? `${height}px` : height;
2626
- const finalHeight = heightValue || (variant === "text" ? "1em" : void 0);
2627
- if (variant === "text" && lines > 1) {
2628
- return /* @__PURE__ */ jsxRuntime.jsxs(
2629
- "div",
2630
- {
2631
- ref,
2632
- className: utils_index.cn("flex flex-col gap-2", className),
2633
- role: "status",
2634
- "aria-label": label,
2635
- "aria-busy": "true",
2636
- "data-testid": testId,
2637
- ...props,
2638
- children: [
2639
- Array.from({ length: lines }).map((_2, index) => /* @__PURE__ */ jsxRuntime.jsx(
2640
- "div",
2641
- {
2642
- className: utils_index.cn(
2643
- "bg-primary-200 dark:bg-primary-700",
2644
- variantStyles$2[variant],
2645
- animate && "animate-pulse"
2646
- ),
2647
- style: {
2648
- width: index === lines - 1 ? "60%" : widthValue || "100%",
2649
- height: finalHeight,
2650
- ...style2
2651
- }
2652
- },
2653
- index
2654
- )),
2655
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: label })
2656
- ]
2657
- }
2658
- );
2659
- }
2660
- return /* @__PURE__ */ jsxRuntime.jsx(
2661
- "div",
2662
- {
2663
- ref,
2664
- className: utils_index.cn(
2665
- "bg-primary-200 dark:bg-primary-700",
2666
- variantStyles$2[variant],
2667
- animate && "animate-pulse",
2668
- className
2669
- ),
2670
- style: {
2671
- width: widthValue || (variant === "circular" ? heightValue : "100%"),
2672
- height: finalHeight,
2673
- ...style2
2674
- },
2675
- role: "status",
2676
- "aria-label": label,
2677
- "aria-busy": "true",
2678
- "data-testid": testId,
2679
- ...props,
2680
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: label })
2681
- }
2682
- );
2683
- }
2684
- );
2685
- Skeleton.displayName = "Skeleton";
2686
- const defaultIcons$1 = {
2687
- "no-data": /* @__PURE__ */ jsxRuntime.jsx(
2688
- "svg",
2689
- {
2690
- className: "w-full h-full",
2691
- fill: "none",
2692
- viewBox: "0 0 24 24",
2693
- stroke: "currentColor",
2694
- strokeWidth: 1.5,
2695
- "aria-hidden": "true",
2696
- children: /* @__PURE__ */ jsxRuntime.jsx(
2697
- "path",
2698
- {
2699
- strokeLinecap: "round",
2700
- strokeLinejoin: "round",
2701
- d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"
2702
- }
2703
- )
2704
- }
2705
- ),
2706
- "no-results": /* @__PURE__ */ jsxRuntime.jsx(
2707
- "svg",
2708
- {
2709
- className: "w-full h-full",
2710
- fill: "none",
2711
- viewBox: "0 0 24 24",
2712
- stroke: "currentColor",
2713
- strokeWidth: 1.5,
2714
- "aria-hidden": "true",
2715
- children: /* @__PURE__ */ jsxRuntime.jsx(
2716
- "path",
2717
- {
2718
- strokeLinecap: "round",
2719
- strokeLinejoin: "round",
2720
- d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
2721
- }
2722
- )
2723
- }
2724
- ),
2725
- "error": /* @__PURE__ */ jsxRuntime.jsx(
2726
- "svg",
2727
- {
2728
- className: "w-full h-full",
2729
- fill: "none",
2730
- viewBox: "0 0 24 24",
2731
- stroke: "currentColor",
2732
- strokeWidth: 1.5,
2733
- "aria-hidden": "true",
2734
- children: /* @__PURE__ */ jsxRuntime.jsx(
2735
- "path",
2736
- {
2737
- strokeLinecap: "round",
2738
- strokeLinejoin: "round",
2739
- d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
2740
- }
2741
- )
2742
- }
2743
- )
2744
- };
2745
- const sizeStyles$4 = {
2746
- sm: {
2747
- container: "py-6 px-4",
2748
- icon: "w-10 h-10",
2749
- title: "text-sm font-medium",
2750
- description: "text-xs"
2751
- },
2752
- md: {
2753
- container: "py-10 px-6",
2754
- icon: "w-12 h-12",
2755
- title: "text-base font-medium",
2756
- description: "text-sm"
2757
- },
2758
- lg: {
2759
- container: "py-16 px-8",
2760
- icon: "w-16 h-16",
2761
- title: "text-lg font-semibold",
2762
- description: "text-base"
2763
- }
2764
- };
2765
- const typeColors = {
2766
- "no-data": "text-primary-400 dark:text-primary-500",
2767
- "no-results": "text-primary-400 dark:text-primary-500",
2768
- "error": "text-error dark:text-error"
2769
- };
2770
- const EmptyState = React.forwardRef(
2771
- ({
2772
- type = "no-data",
2773
- title,
2774
- description,
2775
- icon,
2776
- action,
2777
- size = "md",
2778
- className,
2779
- testId,
2780
- ...props
2781
- }, ref) => {
2782
- const styles = sizeStyles$4[size];
2783
- return /* @__PURE__ */ jsxRuntime.jsxs(
2784
- "div",
2785
- {
2786
- ref,
2787
- className: utils_index.cn(
2788
- "flex flex-col items-center justify-center text-center",
2789
- styles.container,
2790
- className
2791
- ),
2792
- "data-testid": testId,
2793
- ...props,
2794
- children: [
2795
- /* @__PURE__ */ jsxRuntime.jsx(
2796
- "div",
2797
- {
2798
- className: utils_index.cn(styles.icon, typeColors[type], "mb-4"),
2799
- "data-testid": testId ? `${testId}-icon` : void 0,
2800
- children: icon || defaultIcons$1[type]
2801
- }
2802
- ),
2803
- /* @__PURE__ */ jsxRuntime.jsx(
2804
- "h3",
2805
- {
2806
- className: utils_index.cn(
2807
- styles.title,
2808
- "text-primary-900 dark:text-primary-100",
2809
- "mb-1"
2810
- ),
2811
- "data-testid": testId ? `${testId}-title` : void 0,
2812
- children: title
2813
- }
2814
- ),
2815
- description && /* @__PURE__ */ jsxRuntime.jsx(
2816
- "p",
2817
- {
2818
- className: utils_index.cn(
2819
- styles.description,
2820
- "text-primary-500 dark:text-primary-400",
2821
- "max-w-sm mb-4"
2822
- ),
2823
- "data-testid": testId ? `${testId}-description` : void 0,
2824
- children: description
2825
- }
2826
- ),
2827
- action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", "data-testid": testId ? `${testId}-action` : void 0, children: action })
2828
- ]
2829
- }
2830
- );
2831
- }
2832
- );
2833
- EmptyState.displayName = "EmptyState";
2834
- const ChevronLeftIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) });
2835
- const ChevronRightIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) });
2836
- const sizeStyles$3 = {
2837
- sm: { button: "h-8 min-w-8 px-2 text-sm", text: "text-sm" },
2838
- md: { button: "h-10 min-w-10 px-3 text-sm", text: "text-sm" }
2839
- };
2840
- function getPageNumbers(currentPage, totalPages) {
2841
- const pages = [];
2842
- const showPages = 5;
2843
- if (totalPages <= showPages + 2) {
2844
- for (let i = 1; i <= totalPages; i++) {
2845
- pages.push(i);
2846
- }
2847
- } else {
2848
- pages.push(1);
2849
- if (currentPage <= 3) {
2850
- for (let i = 2; i <= 4; i++) {
2851
- pages.push(i);
2852
- }
2853
- pages.push("ellipsis");
2854
- pages.push(totalPages);
2855
- } else if (currentPage >= totalPages - 2) {
2856
- pages.push("ellipsis");
2857
- for (let i = totalPages - 3; i <= totalPages; i++) {
2858
- pages.push(i);
2859
- }
2860
- } else {
2861
- pages.push("ellipsis");
2862
- pages.push(currentPage - 1);
2863
- pages.push(currentPage);
2864
- pages.push(currentPage + 1);
2865
- pages.push("ellipsis");
2866
- pages.push(totalPages);
2867
- }
2868
- }
2869
- return pages;
2870
- }
2871
- function Pagination({
2872
- currentPage,
2873
- totalPages,
2874
- onPageChange,
2875
- variant = "numbered",
2876
- showPageSize = false,
2877
- pageSizeOptions = [10, 25, 50, 100],
2878
- pageSize = 10,
2879
- onPageSizeChange,
2880
- totalItems,
2881
- disabled = false,
2882
- size = "md",
2883
- className,
2884
- testId
2885
- }) {
2886
- const pageSizeId = React.useId();
2887
- const currentSize = sizeStyles$3[size];
2888
- const canGoPrevious = currentPage > 1;
2889
- const canGoNext = currentPage < totalPages;
2890
- const pageNumbers = React.useMemo(
2891
- () => getPageNumbers(currentPage, totalPages),
2892
- [currentPage, totalPages]
2893
- );
2894
- const itemsRange = React.useMemo(() => {
2895
- if (!totalItems) return null;
2896
- const start = (currentPage - 1) * pageSize + 1;
2897
- const end = Math.min(currentPage * pageSize, totalItems);
2898
- return { start, end };
2899
- }, [currentPage, pageSize, totalItems]);
2900
- const handlePrevious = () => {
2901
- if (canGoPrevious && !disabled) {
2902
- onPageChange(currentPage - 1);
2903
- }
2904
- };
2905
- const handleNext = () => {
2906
- if (canGoNext && !disabled) {
2907
- onPageChange(currentPage + 1);
2908
- }
2909
- };
2910
- const handlePageClick = (page) => {
2911
- if (!disabled && page !== currentPage) {
2912
- onPageChange(page);
2913
- }
2914
- };
2915
- if (variant === "load-more") {
2916
- if (!canGoNext) return null;
2917
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_index.cn("flex justify-center", className), "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsx(
2918
- Button,
2919
- {
2920
- variant: "secondary",
2921
- size: size === "sm" ? "sm" : "md",
2922
- onClick: handleNext,
2923
- disabled,
2924
- "data-testid": testId ? `${testId}-load-more` : void 0,
2925
- children: "Load more"
2926
- }
2927
- ) });
2928
- }
2929
- if (variant === "simple") {
2930
- return /* @__PURE__ */ jsxRuntime.jsxs(
2931
- "nav",
2932
- {
2933
- "aria-label": "Pagination",
2934
- className: utils_index.cn("flex items-center justify-between gap-4", className),
2935
- "data-testid": testId,
2936
- children: [
2937
- /* @__PURE__ */ jsxRuntime.jsxs(
2938
- Button,
2939
- {
2940
- variant: "secondary",
2941
- size: size === "sm" ? "sm" : "md",
2942
- onClick: handlePrevious,
2943
- disabled: disabled || !canGoPrevious,
2944
- "aria-label": "Previous page",
2945
- "data-testid": testId ? `${testId}-prev` : void 0,
2946
- children: [
2947
- /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {}),
2948
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Previous" })
2949
- ]
2950
- }
2951
- ),
2952
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: utils_index.cn("text-primary-600 dark:text-primary-400", currentSize.text), children: [
2953
- "Page ",
2954
- currentPage,
2955
- " of ",
2956
- totalPages
2957
- ] }),
2958
- /* @__PURE__ */ jsxRuntime.jsxs(
2959
- Button,
2960
- {
2961
- variant: "secondary",
2962
- size: size === "sm" ? "sm" : "md",
2963
- onClick: handleNext,
2964
- disabled: disabled || !canGoNext,
2965
- "aria-label": "Next page",
2966
- "data-testid": testId ? `${testId}-next` : void 0,
2967
- children: [
2968
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1", children: "Next" }),
2969
- /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
2970
- ]
2971
- }
2972
- )
2973
- ]
2974
- }
2975
- );
2976
- }
2977
- return /* @__PURE__ */ jsxRuntime.jsxs(
2978
- "nav",
2979
- {
2980
- "aria-label": "Pagination",
2981
- className: utils_index.cn("flex items-center justify-between gap-4", className),
2982
- "data-testid": testId,
2983
- children: [
2984
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
2985
- itemsRange && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: utils_index.cn("text-primary-600 dark:text-primary-400", currentSize.text), children: [
2986
- itemsRange.start,
2987
- "-",
2988
- itemsRange.end,
2989
- " of ",
2990
- totalItems
2991
- ] }),
2992
- showPageSize && onPageSizeChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2993
- /* @__PURE__ */ jsxRuntime.jsx(
2994
- "label",
2995
- {
2996
- htmlFor: pageSizeId,
2997
- className: utils_index.cn("text-primary-600 dark:text-primary-400", currentSize.text),
2998
- children: "Show:"
2999
- }
3000
- ),
3001
- /* @__PURE__ */ jsxRuntime.jsx(
3002
- "select",
3003
- {
3004
- id: pageSizeId,
3005
- value: pageSize,
3006
- onChange: (e2) => onPageSizeChange(Number(e2.target.value)),
3007
- disabled,
3008
- className: utils_index.cn(
3009
- "rounded-md border bg-white px-2 py-1",
3010
- "border-primary-300 dark:border-primary-600",
3011
- "dark:bg-primary-800 dark:text-white",
3012
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
3013
- "disabled:cursor-not-allowed disabled:opacity-50",
3014
- currentSize.text
3015
- ),
3016
- children: pageSizeOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: option }, option))
3017
- }
3018
- )
3019
- ] })
3020
- ] }),
3021
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
3022
- /* @__PURE__ */ jsxRuntime.jsx(
3023
- "button",
3024
- {
3025
- type: "button",
3026
- onClick: handlePrevious,
3027
- disabled: disabled || !canGoPrevious,
3028
- "aria-label": "Previous page",
3029
- "data-testid": testId ? `${testId}-prev` : void 0,
3030
- className: utils_index.cn(
3031
- "inline-flex items-center justify-center rounded-md",
3032
- "border border-primary-300 dark:border-primary-600",
3033
- "bg-white dark:bg-primary-800",
3034
- "text-primary-700 dark:text-primary-300",
3035
- "hover:bg-primary-50 dark:hover:bg-primary-700",
3036
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
3037
- "disabled:cursor-not-allowed disabled:opacity-50",
3038
- "transition-colors",
3039
- currentSize.button
3040
- ),
3041
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
3042
- }
3043
- ),
3044
- pageNumbers.map(
3045
- (page, index) => page === "ellipsis" ? /* @__PURE__ */ jsxRuntime.jsx(
3046
- "span",
3047
- {
3048
- className: utils_index.cn(
3049
- "inline-flex items-center justify-center",
3050
- "text-primary-500 dark:text-primary-400",
3051
- currentSize.button
3052
- ),
3053
- children: "..."
3054
- },
3055
- `ellipsis-${index}`
3056
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3057
- "button",
3058
- {
3059
- type: "button",
3060
- onClick: () => handlePageClick(page),
3061
- disabled,
3062
- "aria-label": `Page ${page}`,
3063
- "aria-current": page === currentPage ? "page" : void 0,
3064
- "data-testid": testId ? `${testId}-page-${page}` : void 0,
3065
- className: utils_index.cn(
3066
- "inline-flex items-center justify-center rounded-md",
3067
- "border transition-colors",
3068
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
3069
- "disabled:cursor-not-allowed disabled:opacity-50",
3070
- page === currentPage ? [
3071
- "border-gold-500 bg-gold-500 text-white",
3072
- "dark:border-gold-400 dark:bg-gold-500"
3073
- ] : [
3074
- "border-primary-300 dark:border-primary-600",
3075
- "bg-white dark:bg-primary-800",
3076
- "text-primary-700 dark:text-primary-300",
3077
- "hover:bg-primary-50 dark:hover:bg-primary-700"
3078
- ],
3079
- currentSize.button
3080
- ),
3081
- children: page
3082
- },
3083
- page
3084
- )
3085
- ),
3086
- /* @__PURE__ */ jsxRuntime.jsx(
3087
- "button",
3088
- {
3089
- type: "button",
3090
- onClick: handleNext,
3091
- disabled: disabled || !canGoNext,
3092
- "aria-label": "Next page",
3093
- "data-testid": testId ? `${testId}-next` : void 0,
3094
- className: utils_index.cn(
3095
- "inline-flex items-center justify-center rounded-md",
3096
- "border border-primary-300 dark:border-primary-600",
3097
- "bg-white dark:bg-primary-800",
3098
- "text-primary-700 dark:text-primary-300",
3099
- "hover:bg-primary-50 dark:hover:bg-primary-700",
3100
- "focus:outline-none focus:ring-2 focus:ring-gold-500/20",
3101
- "disabled:cursor-not-allowed disabled:opacity-50",
3102
- "transition-colors",
3103
- currentSize.button
3104
- ),
3105
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
3106
- }
3107
- )
3108
- ] })
3109
- ]
3110
- }
3111
- );
3112
- }
3113
- Pagination.displayName = "Pagination";
3114
- const ChevronIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
3115
- "svg",
3116
- {
3117
- className: "h-5 w-5 text-primary-400 dark:text-primary-500",
3118
- fill: "currentColor",
3119
- viewBox: "0 0 20 20",
3120
- "aria-hidden": "true",
3121
- children: /* @__PURE__ */ jsxRuntime.jsx(
3122
- "path",
3123
- {
3124
- fillRule: "evenodd",
3125
- d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z",
3126
- clipRule: "evenodd"
3127
- }
3128
- )
3129
- }
3130
- );
3131
- const CloseIcon = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx(
3132
- "svg",
3133
- {
3134
- className: utils_index.cn("h-3 w-3", className),
3135
- fill: "none",
3136
- stroke: "currentColor",
3137
- viewBox: "0 0 24 24",
3138
- "aria-hidden": "true",
3139
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })
3140
- }
3141
- );
3142
- function MultiSelect({
3143
- options,
3144
- value,
3145
- onChange,
3146
- searchable = false,
3147
- onSearch,
3148
- showSelectAll = false,
3149
- selectAllLabel = "Select all",
3150
- placeholder = "Select...",
3151
- maxDisplayedItems = 3,
3152
- isLoading = false,
3153
- loadingText = "Loading...",
3154
- emptyText = "No results found",
3155
- label,
3156
- error,
3157
- helperText,
3158
- required = false,
3159
- disabled = false,
3160
- fullWidth = false,
3161
- className,
3162
- testId
3163
- }) {
3164
- const [query, setQuery] = React.useState("");
3165
- const searchInputRef = React.useRef(null);
3166
- const hasError = !!error;
3167
- const isDisabled = disabled || isLoading;
3168
- const labelId = React.useId();
3169
- const searchId = React.useId();
3170
- const filteredOptions = React.useMemo(() => {
3171
- if (!query) return options;
3172
- return options.filter(
3173
- (opt) => opt.label.toLowerCase().includes(query.toLowerCase())
3174
- );
3175
- }, [options, query]);
3176
- const selectedOptions = React.useMemo(
3177
- () => options.filter((opt) => value.includes(opt.value)),
3178
- [options, value]
3179
- );
3180
- const selectableOptions = React.useMemo(
3181
- () => filteredOptions.filter((opt) => !opt.disabled),
3182
- [filteredOptions]
3183
- );
3184
- const allSelected = selectableOptions.length > 0 && selectableOptions.every((opt) => value.includes(opt.value));
3185
- const someSelected = selectableOptions.some((opt) => value.includes(opt.value));
3186
- const handleSelectAll = (e2) => {
3187
- e2.preventDefault();
3188
- e2.stopPropagation();
3189
- if (allSelected) {
3190
- const selectableValues = selectableOptions.map((opt) => opt.value);
3191
- onChange(value.filter((v) => !selectableValues.includes(v)));
3192
- } else {
3193
- const newValues = new Set(value);
3194
- selectableOptions.forEach((opt) => newValues.add(opt.value));
3195
- onChange(Array.from(newValues));
3196
- }
3197
- };
3198
- const handleRemove = (optionValue, e2) => {
3199
- e2.preventDefault();
3200
- e2.stopPropagation();
3201
- onChange(value.filter((v) => v !== optionValue));
3202
- };
3203
- const handleClearAll = (e2) => {
3204
- e2.preventDefault();
3205
- e2.stopPropagation();
3206
- onChange([]);
3207
- };
3208
- const handleSearchChange = (e2) => {
3209
- const newQuery = e2.target.value;
3210
- setQuery(newQuery);
3211
- onSearch?.(newQuery);
3212
- };
3213
- const handleDropdownClose = () => {
3214
- setQuery("");
3215
- };
3216
- const displayedChips = selectedOptions.slice(0, maxDisplayedItems);
3217
- const hiddenCount = selectedOptions.length - maxDisplayedItems;
3218
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn(fullWidth ? "w-full" : "w-auto", className), "data-testid": testId, children: [
3219
- label && /* @__PURE__ */ jsxRuntime.jsxs(
3220
- "label",
3221
- {
3222
- id: labelId,
3223
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
3224
- "data-testid": testId ? `${testId}-label` : void 0,
3225
- children: [
3226
- label,
3227
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
3228
- ]
3229
- }
3230
- ),
3231
- /* @__PURE__ */ jsxRuntime.jsx(
3232
- style.Mo,
3233
- {
3234
- value,
3235
- onChange: (newValue) => {
3236
- onChange(newValue);
3237
- },
3238
- disabled: isDisabled,
3239
- multiple: true,
3240
- children: ({ open }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
3241
- /* @__PURE__ */ jsxRuntime.jsxs(
3242
- "div",
3243
- {
3244
- className: utils_index.cn(
3245
- "relative flex min-h-[42px] w-full flex-wrap items-center gap-1.5 rounded-md border px-3 py-1.5",
3246
- "bg-white dark:bg-primary-800",
3247
- "transition-colors duration-normal",
3248
- isDisabled && "cursor-not-allowed opacity-50",
3249
- hasError ? "border-error focus-within:border-error focus-within:ring-2 focus-within:ring-error/20" : "border-primary-300 dark:border-primary-600 focus-within:border-gold-500 focus-within:ring-2 focus-within:ring-gold-500/20"
3250
- ),
3251
- children: [
3252
- displayedChips.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
3253
- "span",
3254
- {
3255
- className: utils_index.cn(
3256
- "inline-flex items-center gap-1 rounded-md px-2 py-0.5",
3257
- "bg-primary-100 dark:bg-primary-700",
3258
- "text-sm text-primary-700 dark:text-primary-200"
3259
- ),
3260
- "data-testid": testId ? `${testId}-chip-${index}` : void 0,
3261
- children: [
3262
- option.label,
3263
- /* @__PURE__ */ jsxRuntime.jsx(
3264
- "button",
3265
- {
3266
- type: "button",
3267
- onClick: (e2) => handleRemove(option.value, e2),
3268
- className: "rounded hover:bg-primary-200 dark:hover:bg-primary-600",
3269
- "aria-label": `Remove ${option.label}`,
3270
- disabled: isDisabled,
3271
- children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
3272
- }
3273
- )
3274
- ]
3275
- },
3276
- option.value
3277
- )),
3278
- hiddenCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center rounded-md bg-gold-100 px-2 py-0.5 text-sm text-gold-700 dark:bg-gold-900/30 dark:text-gold-400", children: [
3279
- "+",
3280
- hiddenCount,
3281
- " more"
3282
- ] }),
3283
- selectedOptions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-primary-400 dark:text-primary-500", children: placeholder }),
3284
- selectedOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
3285
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
3286
- selectedOptions.length > 0 && !isDisabled && /* @__PURE__ */ jsxRuntime.jsx(
3287
- "button",
3288
- {
3289
- type: "button",
3290
- onClick: handleClearAll,
3291
- className: "rounded p-0.5 text-primary-400 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-300",
3292
- "aria-label": "Clear all",
3293
- children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { className: "h-4 w-4" })
3294
- }
3295
- ),
3296
- /* @__PURE__ */ jsxRuntime.jsx(
3297
- style.Mt,
3298
- {
3299
- "aria-label": "Toggle options",
3300
- className: "flex items-center rounded focus:outline-none focus:ring-2 focus:ring-gold-500/20",
3301
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary", label: loadingText }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, {})
3302
- }
3303
- )
3304
- ] })
3305
- ]
3306
- }
3307
- ),
3308
- /* @__PURE__ */ jsxRuntime.jsx(
3309
- style.Ke,
3310
- {
3311
- show: open,
3312
- leave: "transition ease-in duration-100",
3313
- leaveFrom: "opacity-100",
3314
- leaveTo: "opacity-0",
3315
- afterLeave: handleDropdownClose,
3316
- children: /* @__PURE__ */ jsxRuntime.jsx(
3317
- style.Bt,
3318
- {
3319
- anchor: "bottom start",
3320
- static: true,
3321
- className: "z-dropdown max-h-60 w-[var(--button-width)] overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-primary-800 dark:ring-primary-700 [--anchor-gap:4px]",
3322
- "data-testid": testId ? `${testId}-options` : void 0,
3323
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 px-4 py-2.5 text-primary-500 dark:text-primary-400", children: [
3324
- /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", color: "primary" }),
3325
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: loadingText })
3326
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3327
- searchable && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-primary-200 px-3 py-2 dark:border-primary-700", children: [
3328
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: searchId, className: "sr-only", children: "Search options" }),
3329
- /* @__PURE__ */ jsxRuntime.jsx(
3330
- "input",
3331
- {
3332
- ref: searchInputRef,
3333
- id: searchId,
3334
- type: "text",
3335
- value: query,
3336
- onChange: handleSearchChange,
3337
- placeholder: "Search...",
3338
- "data-testid": testId ? `${testId}-input` : void 0,
3339
- className: utils_index.cn(
3340
- "w-full rounded border border-primary-300 px-2 py-1 text-sm",
3341
- "bg-white dark:bg-primary-900",
3342
- "text-primary-900 dark:text-primary-100",
3343
- "placeholder:text-primary-400 dark:placeholder:text-primary-500",
3344
- "focus:border-gold-500 focus:outline-none focus:ring-1 focus:ring-gold-500",
3345
- "dark:border-primary-600"
3346
- ),
3347
- onClick: (e2) => e2.stopPropagation()
3348
- }
3349
- )
3350
- ] }),
3351
- showSelectAll && selectableOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
3352
- "div",
3353
- {
3354
- className: utils_index.cn(
3355
- "flex cursor-pointer items-center gap-2 px-4 py-2.5",
3356
- "border-b border-primary-200 dark:border-primary-700",
3357
- "hover:bg-primary-50 dark:hover:bg-primary-700"
3358
- ),
3359
- onClick: handleSelectAll,
3360
- children: [
3361
- /* @__PURE__ */ jsxRuntime.jsx(
3362
- Checkbox,
3363
- {
3364
- checked: allSelected,
3365
- indeterminate: someSelected && !allSelected,
3366
- onChange: () => {
3367
- },
3368
- "aria-label": selectAllLabel
3369
- }
3370
- ),
3371
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-primary-900 dark:text-primary-100", children: [
3372
- selectAllLabel,
3373
- " (",
3374
- selectableOptions.length,
3375
- ")"
3376
- ] })
3377
- ]
3378
- }
3379
- ),
3380
- filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2.5 text-primary-500 dark:text-primary-400", children: emptyText }) : filteredOptions.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
3381
- style.It,
3382
- {
3383
- value: option.value,
3384
- disabled: option.disabled,
3385
- "data-testid": testId ? `${testId}-option-${index}` : void 0,
3386
- className: ({ active }) => utils_index.cn(
3387
- "flex cursor-pointer items-center gap-2 px-4 py-2.5",
3388
- active && "bg-primary-50 dark:bg-primary-700",
3389
- option.disabled && "cursor-not-allowed opacity-50"
3390
- ),
3391
- children: [
3392
- /* @__PURE__ */ jsxRuntime.jsx(
3393
- Checkbox,
3394
- {
3395
- checked: value.includes(option.value),
3396
- disabled: option.disabled,
3397
- onChange: () => {
3398
- },
3399
- "aria-label": option.label
3400
- }
3401
- ),
3402
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary-900 dark:text-primary-100", children: option.label })
3403
- ]
3404
- },
3405
- option.value
3406
- ))
3407
- ] })
3408
- }
3409
- )
3410
- }
3411
- )
3412
- ] })
3413
- }
3414
- ),
3415
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
3416
- "p",
3417
- {
3418
- role: hasError ? "alert" : void 0,
3419
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
3420
- className: utils_index.cn(
3421
- "mt-1.5 text-sm",
3422
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
3423
- ),
3424
- children: error || helperText
3425
- }
3426
- )
3427
- ] });
3428
- }
3429
- MultiSelect.displayName = "MultiSelect";
3430
- function shouldShowItem(item) {
3431
- if (item.visible === void 0) return true;
3432
- if (typeof item.visible === "boolean") return item.visible;
3433
- if (typeof item.visible === "function") return item.visible();
3434
- return true;
3435
- }
3436
- function isItemActive(currentPath, href, matcher = "exact") {
3437
- if (!currentPath) return false;
3438
- if (typeof matcher === "function") {
3439
- return matcher(currentPath, href);
3440
- }
3441
- switch (matcher) {
3442
- case "exact":
3443
- return currentPath === href;
3444
- case "startsWith":
3445
- return currentPath === href || currentPath.startsWith(`${href}/`);
3446
- default:
3447
- return false;
3448
- }
3449
- }
3450
- const sizeStyles$2 = {
3451
- sm: "px-2 py-1.5 text-xs gap-2",
3452
- md: "px-3 py-2.5 text-sm gap-3",
3453
- lg: "px-4 py-3 text-base gap-3"
3454
- };
3455
- const iconSizeStyles = {
3456
- sm: "h-4 w-4",
3457
- md: "h-5 w-5",
3458
- lg: "h-6 w-6"
3459
- };
3460
- const DefaultLink = ({
3461
- to,
3462
- children,
3463
- className,
3464
- onClick,
3465
- title,
3466
- "aria-current": ariaCurrent,
3467
- "aria-label": ariaLabel
3468
- }) => /* @__PURE__ */ jsxRuntime.jsx(
3469
- "a",
3470
- {
3471
- href: to,
3472
- className,
3473
- onClick,
3474
- title,
3475
- "aria-current": ariaCurrent,
3476
- "aria-label": ariaLabel,
3477
- children
3478
- }
3479
- );
3480
- function SidebarItem({
3481
- item,
3482
- currentPath,
3483
- size = "md",
3484
- collapsed = false,
3485
- onNavigate,
3486
- LinkComponent,
3487
- className,
3488
- testId,
3489
- ...props
3490
- }) {
3491
- if (!shouldShowItem(item)) {
3492
- return null;
3493
- }
3494
- const isActive = isItemActive(currentPath, item.href, item.activeMatch);
3495
- const LinkElement = LinkComponent || DefaultLink;
3496
- const handleClick = () => {
3497
- if (item.disabled) return;
3498
- item.onClick?.();
3499
- onNavigate?.(item.href);
3500
- };
3501
- const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3502
- item.icon && /* @__PURE__ */ jsxRuntime.jsx(
3503
- "span",
3504
- {
3505
- className: utils_index.cn(
3506
- "flex-shrink-0",
3507
- iconSizeStyles[size],
3508
- "[&>svg]:h-full [&>svg]:w-full"
3509
- ),
3510
- "aria-hidden": "true",
3511
- children: item.icon
3512
- }
3513
- ),
3514
- !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: item.label }),
3515
- !collapsed && item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
3516
- "span",
3517
- {
3518
- className: utils_index.cn(
3519
- "flex-shrink-0 rounded-full px-2 py-0.5 text-xs font-medium",
3520
- isActive ? "bg-primary-200 text-primary-800 dark:bg-primary-700 dark:text-primary-200" : "bg-primary-100 text-primary-600 dark:bg-primary-800 dark:text-primary-300"
3521
- ),
3522
- children: item.badge
3523
- }
3524
- )
3525
- ] });
3526
- if (item.onClick && !item.href) {
3527
- return /* @__PURE__ */ jsxRuntime.jsx(
3528
- "button",
3529
- {
3530
- type: "button",
3531
- onClick: handleClick,
3532
- disabled: item.disabled,
3533
- "aria-label": item["aria-label"] || item.label,
3534
- title: collapsed ? item.label : void 0,
3535
- "data-testid": testId,
3536
- className: utils_index.cn(
3537
- // Base styles
3538
- "flex w-full items-center rounded-lg font-medium",
3539
- "transition-colors duration-150",
3540
- "focus:outline-none focus:ring-2 focus:ring-primary-500/20 focus:ring-offset-2",
3541
- "dark:focus:ring-offset-primary-900",
3542
- // Size styles
3543
- sizeStyles$2[size],
3544
- // State styles
3545
- item.disabled && "opacity-50 cursor-not-allowed",
3546
- !item.disabled && !isActive && [
3547
- "text-primary-600 hover:bg-primary-50 hover:text-primary-900",
3548
- "dark:text-primary-400 dark:hover:bg-primary-800 dark:hover:text-primary-100"
3549
- ],
3550
- isActive && [
3551
- "bg-primary-100 text-primary-900",
3552
- "dark:bg-primary-800 dark:text-primary-100"
3553
- ],
3554
- // Collapsed mode
3555
- collapsed && "justify-center",
3556
- className
3557
- ),
3558
- ...props,
3559
- children: content
3560
- }
3561
- );
3562
- }
3563
- return /* @__PURE__ */ jsxRuntime.jsx(
3564
- LinkElement,
3565
- {
3566
- to: item.href,
3567
- onClick: handleClick,
3568
- "data-testid": testId,
3569
- className: utils_index.cn(
3570
- // Base styles
3571
- "flex items-center rounded-lg font-medium",
3572
- "transition-colors duration-150",
3573
- "focus:outline-none focus:ring-2 focus:ring-primary-500/20 focus:ring-offset-2",
3574
- "dark:focus:ring-offset-primary-900",
3575
- // Size styles
3576
- sizeStyles$2[size],
3577
- // State styles
3578
- item.disabled && "opacity-50 cursor-not-allowed pointer-events-none",
3579
- !item.disabled && !isActive && [
3580
- "text-primary-600 hover:bg-primary-50 hover:text-primary-900",
3581
- "dark:text-primary-400 dark:hover:bg-primary-800 dark:hover:text-primary-100"
3582
- ],
3583
- isActive && [
3584
- "bg-primary-100 text-primary-900",
3585
- "dark:bg-primary-800 dark:text-primary-100"
3586
- ],
3587
- // Collapsed mode
3588
- collapsed && "justify-center",
3589
- className
3590
- ),
3591
- "aria-current": isActive ? "page" : void 0,
3592
- "aria-label": item["aria-label"] || (collapsed ? item.label : void 0),
3593
- title: collapsed ? item.label : void 0,
3594
- children: content
3595
- }
3596
- );
3597
- }
3598
- function shouldShowGroup(group) {
3599
- if (group.visible === void 0) return true;
3600
- if (typeof group.visible === "boolean") return group.visible;
3601
- if (typeof group.visible === "function") return group.visible();
3602
- return true;
3603
- }
3604
- const SidebarGroup = React.forwardRef(
3605
- ({
3606
- group,
3607
- currentPath,
3608
- size = "md",
3609
- collapsed = false,
3610
- LinkComponent,
3611
- onNavigate,
3612
- className,
3613
- ...props
3614
- }, ref) => {
3615
- if (!shouldShowGroup(group)) {
3616
- return null;
3617
- }
3618
- const visibleItems = group.items.filter(shouldShowItem);
3619
- if (visibleItems.length === 0) {
3620
- return null;
3621
- }
3622
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, role: "group", className: utils_index.cn("space-y-1", className), ...props, children: [
3623
- group.label && !collapsed && /* @__PURE__ */ jsxRuntime.jsx(
3624
- "h3",
3625
- {
3626
- className: utils_index.cn(
3627
- "px-3 py-2 text-xs font-semibold uppercase tracking-wider",
3628
- "text-primary-500 dark:text-primary-400"
3629
- ),
3630
- children: group.label
3631
- }
3632
- ),
3633
- /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": group.label || `Navigation group ${group.key}`, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: visibleItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
3634
- SidebarItem,
3635
- {
3636
- item,
3637
- currentPath,
3638
- size,
3639
- collapsed,
3640
- LinkComponent,
3641
- onNavigate
3642
- }
3643
- ) }, item.key)) }) })
3644
- ] });
3645
- }
3646
- );
3647
- SidebarGroup.displayName = "SidebarGroup";
3648
- const SidebarDivider = React.forwardRef(
3649
- ({ label, className, ...props }, ref) => {
3650
- if (label) {
3651
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn("relative my-4", className), children: [
3652
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
3653
- "hr",
3654
- {
3655
- ref,
3656
- className: "w-full border-t border-primary-200 dark:border-primary-700",
3657
- ...props
3658
- }
3659
- ) }),
3660
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-white px-2 text-xs text-primary-500 dark:bg-primary-900 dark:text-primary-400", children: label }) })
3661
- ] });
3662
- }
3663
- return /* @__PURE__ */ jsxRuntime.jsx(
3664
- "hr",
3665
- {
3666
- ref,
3667
- className: utils_index.cn(
3668
- "my-4 border-t border-primary-200 dark:border-primary-700",
3669
- className
3670
- ),
3671
- ...props
3672
- }
3673
- );
3674
- }
3675
- );
3676
- SidebarDivider.displayName = "SidebarDivider";
3677
- const variantStyles$1 = {
3678
- default: [
3679
- "bg-white border-r border-gold-500/40",
3680
- "dark:bg-primary-900 dark:border-gold-500/20"
3681
- ].join(" "),
3682
- minimal: [
3683
- "bg-white border-r border-primary-200",
3684
- "dark:bg-primary-900 dark:border-primary-700"
3685
- ].join(" ")
3686
- };
3687
- const Sidebar = React.forwardRef(
3688
- ({
3689
- navigation,
3690
- currentPath,
3691
- isOpen = false,
3692
- onClose,
3693
- collapsed = false,
3694
- onCollapsedChange,
3695
- variant = "default",
3696
- size = "md",
3697
- header,
3698
- footer,
3699
- LinkComponent,
3700
- onNavigate,
3701
- showMobileOverlay = true,
3702
- width = "16rem",
3703
- collapsedWidth = "4rem",
3704
- className,
3705
- "aria-label": ariaLabel = "Main navigation",
3706
- testId,
3707
- ...props
3708
- }, ref) => {
3709
- React.useEffect(() => {
3710
- const handleEscape = (event) => {
3711
- if (event.key === "Escape" && isOpen) {
3712
- onClose?.();
3713
- }
3714
- };
3715
- document.addEventListener("keydown", handleEscape);
3716
- return () => document.removeEventListener("keydown", handleEscape);
3717
- }, [isOpen, onClose]);
3718
- React.useEffect(() => {
3719
- if (isOpen) {
3720
- document.body.style.overflow = "hidden";
3721
- } else {
3722
- document.body.style.overflow = "";
3723
- }
3724
- return () => {
3725
- document.body.style.overflow = "";
3726
- };
3727
- }, [isOpen]);
3728
- const handleNavigate = React.useCallback(
3729
- (href) => {
3730
- onNavigate?.(href);
3731
- onClose?.();
3732
- },
3733
- [onNavigate, onClose]
3734
- );
3735
- const handleOverlayClick = React.useCallback(() => {
3736
- onClose?.();
3737
- }, [onClose]);
3738
- const handleCollapseToggle = React.useCallback(() => {
3739
- onCollapsedChange?.(!collapsed);
3740
- }, [collapsed, onCollapsedChange]);
3741
- const hasVisibleGroups = (groups) => groups?.some(shouldShowGroup) ?? false;
3742
- const hasFeatured = hasVisibleGroups(navigation.featured);
3743
- const hasPrimary = hasVisibleGroups(navigation.primary);
3744
- const hasSecondary = hasVisibleGroups(navigation.secondary);
3745
- const hasBottom = hasVisibleGroups(navigation.bottom);
3746
- const sidebarWidth = collapsed ? collapsedWidth : width;
3747
- const sidebarContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3748
- header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_index.cn("flex-shrink-0", collapsed && "px-2"), children: header }),
3749
- hasFeatured && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 px-3 py-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: navigation.featured?.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
3750
- SidebarGroup,
3751
- {
3752
- group,
3753
- currentPath,
3754
- size,
3755
- collapsed,
3756
- LinkComponent,
3757
- onNavigate: handleNavigate
3758
- },
3759
- group.key
3760
- )) }) }),
3761
- hasPrimary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto px-3 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: navigation.primary?.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
3762
- SidebarGroup,
3763
- {
3764
- group,
3765
- currentPath,
3766
- size,
3767
- collapsed,
3768
- LinkComponent,
3769
- onNavigate: handleNavigate
3770
- },
3771
- group.key
3772
- )) }) }),
3773
- hasPrimary && hasSecondary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarDivider, {}) }),
3774
- hasSecondary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: navigation.secondary?.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
3775
- SidebarGroup,
3776
- {
3777
- group,
3778
- currentPath,
3779
- size,
3780
- collapsed,
3781
- LinkComponent,
3782
- onNavigate: handleNavigate
3783
- },
3784
- group.key
3785
- )) }) }),
3786
- !hasPrimary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
3787
- (hasPrimary || hasSecondary) && hasBottom && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarDivider, {}) }),
3788
- hasBottom && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 px-3 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: navigation.bottom?.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
3789
- SidebarGroup,
3790
- {
3791
- group,
3792
- currentPath,
3793
- size,
3794
- collapsed,
3795
- LinkComponent,
3796
- onNavigate: handleNavigate
3797
- },
3798
- group.key
3799
- )) }) }),
3800
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_index.cn("flex-shrink-0", collapsed && "px-2"), children: footer }),
3801
- onCollapsedChange && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden lg:block flex-shrink-0 border-t border-primary-200 dark:border-primary-700 p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
3802
- "button",
3803
- {
3804
- type: "button",
3805
- onClick: handleCollapseToggle,
3806
- className: utils_index.cn(
3807
- "flex w-full items-center justify-center rounded-lg p-2",
3808
- "text-primary-500 hover:bg-primary-50 hover:text-primary-700",
3809
- "dark:text-primary-400 dark:hover:bg-primary-800 dark:hover:text-primary-200",
3810
- "transition-colors duration-150",
3811
- "focus:outline-none focus:ring-2 focus:ring-primary-500/20"
3812
- ),
3813
- "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
3814
- "data-testid": testId ? `${testId}-toggle` : void 0,
3815
- children: /* @__PURE__ */ jsxRuntime.jsx(
3816
- "svg",
3817
- {
3818
- className: utils_index.cn(
3819
- "h-5 w-5 transition-transform duration-200",
3820
- collapsed && "rotate-180"
3821
- ),
3822
- fill: "none",
3823
- viewBox: "0 0 24 24",
3824
- stroke: "currentColor",
3825
- "aria-hidden": "true",
3826
- children: /* @__PURE__ */ jsxRuntime.jsx(
3827
- "path",
3828
- {
3829
- strokeLinecap: "round",
3830
- strokeLinejoin: "round",
3831
- strokeWidth: 2,
3832
- d: "M11 19l-7-7 7-7m8 14l-7-7 7-7"
3833
- }
3834
- )
3835
- }
3836
- )
3837
- }
3838
- ) })
3839
- ] });
3840
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3841
- showMobileOverlay && isOpen && /* @__PURE__ */ jsxRuntime.jsx(
3842
- "div",
3843
- {
3844
- className: "fixed inset-0 z-40 bg-black/20 lg:hidden",
3845
- onClick: handleOverlayClick,
3846
- "aria-hidden": "true",
3847
- "data-testid": testId ? `${testId}-overlay` : void 0
3848
- }
3849
- ),
3850
- /* @__PURE__ */ jsxRuntime.jsx(
3851
- "aside",
3852
- {
3853
- ref,
3854
- className: utils_index.cn(
3855
- // Base styles
3856
- "fixed top-0 left-0 z-50 flex h-full flex-col",
3857
- "transform transition-all duration-300 ease-in-out",
3858
- // Desktop styles
3859
- "lg:static lg:z-auto lg:translate-x-0",
3860
- // Mobile styles
3861
- isOpen ? "translate-x-0" : "-translate-x-full",
3862
- // Variant styles
3863
- variantStyles$1[variant],
3864
- className
3865
- ),
3866
- style: { width: sidebarWidth },
3867
- "aria-label": ariaLabel,
3868
- "data-testid": testId,
3869
- ...props,
3870
- children: sidebarContent
3871
- }
3872
- )
3873
- ] });
3874
- }
3875
- );
3876
- Sidebar.displayName = "Sidebar";
3877
- const CheckCircleIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) });
3878
- const XCircleIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) });
3879
- const ExclamationCircleIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" }) });
3880
- const InformationCircleIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" }) });
3881
- const XMarkIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) });
3882
- const defaultIcons = {
3883
- success: /* @__PURE__ */ jsxRuntime.jsx(CheckCircleIcon, {}),
3884
- error: /* @__PURE__ */ jsxRuntime.jsx(XCircleIcon, {}),
3885
- warning: /* @__PURE__ */ jsxRuntime.jsx(ExclamationCircleIcon, {}),
3886
- info: /* @__PURE__ */ jsxRuntime.jsx(InformationCircleIcon, {})
3887
- };
3888
- const variantStyles = {
3889
- success: {
3890
- container: utils_index.cn(
3891
- "bg-success-light border-success/20 text-[#166534]",
3892
- "dark:bg-success/10 dark:border-success/30 dark:text-[#86efac]"
3893
- ),
3894
- icon: "text-success dark:text-[#4ade80]",
3895
- title: "text-[#14532d] dark:text-[#bbf7d0]"
3896
- },
3897
- error: {
3898
- container: utils_index.cn(
3899
- "bg-error-light border-error/20 text-[#991b1b]",
3900
- "dark:bg-error/10 dark:border-error/30 dark:text-[#fca5a5]"
3901
- ),
3902
- icon: "text-error dark:text-[#f87171]",
3903
- title: "text-[#7f1d1d] dark:text-[#fecaca]"
3904
- },
3905
- warning: {
3906
- container: utils_index.cn(
3907
- "bg-warning-light border-warning/20 text-[#854d0e]",
3908
- "dark:bg-warning/10 dark:border-warning/30 dark:text-[#fde047]"
3909
- ),
3910
- icon: "text-warning dark:text-[#facc15]",
3911
- title: "text-[#713f12] dark:text-[#fef08a]"
3912
- },
3913
- info: {
3914
- container: utils_index.cn(
3915
- "bg-info-light border-info/20 text-[#1e40af]",
3916
- "dark:bg-info/10 dark:border-info/30 dark:text-[#93c5fd]"
3917
- ),
3918
- icon: "text-info dark:text-[#60a5fa]",
3919
- title: "text-[#1e3a8a] dark:text-[#bfdbfe]"
3920
- }
3921
- };
3922
- const Alert = React.forwardRef(
3923
- ({ variant = "info", title, message, icon, onClose, className, testId, ...props }, ref) => {
3924
- const styles = variantStyles[variant];
3925
- const displayIcon = icon === null ? null : icon ?? defaultIcons[variant];
3926
- return /* @__PURE__ */ jsxRuntime.jsx(
3927
- "div",
3928
- {
3929
- ref,
3930
- role: "alert",
3931
- className: utils_index.cn(
3932
- "rounded-lg border p-4",
3933
- styles.container,
3934
- className
3935
- ),
3936
- "data-testid": testId,
3937
- ...props,
3938
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start", children: [
3939
- displayIcon !== null && /* @__PURE__ */ jsxRuntime.jsx(
3940
- "div",
3941
- {
3942
- className: utils_index.cn("flex-shrink-0", styles.icon),
3943
- "aria-hidden": "true",
3944
- "data-testid": testId ? `${testId}-icon` : void 0,
3945
- children: displayIcon
3946
- }
3947
- ),
3948
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn("flex-1", displayIcon !== null && "ml-3"), children: [
3949
- title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: utils_index.cn("text-sm font-medium", styles.title), children: title }),
3950
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_index.cn("text-sm", title && "mt-1"), children: message })
3951
- ] }),
3952
- onClose && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-3 flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
3953
- "button",
3954
- {
3955
- type: "button",
3956
- onClick: onClose,
3957
- className: utils_index.cn(
3958
- "inline-flex rounded-md p-1.5",
3959
- "hover:opacity-75 focus:outline-none focus:ring-2 focus:ring-offset-2",
3960
- "focus:ring-current/20",
3961
- "dark:focus:ring-offset-primary-900"
3962
- ),
3963
- "data-testid": testId ? `${testId}-close-button` : void 0,
3964
- children: [
3965
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Dismiss" }),
3966
- /* @__PURE__ */ jsxRuntime.jsx(XMarkIcon, {})
3967
- ]
3968
- }
3969
- ) })
3970
- ] })
3971
- }
3972
- );
3973
- }
3974
- );
3975
- Alert.displayName = "Alert";
3976
- const sizeStyles$1 = {
3977
- xs: { container: "w-6 h-6", text: "text-xs", status: "w-2 h-2 border" },
3978
- sm: { container: "w-8 h-8", text: "text-sm", status: "w-2.5 h-2.5 border" },
3979
- md: { container: "w-10 h-10", text: "text-base", status: "w-3 h-3 border-2" },
3980
- lg: { container: "w-12 h-12", text: "text-lg", status: "w-3.5 h-3.5 border-2" },
3981
- xl: { container: "w-16 h-16", text: "text-2xl", status: "w-4 h-4 border-2" }
3982
- };
3983
- const statusStyles = {
3984
- online: "bg-success",
3985
- offline: "bg-primary-400 dark:bg-primary-500",
3986
- away: "bg-warning",
3987
- busy: "bg-error"
3988
- };
3989
- const Avatar = React.forwardRef(
3990
- ({ name, src, size = "md", alt, status, className, testId, ...props }, ref) => {
3991
- const getInitials = (fullName) => {
3992
- const names = fullName.trim().split(" ");
3993
- if (names.length === 1) {
3994
- return names[0]?.charAt(0).toUpperCase() || "";
3995
- }
3996
- const firstName = names[0];
3997
- const lastName = names[names.length - 1];
3998
- return ((firstName?.charAt(0) || "") + (lastName?.charAt(0) || "")).toUpperCase();
3999
- };
4000
- const initials = getInitials(name);
4001
- const styles = sizeStyles$1[size];
4002
- return /* @__PURE__ */ jsxRuntime.jsxs(
4003
- "div",
4004
- {
4005
- ref,
4006
- className: utils_index.cn(
4007
- "relative inline-flex items-center justify-center",
4008
- "rounded-full font-medium",
4009
- // Light mode
4010
- "bg-gold-500 text-white",
4011
- // Dark mode
4012
- "dark:bg-gold-600 dark:text-white",
4013
- styles.container,
4014
- className
4015
- ),
4016
- "data-testid": testId,
4017
- ...props,
4018
- children: [
4019
- src ? /* @__PURE__ */ jsxRuntime.jsx(
4020
- "img",
4021
- {
4022
- src,
4023
- alt: alt || `${name}'s avatar`,
4024
- className: "w-full h-full rounded-full object-cover",
4025
- "data-testid": testId ? `${testId}-image` : void 0
4026
- }
4027
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.text, children: initials }),
4028
- status && /* @__PURE__ */ jsxRuntime.jsx(
4029
- "span",
4030
- {
4031
- role: "status",
4032
- className: utils_index.cn(
4033
- "absolute bottom-0 right-0 rounded-full",
4034
- "border-white dark:border-primary-900",
4035
- styles.status,
4036
- statusStyles[status]
4037
- ),
4038
- "aria-label": `Status: ${status}`,
4039
- "data-testid": testId ? `${testId}-status` : void 0
4040
- }
4041
- )
4042
- ]
4043
- }
4044
- );
4045
- }
4046
- );
4047
- Avatar.displayName = "Avatar";
4048
- const OTPInput = ({
4049
- length = 6,
4050
- value,
4051
- onChange,
4052
- error,
4053
- disabled = false,
4054
- autoFocus = false,
4055
- label = "One-time password",
4056
- className
4057
- }) => {
4058
- const inputRefs = React.useRef([]);
4059
- const digits = value.split("").slice(0, length);
4060
- while (digits.length < length) {
4061
- digits.push("");
4062
- }
4063
- const focusInput = React.useCallback((index) => {
4064
- const input = inputRefs.current[index];
4065
- if (input) {
4066
- input.focus();
4067
- input.select();
4068
- }
4069
- }, []);
4070
- const handleChange = React.useCallback(
4071
- (index, event_) => {
4072
- const newValue = event_.target.value;
4073
- if (!/^\d*$/.test(newValue)) return;
4074
- const digit = newValue.slice(-1);
4075
- const newDigits = [...digits];
4076
- newDigits[index] = digit;
4077
- const newOtp = newDigits.join("");
4078
- onChange(newOtp);
4079
- if (digit && index < length - 1) {
4080
- focusInput(index + 1);
4081
- }
4082
- },
4083
- [digits, length, onChange, focusInput]
4084
- );
4085
- const handleKeyDown = React.useCallback(
4086
- (index, event_) => {
4087
- switch (event_.key) {
4088
- case "Backspace":
4089
- if (!digits[index] && index > 0) {
4090
- event_.preventDefault();
4091
- const newDigits = [...digits];
4092
- newDigits[index - 1] = "";
4093
- onChange(newDigits.join(""));
4094
- focusInput(index - 1);
4095
- } else if (digits[index]) {
4096
- const newDigits = [...digits];
4097
- newDigits[index] = "";
4098
- onChange(newDigits.join(""));
4099
- }
4100
- break;
4101
- case "ArrowLeft":
4102
- event_.preventDefault();
4103
- if (index > 0) {
4104
- focusInput(index - 1);
4105
- }
4106
- break;
4107
- case "ArrowRight":
4108
- event_.preventDefault();
4109
- if (index < length - 1) {
4110
- focusInput(index + 1);
4111
- }
4112
- break;
4113
- case "Delete": {
4114
- event_.preventDefault();
4115
- const newDigits = [...digits];
4116
- newDigits[index] = "";
4117
- onChange(newDigits.join(""));
4118
- break;
4119
- }
4120
- }
4121
- },
4122
- [digits, length, onChange, focusInput]
4123
- );
4124
- const handlePaste = React.useCallback(
4125
- (event_) => {
4126
- event_.preventDefault();
4127
- const pastedData = event_.clipboardData.getData("text");
4128
- const pastedDigits = pastedData.replace(/\D/g, "").slice(0, length);
4129
- if (pastedDigits) {
4130
- onChange(pastedDigits);
4131
- const focusIndex = Math.min(pastedDigits.length, length - 1);
4132
- focusInput(focusIndex);
4133
- }
4134
- },
4135
- [length, onChange, focusInput]
4136
- );
4137
- const errorId = error ? "otp-input-error" : void 0;
4138
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils_index.cn("w-full", className), "data-testid": "otp-input", children: [
4139
- /* @__PURE__ */ jsxRuntime.jsx(
4140
- "div",
4141
- {
4142
- role: "group",
4143
- "aria-label": label,
4144
- "aria-describedby": errorId,
4145
- className: "flex justify-center gap-2 sm:gap-3",
4146
- children: digits.map((digit, index) => /* @__PURE__ */ jsxRuntime.jsx(
4147
- "input",
4148
- {
4149
- ref: (element) => {
4150
- inputRefs.current[index] = element;
4151
- },
4152
- type: "text",
4153
- inputMode: "numeric",
4154
- pattern: "\\d*",
4155
- maxLength: 1,
4156
- value: digit,
4157
- disabled,
4158
- autoFocus: autoFocus && index === 0,
4159
- "aria-label": `Digit ${index + 1} of ${length}`,
4160
- "aria-invalid": !!error,
4161
- "data-testid": `otp-input-digit-${index}`,
4162
- className: utils_index.cn(
4163
- "w-10 h-12 sm:w-12 sm:h-14",
4164
- "text-center text-xl sm:text-2xl font-semibold",
4165
- "border-2 rounded-lg",
4166
- "focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500",
4167
- "transition-colors duration-200",
4168
- // Light mode
4169
- error ? "border-error bg-error-light" : "border-primary-300 bg-white",
4170
- // Dark mode
4171
- error ? "dark:border-error dark:bg-error/10" : "dark:border-primary-600 dark:bg-primary-900 dark:text-white",
4172
- "dark:focus:ring-primary-400 dark:focus:border-primary-400",
4173
- disabled && "bg-primary-100 cursor-not-allowed opacity-50 dark:bg-primary-800"
4174
- ),
4175
- onChange: (event_) => handleChange(index, event_),
4176
- onKeyDown: (event_) => handleKeyDown(index, event_),
4177
- onPaste: handlePaste,
4178
- onFocus: (event_) => event_.target.select()
4179
- },
4180
- index
4181
- ))
4182
- }
4183
- ),
4184
- error && /* @__PURE__ */ jsxRuntime.jsx(
4185
- "p",
4186
- {
4187
- id: errorId,
4188
- role: "alert",
4189
- "aria-live": "assertive",
4190
- "data-testid": "otp-input-error",
4191
- className: utils_index.cn(
4192
- "mt-2 text-sm text-center",
4193
- "text-error dark:text-[#fca5a5]"
4194
- ),
4195
- children: error
4196
- }
4197
- )
4198
- ] });
4199
- };
4200
- function parseDate(value) {
4201
- if (!value) return void 0;
4202
- const [y, m, d2] = value.split("-").map(Number);
4203
- if (!y || !m || !d2) return void 0;
4204
- const date = new Date(y, m - 1, d2);
4205
- if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d2) {
4206
- return void 0;
4207
- }
4208
- return date;
4209
- }
4210
- function formatDate(date) {
4211
- const y = date.getFullYear();
4212
- const m = String(date.getMonth() + 1).padStart(2, "0");
4213
- const d2 = String(date.getDate()).padStart(2, "0");
4214
- return `${y}-${m}-${d2}`;
4215
- }
4216
- function isValidDateString(value) {
4217
- return /^\d{4}-\d{2}-\d{2}$/.test(value) && parseDate(value) !== void 0;
4218
- }
4219
- function CalendarDropdown(props) {
4220
- const { options, value, onChange, className, "aria-label": ariaLabel, ...rest } = props;
4221
- const [open, setOpen] = React.useState(false);
4222
- const containerRef = React.useRef(null);
4223
- const listRef = React.useRef(null);
4224
- const selectedOption = options?.find((o) => o.value === Number(value));
4225
- React.useEffect(() => {
4226
- if (!open) return;
4227
- const handleMouseDown = (e2) => {
4228
- if (!containerRef.current?.contains(e2.target)) {
4229
- setOpen(false);
4230
- }
4231
- };
4232
- document.addEventListener("mousedown", handleMouseDown);
4233
- return () => document.removeEventListener("mousedown", handleMouseDown);
4234
- }, [open]);
4235
- React.useEffect(() => {
4236
- if (open && listRef.current) {
4237
- const active = listRef.current.querySelector('[data-active="true"]');
4238
- if (active) {
4239
- active.scrollIntoView({ block: "nearest" });
4240
- }
4241
- }
4242
- }, [open]);
4243
- const handleSelect = (optionValue) => {
4244
- if (onChange) {
4245
- const syntheticEvent = {
4246
- target: { value: String(optionValue) }
4247
- };
4248
- onChange(syntheticEvent);
4249
- }
4250
- setOpen(false);
4251
- };
4252
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: utils_index.cn("relative", className), children: [
4253
- /* @__PURE__ */ jsxRuntime.jsx("select", { ...rest, value, onChange, className: "sr-only", tabIndex: -1, children: options?.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value)) }),
4254
- /* @__PURE__ */ jsxRuntime.jsxs(
4255
- "button",
4256
- {
4257
- type: "button",
4258
- onClick: () => setOpen(!open),
4259
- "aria-label": ariaLabel,
4260
- "aria-expanded": open,
4261
- "aria-haspopup": "listbox",
4262
- className: utils_index.cn(
4263
- "inline-flex items-center gap-1 rounded-md px-2 py-1 text-sm font-semibold",
4264
- "text-primary-800 dark:text-primary-200",
4265
- "hover:bg-primary-100 dark:hover:bg-primary-700",
4266
- "transition-colors"
4267
- ),
4268
- children: [
4269
- selectedOption?.label,
4270
- /* @__PURE__ */ jsxRuntime.jsx(
4271
- "svg",
4272
- {
4273
- xmlns: "http://www.w3.org/2000/svg",
4274
- viewBox: "0 0 20 20",
4275
- fill: "currentColor",
4276
- className: utils_index.cn("h-4 w-4 text-primary-500 transition-transform", open && "rotate-180"),
4277
- children: /* @__PURE__ */ jsxRuntime.jsx(
4278
- "path",
4279
- {
4280
- fillRule: "evenodd",
4281
- d: "M5.22 8.22a.75.75 0 011.06 0L10 11.94l3.72-3.72a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.22 9.28a.75.75 0 010-1.06z",
4282
- clipRule: "evenodd"
4283
- }
4284
- )
4285
- }
4286
- )
4287
- ]
4288
- }
4289
- ),
4290
- open && /* @__PURE__ */ jsxRuntime.jsx(
4291
- "div",
4292
- {
4293
- ref: listRef,
4294
- role: "listbox",
4295
- "aria-label": ariaLabel,
4296
- className: utils_index.cn(
4297
- "absolute left-0 top-full z-10 mt-1",
4298
- "max-h-48 min-w-[8rem] overflow-auto",
4299
- "rounded-md border border-primary-200 bg-white py-1 shadow-lg",
4300
- "dark:border-primary-600 dark:bg-primary-800"
4301
- ),
4302
- children: options?.map((o) => {
4303
- const isSelected = o.value === Number(value);
4304
- return /* @__PURE__ */ jsxRuntime.jsx(
4305
- "button",
4306
- {
4307
- type: "button",
4308
- role: "option",
4309
- "aria-selected": isSelected,
4310
- "data-active": isSelected ? "true" : void 0,
4311
- disabled: o.disabled,
4312
- onClick: () => handleSelect(o.value),
4313
- className: utils_index.cn(
4314
- "flex w-full items-center px-3 py-1.5 text-left text-sm",
4315
- "transition-colors",
4316
- isSelected ? "bg-gold-50 font-semibold text-gold-700 dark:bg-gold-900/30 dark:text-gold-400" : "text-primary-700 dark:text-primary-300",
4317
- !o.disabled && !isSelected && "hover:bg-primary-50 dark:hover:bg-primary-700",
4318
- o.disabled && "cursor-not-allowed opacity-40"
4319
- ),
4320
- children: o.label
4321
- },
4322
- o.value
4323
- );
4324
- })
4325
- }
4326
- )
4327
- ] });
4328
- }
4329
- const DateInput = React.forwardRef(
4330
- ({
4331
- value,
4332
- onChange,
4333
- label,
4334
- error,
4335
- helperText,
4336
- fullWidth = false,
4337
- disabled = false,
4338
- className,
4339
- id,
4340
- required,
4341
- min,
4342
- max,
4343
- testId,
4344
- placeholder = "Select date",
4345
- disabledDate,
4346
- allowClear = true,
4347
- locale,
4348
- formatDisplayValue
4349
- }, ref) => {
4350
- const [isOpen, setIsOpen] = React.useState(false);
4351
- const [inputValue, setInputValue] = React.useState(value || "");
4352
- const [isEditing, setIsEditing] = React.useState(false);
4353
- const [month, setMonth] = React.useState(() => parseDate(value) || /* @__PURE__ */ new Date());
4354
- const containerRef = React.useRef(null);
4355
- const inputRef = React.useRef(null);
4356
- const panelRef = React.useRef(null);
4357
- const [panelPosition, setPanelPosition] = React.useState({
4358
- top: 0,
4359
- left: 0
4360
- });
4361
- const inputId = id || label?.toLowerCase().replace(/\s+/g, "-");
4362
- const hasError = !!error;
4363
- const errorId = hasError ? `${inputId}-error` : void 0;
4364
- const selectedDate = parseDate(value);
4365
- const minDate = parseDate(min ?? null);
4366
- const maxDate = parseDate(max ?? null);
4367
- const getDisplayValue = React.useCallback(
4368
- (val) => {
4369
- if (!val) return "";
4370
- const d2 = parseDate(val);
4371
- if (!d2) return val;
4372
- if (formatDisplayValue) return formatDisplayValue(d2, locale);
4373
- if (locale) {
4374
- return d2.toLocaleDateString(locale.code, {
4375
- year: "numeric",
4376
- month: "short",
4377
- day: "numeric"
4378
- });
4379
- }
4380
- return val;
4381
- },
4382
- [formatDisplayValue, locale]
4383
- );
4384
- React.useEffect(() => {
4385
- if (!isEditing) {
4386
- setInputValue(getDisplayValue(value));
4387
- }
4388
- }, [value, isEditing, getDisplayValue]);
4389
- React.useEffect(() => {
4390
- const d2 = parseDate(value);
4391
- if (d2) setMonth(d2);
4392
- }, [value]);
4393
- const disabledMatcher = React.useCallback(
4394
- (date) => {
4395
- if (minDate && date < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) {
4396
- return true;
4397
- }
4398
- if (maxDate && date > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) {
4399
- return true;
4400
- }
4401
- if (disabledDate?.(date)) return true;
4402
- return false;
4403
- },
4404
- // eslint-disable-next-line react-hooks/exhaustive-deps
4405
- [min, max, disabledDate]
4406
- );
4407
- const updatePosition = React.useCallback(() => {
4408
- if (!containerRef.current) return;
4409
- const rect = containerRef.current.getBoundingClientRect();
4410
- const spaceBelow = window.innerHeight - rect.bottom;
4411
- const panelHeight = 340;
4412
- const top = spaceBelow >= panelHeight ? rect.bottom + window.scrollY + 4 : rect.top + window.scrollY - panelHeight - 4;
4413
- const left = rect.left + window.scrollX;
4414
- setPanelPosition({ top, left });
4415
- }, []);
4416
- const openCalendar = React.useCallback(() => {
4417
- if (disabled) return;
4418
- updatePosition();
4419
- setIsOpen(true);
4420
- }, [disabled, updatePosition]);
4421
- const closeCalendar = React.useCallback(() => {
4422
- setIsOpen(false);
4423
- }, []);
4424
- const toggleCalendar = React.useCallback(() => {
4425
- if (isOpen) {
4426
- closeCalendar();
4427
- } else {
4428
- openCalendar();
4429
- }
4430
- }, [isOpen, openCalendar, closeCalendar]);
4431
- React.useEffect(() => {
4432
- if (!isOpen) return;
4433
- const handleMouseDown = (e2) => {
4434
- const target = e2.target;
4435
- if (containerRef.current?.contains(target) || panelRef.current?.contains(target)) {
4436
- return;
4437
- }
4438
- closeCalendar();
4439
- };
4440
- document.addEventListener("mousedown", handleMouseDown);
4441
- return () => document.removeEventListener("mousedown", handleMouseDown);
4442
- }, [isOpen, closeCalendar]);
4443
- React.useEffect(() => {
4444
- if (!isOpen) return;
4445
- const handleKeyDown = (e2) => {
4446
- if (e2.key === "Escape") {
4447
- closeCalendar();
4448
- inputRef.current?.focus();
4449
- }
4450
- };
4451
- document.addEventListener("keydown", handleKeyDown);
4452
- return () => document.removeEventListener("keydown", handleKeyDown);
4453
- }, [isOpen, closeCalendar]);
4454
- const handleDaySelect = React.useCallback(
4455
- (date) => {
4456
- if (date) {
4457
- const formatted = formatDate(date);
4458
- onChange(formatted);
4459
- setInputValue(getDisplayValue(formatted));
4460
- setIsEditing(false);
4461
- }
4462
- closeCalendar();
4463
- inputRef.current?.focus();
4464
- },
4465
- [onChange, closeCalendar, getDisplayValue]
4466
- );
4467
- const handleInputChange = (e2) => {
4468
- const val = e2.target.value;
4469
- setIsEditing(true);
4470
- setInputValue(val);
4471
- if (val === "") {
4472
- onChange(null);
4473
- } else if (isValidDateString(val)) {
4474
- const d2 = parseDate(val);
4475
- if (!disabledMatcher(d2)) {
4476
- onChange(val);
4477
- setMonth(d2);
4478
- }
4479
- }
4480
- };
4481
- const handleInputBlur = () => {
4482
- setIsEditing(false);
4483
- setInputValue(getDisplayValue(value));
4484
- };
4485
- const handleInputKeyDown = (e2) => {
4486
- if (e2.key === "ArrowDown" && !isOpen) {
4487
- e2.preventDefault();
4488
- openCalendar();
4489
- }
4490
- if (e2.key === "Enter" && !isOpen) {
4491
- e2.preventDefault();
4492
- openCalendar();
4493
- }
4494
- };
4495
- const handleInputClick = () => {
4496
- if (!isOpen) {
4497
- openCalendar();
4498
- }
4499
- };
4500
- const handleClear = (e2) => {
4501
- e2.stopPropagation();
4502
- onChange(null);
4503
- setInputValue("");
4504
- setIsEditing(false);
4505
- inputRef.current?.focus();
4506
- };
4507
- const handleTodayClick = () => {
4508
- const today = /* @__PURE__ */ new Date();
4509
- today.setHours(0, 0, 0, 0);
4510
- if (!disabledMatcher(today)) {
4511
- handleDaySelect(today);
4512
- }
4513
- };
4514
- const setRefs = React.useCallback(
4515
- (node) => {
4516
- inputRef.current = node;
4517
- if (typeof ref === "function") {
4518
- ref(node);
4519
- } else if (ref) {
4520
- ref.current = node;
4521
- }
4522
- },
4523
- [ref]
4524
- );
4525
- const defaultClassNames = style.getDefaultClassNames();
4526
- const tejaClassNames = {
4527
- root: `${defaultClassNames.root} text-primary-900 dark:text-primary-100`,
4528
- months: defaultClassNames.months,
4529
- month: defaultClassNames.month,
4530
- month_caption: `${defaultClassNames.month_caption} text-sm font-semibold text-primary-800 dark:text-primary-200`,
4531
- nav: defaultClassNames.nav,
4532
- button_previous: `${defaultClassNames.button_previous} text-primary-600 hover:text-primary-900 dark:text-primary-400 dark:hover:text-primary-100`,
4533
- button_next: `${defaultClassNames.button_next} text-primary-600 hover:text-primary-900 dark:text-primary-400 dark:hover:text-primary-100`,
4534
- weekday: `${defaultClassNames.weekday} text-xs font-medium text-primary-500 dark:text-primary-400`,
4535
- day: `${defaultClassNames.day} text-sm`,
4536
- day_button: `${defaultClassNames.day_button} !rounded-md hover:bg-gold-100 dark:hover:bg-gold-900/30`,
4537
- selected: `${defaultClassNames.selected} !bg-gold-500 !text-white dark:!bg-gold-600 !font-semibold !text-base`,
4538
- today: `${defaultClassNames.today} !font-semibold !text-gold-600 dark:!text-gold-400`,
4539
- outside: `${defaultClassNames.outside} !opacity-50 text-primary-400 dark:text-primary-500`,
4540
- disabled: `${defaultClassNames.disabled} text-primary-300 dark:text-primary-600 cursor-not-allowed`,
4541
- chevron: `${defaultClassNames.chevron} !fill-primary-600 dark:!fill-primary-400`,
4542
- dropdowns: `${defaultClassNames.dropdowns} flex items-center gap-0`,
4543
- dropdown_root: `${defaultClassNames.dropdown_root}`,
4544
- caption_label: `${defaultClassNames.caption_label} text-sm font-semibold text-primary-800 dark:text-primary-200`
4545
- };
4546
- const rdpCssOverrides = {
4547
- "--rdp-accent-color": "#f59e0b",
4548
- "--rdp-accent-background-color": "#fefce8",
4549
- "--rdp-today-color": "#d97706",
4550
- "--rdp-selected-border": "0",
4551
- "--rdp-day-height": "36px",
4552
- "--rdp-day-width": "36px",
4553
- "--rdp-day_button-height": "32px",
4554
- "--rdp-day_button-width": "32px",
4555
- "--rdp-day_button-border-radius": "6px",
4556
- "--rdp-day_button-border": "2px solid transparent"
4557
- };
4558
- return /* @__PURE__ */ jsxRuntime.jsxs(
4559
- "div",
4560
- {
4561
- ref: containerRef,
4562
- className: utils_index.cn(fullWidth ? "w-full" : "w-auto"),
4563
- "data-testid": testId,
4564
- children: [
4565
- label && /* @__PURE__ */ jsxRuntime.jsxs(
4566
- "label",
4567
- {
4568
- htmlFor: inputId,
4569
- className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white",
4570
- "data-testid": testId ? `${testId}-label` : void 0,
4571
- children: [
4572
- label,
4573
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-error", children: "*" })
4574
- ]
4575
- }
4576
- ),
4577
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
4578
- /* @__PURE__ */ jsxRuntime.jsx(
4579
- "input",
4580
- {
4581
- ref: setRefs,
4582
- type: "text",
4583
- id: inputId,
4584
- value: inputValue,
4585
- placeholder,
4586
- onChange: handleInputChange,
4587
- onBlur: handleInputBlur,
4588
- onKeyDown: handleInputKeyDown,
4589
- onClick: handleInputClick,
4590
- disabled,
4591
- required,
4592
- role: "combobox",
4593
- "aria-label": label ? void 0 : "Select date",
4594
- "aria-invalid": hasError ? "true" : void 0,
4595
- "aria-describedby": errorId,
4596
- "aria-haspopup": "dialog",
4597
- "aria-expanded": isOpen,
4598
- "data-testid": testId ? `${testId}-input` : "date-input",
4599
- className: utils_index.cn(
4600
- "block w-full rounded-md border bg-white px-4 py-2.5 pr-20 text-sm text-primary-900",
4601
- "transition-colors duration-normal",
4602
- "placeholder:text-primary-400",
4603
- "focus:outline-none focus:ring-2",
4604
- "disabled:cursor-not-allowed disabled:bg-primary-50 disabled:text-primary-500",
4605
- "dark:bg-primary-800 dark:text-primary-100",
4606
- "dark:placeholder:text-primary-500",
4607
- "dark:disabled:bg-primary-900 dark:disabled:text-primary-600",
4608
- !disabled && "cursor-pointer",
4609
- hasError ? "border-error focus:border-error focus:ring-error/20 dark:border-error/70 dark:focus:ring-error/30" : "border-primary-300 focus:border-gold-500 focus:ring-gold-500/20 dark:border-primary-600 dark:focus:border-gold-400 dark:focus:ring-gold-400/30",
4610
- className
4611
- )
4612
- }
4613
- ),
4614
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-y-0 right-0 flex items-center gap-1 pr-3", children: [
4615
- allowClear && value && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
4616
- "button",
4617
- {
4618
- type: "button",
4619
- onClick: handleClear,
4620
- tabIndex: -1,
4621
- "aria-label": "Clear date",
4622
- "data-testid": testId ? `${testId}-clear` : void 0,
4623
- className: "rounded p-0.5 text-primary-400 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-300",
4624
- children: /* @__PURE__ */ jsxRuntime.jsx(
4625
- "svg",
4626
- {
4627
- xmlns: "http://www.w3.org/2000/svg",
4628
- viewBox: "0 0 20 20",
4629
- fill: "currentColor",
4630
- className: "h-4 w-4",
4631
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" })
4632
- }
4633
- )
4634
- }
4635
- ),
4636
- /* @__PURE__ */ jsxRuntime.jsx(
4637
- "button",
4638
- {
4639
- type: "button",
4640
- onClick: toggleCalendar,
4641
- tabIndex: -1,
4642
- disabled,
4643
- "aria-label": "Open calendar",
4644
- "data-testid": testId ? `${testId}-toggle` : void 0,
4645
- className: utils_index.cn(
4646
- "rounded p-0.5 text-primary-400 dark:text-primary-500",
4647
- disabled ? "cursor-not-allowed opacity-50" : "hover:text-primary-600 dark:hover:text-primary-300"
4648
- ),
4649
- children: /* @__PURE__ */ jsxRuntime.jsx(
4650
- "svg",
4651
- {
4652
- xmlns: "http://www.w3.org/2000/svg",
4653
- viewBox: "0 0 20 20",
4654
- fill: "currentColor",
4655
- className: "h-5 w-5",
4656
- children: /* @__PURE__ */ jsxRuntime.jsx(
4657
- "path",
4658
- {
4659
- fillRule: "evenodd",
4660
- d: "M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z",
4661
- clipRule: "evenodd"
4662
- }
4663
- )
4664
- }
4665
- )
4666
- }
4667
- )
4668
- ] })
4669
- ] }),
4670
- (error || helperText) && /* @__PURE__ */ jsxRuntime.jsx(
4671
- "p",
4672
- {
4673
- id: errorId,
4674
- role: hasError ? "alert" : void 0,
4675
- "data-testid": testId ? hasError ? `${testId}-error` : `${testId}-helper-text` : void 0,
4676
- className: utils_index.cn(
4677
- "mt-1.5 text-sm",
4678
- hasError ? "text-error" : "text-primary-500 dark:text-primary-400"
4679
- ),
4680
- children: error || helperText
4681
- }
4682
- ),
4683
- isOpen && ReactDOM.createPortal(
4684
- /* @__PURE__ */ jsxRuntime.jsx(
4685
- "div",
4686
- {
4687
- ref: panelRef,
4688
- role: "dialog",
4689
- "aria-label": "Date picker",
4690
- "data-testid": testId ? `${testId}-calendar` : void 0,
4691
- className: "z-dropdown rounded-lg border border-primary-200 bg-white p-3 shadow-lg dark:border-primary-700 dark:bg-primary-800",
4692
- style: {
4693
- position: "absolute",
4694
- top: panelPosition.top,
4695
- left: panelPosition.left
4696
- },
4697
- children: /* @__PURE__ */ jsxRuntime.jsx(
4698
- style.DayPicker,
4699
- {
4700
- mode: "single",
4701
- selected: selectedDate,
4702
- onSelect: handleDaySelect,
4703
- disabled: disabledMatcher,
4704
- month,
4705
- onMonthChange: setMonth,
4706
- locale,
4707
- captionLayout: "dropdown",
4708
- startMonth: minDate || new Date((/* @__PURE__ */ new Date()).getFullYear() - 100, 0),
4709
- endMonth: maxDate || new Date((/* @__PURE__ */ new Date()).getFullYear() + 10, 11),
4710
- classNames: tejaClassNames,
4711
- components: { Dropdown: CalendarDropdown },
4712
- style: rdpCssOverrides,
4713
- showOutsideDays: true,
4714
- fixedWeeks: true,
4715
- footer: /* @__PURE__ */ jsxRuntime.jsx(
4716
- "button",
4717
- {
4718
- type: "button",
4719
- onClick: handleTodayClick,
4720
- "data-testid": testId ? `${testId}-today` : void 0,
4721
- className: "mt-2 w-full rounded-md border border-primary-200 px-3 py-1.5 text-xs font-medium text-primary-700 hover:bg-primary-50 dark:border-primary-600 dark:text-primary-300 dark:hover:bg-primary-700",
4722
- children: "Today"
4723
- }
4724
- )
4725
- }
4726
- )
4727
- }
4728
- ),
4729
- document.body
4730
- )
4731
- ]
4732
- }
4733
- );
4734
- }
4735
- );
4736
- DateInput.displayName = "DateInput";
4737
- const sizeStyles = {
4738
- sm: "px-2.5 py-1 text-xs gap-1",
4739
- md: "px-3 py-1.5 text-sm gap-1.5",
4740
- lg: "px-4 py-2 text-base gap-2"
4741
- };
4742
- const checkmarkSize = {
4743
- sm: "w-3 h-3",
4744
- md: "w-4 h-4",
4745
- lg: "w-5 h-5"
4746
- };
4747
- const PillSelector = React.forwardRef(
4748
- ({
4749
- options,
4750
- selected,
4751
- onChange,
4752
- multiple = true,
4753
- size = "md",
4754
- label,
4755
- fullWidth = false,
4756
- disabled = false,
4757
- className,
4758
- ...props
4759
- }, ref) => {
4760
- const handleClick = (value) => {
4761
- if (disabled) return;
4762
- if (multiple) {
4763
- if (selected.includes(value)) {
4764
- onChange(selected.filter((v) => v !== value));
4765
- } else {
4766
- onChange([...selected, value]);
4767
- }
4768
- } else {
4769
- onChange([value]);
4770
- }
4771
- };
4772
- return /* @__PURE__ */ jsxRuntime.jsxs(
4773
- "div",
4774
- {
4775
- ref,
4776
- className: utils_index.cn(fullWidth ? "w-full" : "w-auto", className),
4777
- ...props,
4778
- children: [
4779
- label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block text-sm font-medium text-primary-700 dark:text-white", children: label }),
4780
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", role: "group", "aria-label": label, children: options.map((option) => {
4781
- const isSelected = selected.includes(option.value);
4782
- return /* @__PURE__ */ jsxRuntime.jsxs(
4783
- "button",
4784
- {
4785
- type: "button",
4786
- disabled,
4787
- "aria-pressed": isSelected,
4788
- onClick: () => handleClick(option.value),
4789
- className: utils_index.cn(
4790
- "inline-flex items-center justify-center rounded-full border font-medium",
4791
- "transition-colors duration-normal",
4792
- "focus:outline-none focus:ring-2 focus:ring-offset-1",
4793
- "disabled:cursor-not-allowed disabled:opacity-50",
4794
- sizeStyles[size],
4795
- isSelected ? utils_index.cn(
4796
- // Light mode - selected
4797
- "border-primary-700 bg-primary-700 text-white",
4798
- "hover:bg-primary-800 hover:border-primary-800",
4799
- "focus:ring-primary-500/30",
4800
- // Dark mode - selected
4801
- "dark:border-gold-500 dark:bg-gold-500 dark:text-primary-900",
4802
- "dark:hover:bg-gold-400 dark:hover:border-gold-400",
4803
- "dark:focus:ring-gold-400/30"
4804
- ) : utils_index.cn(
4805
- // Light mode - unselected
4806
- "border-primary-300 bg-white text-primary-700",
4807
- "hover:border-primary-400 hover:bg-primary-50",
4808
- "focus:ring-primary-500/20",
4809
- // Dark mode - unselected
4810
- "dark:border-primary-600 dark:bg-primary-800 dark:text-primary-200",
4811
- "dark:hover:border-primary-500 dark:hover:bg-primary-700",
4812
- "dark:focus:ring-primary-400/20"
4813
- )
4814
- ),
4815
- children: [
4816
- isSelected && /* @__PURE__ */ jsxRuntime.jsx(
4817
- "svg",
4818
- {
4819
- className: checkmarkSize[size],
4820
- fill: "currentColor",
4821
- viewBox: "0 0 20 20",
4822
- "aria-hidden": "true",
4823
- children: /* @__PURE__ */ jsxRuntime.jsx(
4824
- "path",
4825
- {
4826
- fillRule: "evenodd",
4827
- clipRule: "evenodd",
4828
- d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
4829
- }
4830
- )
4831
- }
4832
- ),
4833
- option.icon,
4834
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
4835
- ]
4836
- },
4837
- option.value
4838
- );
4839
- }) })
4840
- ]
4841
- }
4842
- );
4843
- }
4844
- );
4845
- PillSelector.displayName = "PillSelector";
4846
5
  exports.useDebounce = useSidebar.useDebounce;
4847
6
  exports.useDebouncedCallback = useSidebar.useDebouncedCallback;
4848
7
  exports.useDebouncedCallbackWithControl = useSidebar.useDebouncedCallbackWithControl;
@@ -4850,42 +9,4 @@ exports.useSelection = useSidebar.useSelection;
4850
9
  exports.useSidebar = useSidebar.useSidebar;
4851
10
  exports.useTable = useSidebar.useTable;
4852
11
  exports.cn = utils_index.cn;
4853
- exports.Alert = Alert;
4854
- exports.Avatar = Avatar;
4855
- exports.Badge = Badge;
4856
- exports.Breadcrumbs = Breadcrumbs;
4857
- exports.Button = Button;
4858
- exports.Card = Card;
4859
- exports.Checkbox = Checkbox;
4860
- exports.Combobox = Combobox;
4861
- exports.ConfirmDialog = ConfirmDialog;
4862
- exports.DateInput = DateInput;
4863
- exports.Drawer = Drawer;
4864
- exports.EmptyState = EmptyState;
4865
- exports.Input = Input;
4866
- exports.Modal = Modal;
4867
- exports.MultiSelect = MultiSelect;
4868
- exports.OTPInput = OTPInput;
4869
- exports.Pagination = Pagination;
4870
- exports.PasswordInput = PasswordInput;
4871
- exports.PillSelector = PillSelector;
4872
- exports.Radio = Radio;
4873
- exports.RadioGroup = RadioGroup;
4874
- exports.Select = Select;
4875
- exports.Sidebar = Sidebar;
4876
- exports.SidebarDivider = SidebarDivider;
4877
- exports.SidebarGroup = SidebarGroup;
4878
- exports.SidebarItem = SidebarItem;
4879
- exports.Skeleton = Skeleton;
4880
- exports.Spinner = Spinner;
4881
- exports.TabContentPanels = TabContentPanels;
4882
- exports.Table = Table;
4883
- exports.TableBody = TableBody;
4884
- exports.TableCell = TableCell;
4885
- exports.TableHead = TableHead;
4886
- exports.TableHeader = TableHeader;
4887
- exports.TableRow = TableRow;
4888
- exports.Tabs = Tabs;
4889
- exports.Textarea = Textarea;
4890
- exports.Toggle = Toggle;
4891
12
  //# sourceMappingURL=index.cjs.map