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