@sovereignfs/ui 0.21.0

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 (141) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +24 -0
  3. package/dist/Avatar.module.css +38 -0
  4. package/dist/Badge.module.css +88 -0
  5. package/dist/Button.module.css +77 -0
  6. package/dist/Card.module.css +34 -0
  7. package/dist/Dialog.module.css +188 -0
  8. package/dist/Drawer.module.css +30 -0
  9. package/dist/EmptyState.module.css +27 -0
  10. package/dist/FormField.module.css +28 -0
  11. package/dist/Icon.module.css +22 -0
  12. package/dist/Input.module.css +37 -0
  13. package/dist/NavTabs.module.css +48 -0
  14. package/dist/PageHeader.module.css +32 -0
  15. package/dist/Popover.module.css +44 -0
  16. package/dist/SegmentedControl.module.css +53 -0
  17. package/dist/Select.module.css +69 -0
  18. package/dist/Spinner.module.css +39 -0
  19. package/dist/SystemBanner.module.css +67 -0
  20. package/dist/Tabs.module.css +49 -0
  21. package/dist/Toast.module.css +130 -0
  22. package/dist/Toggle.module.css +52 -0
  23. package/dist/Tooltip.module.css +51 -0
  24. package/dist/index.d.ts +327 -0
  25. package/dist/index.js +1370 -0
  26. package/dist/tokens/primitives.css +99 -0
  27. package/dist/tokens/semantic.css +111 -0
  28. package/dist/tokens.css +5 -0
  29. package/package.json +50 -0
  30. package/src/components/Avatar/Avatar.module.css +38 -0
  31. package/src/components/Avatar/Avatar.tsx +42 -0
  32. package/src/components/Badge/Badge.module.css +88 -0
  33. package/src/components/Badge/Badge.stories.tsx +118 -0
  34. package/src/components/Badge/Badge.tsx +59 -0
  35. package/src/components/Badge/__tests__/Badge.test.tsx +64 -0
  36. package/src/components/Button/Button.module.css +77 -0
  37. package/src/components/Button/Button.stories.tsx +76 -0
  38. package/src/components/Button/Button.tsx +36 -0
  39. package/src/components/Button/__tests__/Button.test.tsx +37 -0
  40. package/src/components/Card/Card.module.css +34 -0
  41. package/src/components/Card/Card.tsx +34 -0
  42. package/src/components/Dialog/Dialog.module.css +188 -0
  43. package/src/components/Dialog/Dialog.stories.tsx +97 -0
  44. package/src/components/Dialog/Dialog.tsx +137 -0
  45. package/src/components/Dialog/__tests__/Dialog.test.tsx +73 -0
  46. package/src/components/Drawer/Drawer.module.css +30 -0
  47. package/src/components/Drawer/Drawer.stories.tsx +88 -0
  48. package/src/components/Drawer/Drawer.tsx +103 -0
  49. package/src/components/Drawer/__tests__/Drawer.test.tsx +56 -0
  50. package/src/components/EmptyState/EmptyState.module.css +27 -0
  51. package/src/components/EmptyState/EmptyState.tsx +27 -0
  52. package/src/components/FormField/FormField.module.css +28 -0
  53. package/src/components/FormField/FormField.tsx +53 -0
  54. package/src/components/Icon/Icon.module.css +22 -0
  55. package/src/components/Icon/Icon.stories.tsx +94 -0
  56. package/src/components/Icon/Icon.tsx +43 -0
  57. package/src/components/Icon/__tests__/Icon.test.tsx +40 -0
  58. package/src/components/Icon/icons/activity.tsx +20 -0
  59. package/src/components/Icon/icons/alert-triangle.tsx +22 -0
  60. package/src/components/Icon/icons/bell.tsx +21 -0
  61. package/src/components/Icon/icons/check.tsx +20 -0
  62. package/src/components/Icon/icons/chevron-down.tsx +20 -0
  63. package/src/components/Icon/icons/chevron-left.tsx +20 -0
  64. package/src/components/Icon/icons/chevron-right.tsx +20 -0
  65. package/src/components/Icon/icons/chevron-up.tsx +20 -0
  66. package/src/components/Icon/icons/eye-off.tsx +23 -0
  67. package/src/components/Icon/icons/eye.tsx +21 -0
  68. package/src/components/Icon/icons/grid-2x2.tsx +22 -0
  69. package/src/components/Icon/icons/house.tsx +21 -0
  70. package/src/components/Icon/icons/index.ts +122 -0
  71. package/src/components/Icon/icons/info.tsx +22 -0
  72. package/src/components/Icon/icons/lock.tsx +21 -0
  73. package/src/components/Icon/icons/log-out.tsx +22 -0
  74. package/src/components/Icon/icons/mail.tsx +21 -0
  75. package/src/components/Icon/icons/package.tsx +23 -0
  76. package/src/components/Icon/icons/pencil.tsx +21 -0
  77. package/src/components/Icon/icons/plus.tsx +21 -0
  78. package/src/components/Icon/icons/rotate-ccw.tsx +21 -0
  79. package/src/components/Icon/icons/search.tsx +21 -0
  80. package/src/components/Icon/icons/settings.tsx +21 -0
  81. package/src/components/Icon/icons/shield.tsx +20 -0
  82. package/src/components/Icon/icons/sliders-horizontal.tsx +28 -0
  83. package/src/components/Icon/icons/terminal.tsx +19 -0
  84. package/src/components/Icon/icons/trash-2.tsx +24 -0
  85. package/src/components/Icon/icons/user.tsx +21 -0
  86. package/src/components/Icon/icons/x.tsx +21 -0
  87. package/src/components/Input/Input.module.css +37 -0
  88. package/src/components/Input/Input.stories.tsx +86 -0
  89. package/src/components/Input/Input.tsx +14 -0
  90. package/src/components/Input/__tests__/Input.test.tsx +22 -0
  91. package/src/components/NavTabs/NavTabs.module.css +48 -0
  92. package/src/components/NavTabs/NavTabs.tsx +33 -0
  93. package/src/components/PageHeader/PageHeader.module.css +32 -0
  94. package/src/components/PageHeader/PageHeader.tsx +21 -0
  95. package/src/components/Popover/Popover.module.css +44 -0
  96. package/src/components/Popover/Popover.stories.tsx +232 -0
  97. package/src/components/Popover/Popover.tsx +75 -0
  98. package/src/components/Popover/__tests__/Popover.test.tsx +98 -0
  99. package/src/components/SegmentedControl/SegmentedControl.module.css +53 -0
  100. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +118 -0
  101. package/src/components/SegmentedControl/SegmentedControl.tsx +56 -0
  102. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +63 -0
  103. package/src/components/Select/Select.module.css +69 -0
  104. package/src/components/Select/Select.stories.tsx +115 -0
  105. package/src/components/Select/Select.tsx +40 -0
  106. package/src/components/Select/__tests__/Select.test.tsx +59 -0
  107. package/src/components/Spinner/Spinner.module.css +39 -0
  108. package/src/components/Spinner/Spinner.tsx +23 -0
  109. package/src/components/SystemBanner/SystemBanner.module.css +67 -0
  110. package/src/components/SystemBanner/SystemBanner.stories.tsx +86 -0
  111. package/src/components/SystemBanner/SystemBanner.tsx +50 -0
  112. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +50 -0
  113. package/src/components/Tabs/Tabs.module.css +49 -0
  114. package/src/components/Tabs/Tabs.stories.tsx +100 -0
  115. package/src/components/Tabs/Tabs.tsx +46 -0
  116. package/src/components/Tabs/__tests__/Tabs.test.tsx +45 -0
  117. package/src/components/Toast/Toast.module.css +130 -0
  118. package/src/components/Toast/Toast.stories.tsx +191 -0
  119. package/src/components/Toast/Toast.tsx +139 -0
  120. package/src/components/Toggle/Toggle.module.css +52 -0
  121. package/src/components/Toggle/Toggle.stories.tsx +95 -0
  122. package/src/components/Toggle/Toggle.tsx +39 -0
  123. package/src/components/Toggle/__tests__/Toggle.test.tsx +47 -0
  124. package/src/components/Tooltip/Tooltip.module.css +51 -0
  125. package/src/components/Tooltip/Tooltip.tsx +30 -0
  126. package/src/css-modules.d.ts +4 -0
  127. package/src/index.ts +45 -0
  128. package/src/stories/Avatar.stories.tsx +44 -0
  129. package/src/stories/Card.stories.tsx +35 -0
  130. package/src/stories/DesignSystemOverview.stories.tsx +1683 -0
  131. package/src/stories/EmptyState.stories.tsx +33 -0
  132. package/src/stories/FormField.stories.tsx +47 -0
  133. package/src/stories/MobilePatterns.stories.tsx +1285 -0
  134. package/src/stories/NavTabs.stories.tsx +35 -0
  135. package/src/stories/PageHeader.stories.tsx +31 -0
  136. package/src/stories/Spinner.stories.tsx +25 -0
  137. package/src/stories/TokenGallery.stories.tsx +355 -0
  138. package/src/stories/Tooltip.stories.tsx +59 -0
  139. package/src/tokens/primitives.css +99 -0
  140. package/src/tokens/semantic.css +111 -0
  141. package/src/tokens.css +5 -0
package/dist/index.js ADDED
@@ -0,0 +1,1370 @@
1
+ // src/components/Badge/Badge.tsx
2
+ import styles from "./Badge.module.css";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ var STATUS_DOT_CLASS = {
5
+ active: styles.dotGreen,
6
+ enabled: styles.dotGreen,
7
+ deactivated: styles.dotRed,
8
+ failed: styles.dotRed,
9
+ invited: styles.dotAmber,
10
+ pending: styles.dotAmber,
11
+ neutral: styles.dotGrey
12
+ };
13
+ var STATUS_CHIP_CLASS = {
14
+ active: styles.chipGreen,
15
+ enabled: styles.chipGreen,
16
+ deactivated: styles.chipRed,
17
+ failed: styles.chipRed,
18
+ invited: styles.chipAmber,
19
+ pending: styles.chipAmber,
20
+ neutral: styles.chipNeutral
21
+ };
22
+ function Badge({ variant = "role", status = "neutral", children }) {
23
+ const isStatus = variant === "status";
24
+ const dotClass = isStatus ? STATUS_DOT_CLASS[status] : void 0;
25
+ const chipClass = isStatus ? STATUS_CHIP_CLASS[status] : void 0;
26
+ return /* @__PURE__ */ jsxs("span", { className: [styles.badge, styles[variant], chipClass].filter(Boolean).join(" "), children: [
27
+ isStatus && /* @__PURE__ */ jsx("span", { className: [styles.dot, dotClass].join(" "), "aria-hidden": true }),
28
+ children
29
+ ] });
30
+ }
31
+
32
+ // src/components/Icon/icons/house.tsx
33
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
34
+ function HouseIcon(props) {
35
+ return /* @__PURE__ */ jsxs2(
36
+ "svg",
37
+ {
38
+ xmlns: "http://www.w3.org/2000/svg",
39
+ viewBox: "0 0 24 24",
40
+ fill: "none",
41
+ stroke: "currentColor",
42
+ strokeWidth: "2",
43
+ strokeLinecap: "round",
44
+ strokeLinejoin: "round",
45
+ ...props,
46
+ children: [
47
+ /* @__PURE__ */ jsx2("path", { d: "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" }),
48
+ /* @__PURE__ */ jsx2("path", { d: "M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" })
49
+ ]
50
+ }
51
+ );
52
+ }
53
+
54
+ // src/components/Icon/icons/settings.tsx
55
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
56
+ function SettingsIcon(props) {
57
+ return /* @__PURE__ */ jsxs3(
58
+ "svg",
59
+ {
60
+ xmlns: "http://www.w3.org/2000/svg",
61
+ viewBox: "0 0 24 24",
62
+ fill: "none",
63
+ stroke: "currentColor",
64
+ strokeWidth: "2",
65
+ strokeLinecap: "round",
66
+ strokeLinejoin: "round",
67
+ ...props,
68
+ children: [
69
+ /* @__PURE__ */ jsx3("path", { d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }),
70
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" })
71
+ ]
72
+ }
73
+ );
74
+ }
75
+
76
+ // src/components/Icon/icons/log-out.tsx
77
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
78
+ function LogOutIcon(props) {
79
+ return /* @__PURE__ */ jsxs4(
80
+ "svg",
81
+ {
82
+ xmlns: "http://www.w3.org/2000/svg",
83
+ viewBox: "0 0 24 24",
84
+ fill: "none",
85
+ stroke: "currentColor",
86
+ strokeWidth: "2",
87
+ strokeLinecap: "round",
88
+ strokeLinejoin: "round",
89
+ ...props,
90
+ children: [
91
+ /* @__PURE__ */ jsx4("path", { d: "m16 17 5-5-5-5" }),
92
+ /* @__PURE__ */ jsx4("path", { d: "M21 12H9" }),
93
+ /* @__PURE__ */ jsx4("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" })
94
+ ]
95
+ }
96
+ );
97
+ }
98
+
99
+ // src/components/Icon/icons/chevron-right.tsx
100
+ import { jsx as jsx5 } from "react/jsx-runtime";
101
+ function ChevronRightIcon(props) {
102
+ return /* @__PURE__ */ jsx5(
103
+ "svg",
104
+ {
105
+ xmlns: "http://www.w3.org/2000/svg",
106
+ viewBox: "0 0 24 24",
107
+ fill: "none",
108
+ stroke: "currentColor",
109
+ strokeWidth: "2",
110
+ strokeLinecap: "round",
111
+ strokeLinejoin: "round",
112
+ ...props,
113
+ children: /* @__PURE__ */ jsx5("path", { d: "m9 18 6-6-6-6" })
114
+ }
115
+ );
116
+ }
117
+
118
+ // src/components/Icon/icons/chevron-left.tsx
119
+ import { jsx as jsx6 } from "react/jsx-runtime";
120
+ function ChevronLeftIcon(props) {
121
+ return /* @__PURE__ */ jsx6(
122
+ "svg",
123
+ {
124
+ xmlns: "http://www.w3.org/2000/svg",
125
+ viewBox: "0 0 24 24",
126
+ fill: "none",
127
+ stroke: "currentColor",
128
+ strokeWidth: "2",
129
+ strokeLinecap: "round",
130
+ strokeLinejoin: "round",
131
+ ...props,
132
+ children: /* @__PURE__ */ jsx6("path", { d: "m15 18-6-6 6-6" })
133
+ }
134
+ );
135
+ }
136
+
137
+ // src/components/Icon/icons/chevron-down.tsx
138
+ import { jsx as jsx7 } from "react/jsx-runtime";
139
+ function ChevronDownIcon(props) {
140
+ return /* @__PURE__ */ jsx7(
141
+ "svg",
142
+ {
143
+ xmlns: "http://www.w3.org/2000/svg",
144
+ viewBox: "0 0 24 24",
145
+ fill: "none",
146
+ stroke: "currentColor",
147
+ strokeWidth: "2",
148
+ strokeLinecap: "round",
149
+ strokeLinejoin: "round",
150
+ ...props,
151
+ children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" })
152
+ }
153
+ );
154
+ }
155
+
156
+ // src/components/Icon/icons/chevron-up.tsx
157
+ import { jsx as jsx8 } from "react/jsx-runtime";
158
+ function ChevronUpIcon(props) {
159
+ return /* @__PURE__ */ jsx8(
160
+ "svg",
161
+ {
162
+ xmlns: "http://www.w3.org/2000/svg",
163
+ viewBox: "0 0 24 24",
164
+ fill: "none",
165
+ stroke: "currentColor",
166
+ strokeWidth: "2",
167
+ strokeLinecap: "round",
168
+ strokeLinejoin: "round",
169
+ ...props,
170
+ children: /* @__PURE__ */ jsx8("path", { d: "m18 15-6-6-6 6" })
171
+ }
172
+ );
173
+ }
174
+
175
+ // src/components/Icon/icons/x.tsx
176
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
177
+ function XIcon(props) {
178
+ return /* @__PURE__ */ jsxs5(
179
+ "svg",
180
+ {
181
+ xmlns: "http://www.w3.org/2000/svg",
182
+ viewBox: "0 0 24 24",
183
+ fill: "none",
184
+ stroke: "currentColor",
185
+ strokeWidth: "2",
186
+ strokeLinecap: "round",
187
+ strokeLinejoin: "round",
188
+ ...props,
189
+ children: [
190
+ /* @__PURE__ */ jsx9("path", { d: "M18 6 6 18" }),
191
+ /* @__PURE__ */ jsx9("path", { d: "m6 6 12 12" })
192
+ ]
193
+ }
194
+ );
195
+ }
196
+
197
+ // src/components/Icon/icons/check.tsx
198
+ import { jsx as jsx10 } from "react/jsx-runtime";
199
+ function CheckIcon(props) {
200
+ return /* @__PURE__ */ jsx10(
201
+ "svg",
202
+ {
203
+ xmlns: "http://www.w3.org/2000/svg",
204
+ viewBox: "0 0 24 24",
205
+ fill: "none",
206
+ stroke: "currentColor",
207
+ strokeWidth: "2",
208
+ strokeLinecap: "round",
209
+ strokeLinejoin: "round",
210
+ ...props,
211
+ children: /* @__PURE__ */ jsx10("path", { d: "M20 6 9 17l-5-5" })
212
+ }
213
+ );
214
+ }
215
+
216
+ // src/components/Icon/icons/plus.tsx
217
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
218
+ function PlusIcon(props) {
219
+ return /* @__PURE__ */ jsxs6(
220
+ "svg",
221
+ {
222
+ xmlns: "http://www.w3.org/2000/svg",
223
+ viewBox: "0 0 24 24",
224
+ fill: "none",
225
+ stroke: "currentColor",
226
+ strokeWidth: "2",
227
+ strokeLinecap: "round",
228
+ strokeLinejoin: "round",
229
+ ...props,
230
+ children: [
231
+ /* @__PURE__ */ jsx11("path", { d: "M5 12h14" }),
232
+ /* @__PURE__ */ jsx11("path", { d: "M12 5v14" })
233
+ ]
234
+ }
235
+ );
236
+ }
237
+
238
+ // src/components/Icon/icons/trash-2.tsx
239
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
240
+ function Trash2Icon(props) {
241
+ return /* @__PURE__ */ jsxs7(
242
+ "svg",
243
+ {
244
+ xmlns: "http://www.w3.org/2000/svg",
245
+ viewBox: "0 0 24 24",
246
+ fill: "none",
247
+ stroke: "currentColor",
248
+ strokeWidth: "2",
249
+ strokeLinecap: "round",
250
+ strokeLinejoin: "round",
251
+ ...props,
252
+ children: [
253
+ /* @__PURE__ */ jsx12("path", { d: "M10 11v6" }),
254
+ /* @__PURE__ */ jsx12("path", { d: "M14 11v6" }),
255
+ /* @__PURE__ */ jsx12("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
256
+ /* @__PURE__ */ jsx12("path", { d: "M3 6h18" }),
257
+ /* @__PURE__ */ jsx12("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
258
+ ]
259
+ }
260
+ );
261
+ }
262
+
263
+ // src/components/Icon/icons/pencil.tsx
264
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
265
+ function PencilIcon(props) {
266
+ return /* @__PURE__ */ jsxs8(
267
+ "svg",
268
+ {
269
+ xmlns: "http://www.w3.org/2000/svg",
270
+ viewBox: "0 0 24 24",
271
+ fill: "none",
272
+ stroke: "currentColor",
273
+ strokeWidth: "2",
274
+ strokeLinecap: "round",
275
+ strokeLinejoin: "round",
276
+ ...props,
277
+ children: [
278
+ /* @__PURE__ */ jsx13("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }),
279
+ /* @__PURE__ */ jsx13("path", { d: "m15 5 4 4" })
280
+ ]
281
+ }
282
+ );
283
+ }
284
+
285
+ // src/components/Icon/icons/rotate-ccw.tsx
286
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
287
+ function RotateCcwIcon(props) {
288
+ return /* @__PURE__ */ jsxs9(
289
+ "svg",
290
+ {
291
+ xmlns: "http://www.w3.org/2000/svg",
292
+ viewBox: "0 0 24 24",
293
+ fill: "none",
294
+ stroke: "currentColor",
295
+ strokeWidth: "2",
296
+ strokeLinecap: "round",
297
+ strokeLinejoin: "round",
298
+ ...props,
299
+ children: [
300
+ /* @__PURE__ */ jsx14("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
301
+ /* @__PURE__ */ jsx14("path", { d: "M3 3v5h5" })
302
+ ]
303
+ }
304
+ );
305
+ }
306
+
307
+ // src/components/Icon/icons/search.tsx
308
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
309
+ function SearchIcon(props) {
310
+ return /* @__PURE__ */ jsxs10(
311
+ "svg",
312
+ {
313
+ xmlns: "http://www.w3.org/2000/svg",
314
+ viewBox: "0 0 24 24",
315
+ fill: "none",
316
+ stroke: "currentColor",
317
+ strokeWidth: "2",
318
+ strokeLinecap: "round",
319
+ strokeLinejoin: "round",
320
+ ...props,
321
+ children: [
322
+ /* @__PURE__ */ jsx15("path", { d: "m21 21-4.34-4.34" }),
323
+ /* @__PURE__ */ jsx15("circle", { cx: "11", cy: "11", r: "8" })
324
+ ]
325
+ }
326
+ );
327
+ }
328
+
329
+ // src/components/Icon/icons/user.tsx
330
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
331
+ function UserIcon(props) {
332
+ return /* @__PURE__ */ jsxs11(
333
+ "svg",
334
+ {
335
+ xmlns: "http://www.w3.org/2000/svg",
336
+ viewBox: "0 0 24 24",
337
+ fill: "none",
338
+ stroke: "currentColor",
339
+ strokeWidth: "2",
340
+ strokeLinecap: "round",
341
+ strokeLinejoin: "round",
342
+ ...props,
343
+ children: [
344
+ /* @__PURE__ */ jsx16("path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }),
345
+ /* @__PURE__ */ jsx16("circle", { cx: "12", cy: "7", r: "4" })
346
+ ]
347
+ }
348
+ );
349
+ }
350
+
351
+ // src/components/Icon/icons/shield.tsx
352
+ import { jsx as jsx17 } from "react/jsx-runtime";
353
+ function ShieldIcon(props) {
354
+ return /* @__PURE__ */ jsx17(
355
+ "svg",
356
+ {
357
+ xmlns: "http://www.w3.org/2000/svg",
358
+ viewBox: "0 0 24 24",
359
+ fill: "none",
360
+ stroke: "currentColor",
361
+ strokeWidth: "2",
362
+ strokeLinecap: "round",
363
+ strokeLinejoin: "round",
364
+ ...props,
365
+ children: /* @__PURE__ */ jsx17("path", { d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" })
366
+ }
367
+ );
368
+ }
369
+
370
+ // src/components/Icon/icons/lock.tsx
371
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
372
+ function LockIcon(props) {
373
+ return /* @__PURE__ */ jsxs12(
374
+ "svg",
375
+ {
376
+ xmlns: "http://www.w3.org/2000/svg",
377
+ viewBox: "0 0 24 24",
378
+ fill: "none",
379
+ stroke: "currentColor",
380
+ strokeWidth: "2",
381
+ strokeLinecap: "round",
382
+ strokeLinejoin: "round",
383
+ ...props,
384
+ children: [
385
+ /* @__PURE__ */ jsx18("rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }),
386
+ /* @__PURE__ */ jsx18("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
387
+ ]
388
+ }
389
+ );
390
+ }
391
+
392
+ // src/components/Icon/icons/eye.tsx
393
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
394
+ function EyeIcon(props) {
395
+ return /* @__PURE__ */ jsxs13(
396
+ "svg",
397
+ {
398
+ xmlns: "http://www.w3.org/2000/svg",
399
+ viewBox: "0 0 24 24",
400
+ fill: "none",
401
+ stroke: "currentColor",
402
+ strokeWidth: "2",
403
+ strokeLinecap: "round",
404
+ strokeLinejoin: "round",
405
+ ...props,
406
+ children: [
407
+ /* @__PURE__ */ jsx19("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
408
+ /* @__PURE__ */ jsx19("circle", { cx: "12", cy: "12", r: "3" })
409
+ ]
410
+ }
411
+ );
412
+ }
413
+
414
+ // src/components/Icon/icons/eye-off.tsx
415
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
416
+ function EyeOffIcon(props) {
417
+ return /* @__PURE__ */ jsxs14(
418
+ "svg",
419
+ {
420
+ xmlns: "http://www.w3.org/2000/svg",
421
+ viewBox: "0 0 24 24",
422
+ fill: "none",
423
+ stroke: "currentColor",
424
+ strokeWidth: "2",
425
+ strokeLinecap: "round",
426
+ strokeLinejoin: "round",
427
+ ...props,
428
+ children: [
429
+ /* @__PURE__ */ jsx20("path", { d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }),
430
+ /* @__PURE__ */ jsx20("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
431
+ /* @__PURE__ */ jsx20("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
432
+ /* @__PURE__ */ jsx20("path", { d: "m2 2 20 20" })
433
+ ]
434
+ }
435
+ );
436
+ }
437
+
438
+ // src/components/Icon/icons/mail.tsx
439
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
440
+ function MailIcon(props) {
441
+ return /* @__PURE__ */ jsxs15(
442
+ "svg",
443
+ {
444
+ xmlns: "http://www.w3.org/2000/svg",
445
+ viewBox: "0 0 24 24",
446
+ fill: "none",
447
+ stroke: "currentColor",
448
+ strokeWidth: "2",
449
+ strokeLinecap: "round",
450
+ strokeLinejoin: "round",
451
+ ...props,
452
+ children: [
453
+ /* @__PURE__ */ jsx21("path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" }),
454
+ /* @__PURE__ */ jsx21("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" })
455
+ ]
456
+ }
457
+ );
458
+ }
459
+
460
+ // src/components/Icon/icons/bell.tsx
461
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
462
+ function BellIcon(props) {
463
+ return /* @__PURE__ */ jsxs16(
464
+ "svg",
465
+ {
466
+ xmlns: "http://www.w3.org/2000/svg",
467
+ viewBox: "0 0 24 24",
468
+ fill: "none",
469
+ stroke: "currentColor",
470
+ strokeWidth: "2",
471
+ strokeLinecap: "round",
472
+ strokeLinejoin: "round",
473
+ ...props,
474
+ children: [
475
+ /* @__PURE__ */ jsx22("path", { d: "M10.268 21a2 2 0 0 0 3.464 0" }),
476
+ /* @__PURE__ */ jsx22("path", { d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" })
477
+ ]
478
+ }
479
+ );
480
+ }
481
+
482
+ // src/components/Icon/icons/activity.tsx
483
+ import { jsx as jsx23 } from "react/jsx-runtime";
484
+ function ActivityIcon(props) {
485
+ return /* @__PURE__ */ jsx23(
486
+ "svg",
487
+ {
488
+ xmlns: "http://www.w3.org/2000/svg",
489
+ viewBox: "0 0 24 24",
490
+ fill: "none",
491
+ stroke: "currentColor",
492
+ strokeWidth: "2",
493
+ strokeLinecap: "round",
494
+ strokeLinejoin: "round",
495
+ ...props,
496
+ children: /* @__PURE__ */ jsx23("path", { d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" })
497
+ }
498
+ );
499
+ }
500
+
501
+ // src/components/Icon/icons/package.tsx
502
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
503
+ function PackageIcon(props) {
504
+ return /* @__PURE__ */ jsxs17(
505
+ "svg",
506
+ {
507
+ xmlns: "http://www.w3.org/2000/svg",
508
+ viewBox: "0 0 24 24",
509
+ fill: "none",
510
+ stroke: "currentColor",
511
+ strokeWidth: "2",
512
+ strokeLinecap: "round",
513
+ strokeLinejoin: "round",
514
+ ...props,
515
+ children: [
516
+ /* @__PURE__ */ jsx24("path", { d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" }),
517
+ /* @__PURE__ */ jsx24("path", { d: "M12 22V12" }),
518
+ /* @__PURE__ */ jsx24("polyline", { points: "3.29 7 12 12 20.71 7" }),
519
+ /* @__PURE__ */ jsx24("path", { d: "m7.5 4.27 9 5.15" })
520
+ ]
521
+ }
522
+ );
523
+ }
524
+
525
+ // src/components/Icon/icons/grid-2x2.tsx
526
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
527
+ function Grid2x2Icon(props) {
528
+ return /* @__PURE__ */ jsxs18(
529
+ "svg",
530
+ {
531
+ xmlns: "http://www.w3.org/2000/svg",
532
+ viewBox: "0 0 24 24",
533
+ fill: "none",
534
+ stroke: "currentColor",
535
+ strokeWidth: "2",
536
+ strokeLinecap: "round",
537
+ strokeLinejoin: "round",
538
+ ...props,
539
+ children: [
540
+ /* @__PURE__ */ jsx25("path", { d: "M12 3v18" }),
541
+ /* @__PURE__ */ jsx25("path", { d: "M3 12h18" }),
542
+ /* @__PURE__ */ jsx25("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" })
543
+ ]
544
+ }
545
+ );
546
+ }
547
+
548
+ // src/components/Icon/icons/info.tsx
549
+ import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
550
+ function InfoIcon(props) {
551
+ return /* @__PURE__ */ jsxs19(
552
+ "svg",
553
+ {
554
+ xmlns: "http://www.w3.org/2000/svg",
555
+ viewBox: "0 0 24 24",
556
+ fill: "none",
557
+ stroke: "currentColor",
558
+ strokeWidth: "2",
559
+ strokeLinecap: "round",
560
+ strokeLinejoin: "round",
561
+ ...props,
562
+ children: [
563
+ /* @__PURE__ */ jsx26("circle", { cx: "12", cy: "12", r: "10" }),
564
+ /* @__PURE__ */ jsx26("path", { d: "M12 16v-4" }),
565
+ /* @__PURE__ */ jsx26("path", { d: "M12 8h.01" })
566
+ ]
567
+ }
568
+ );
569
+ }
570
+
571
+ // src/components/Icon/icons/alert-triangle.tsx
572
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
573
+ function AlertTriangleIcon(props) {
574
+ return /* @__PURE__ */ jsxs20(
575
+ "svg",
576
+ {
577
+ xmlns: "http://www.w3.org/2000/svg",
578
+ viewBox: "0 0 24 24",
579
+ fill: "none",
580
+ stroke: "currentColor",
581
+ strokeWidth: "2",
582
+ strokeLinecap: "round",
583
+ strokeLinejoin: "round",
584
+ ...props,
585
+ children: [
586
+ /* @__PURE__ */ jsx27("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
587
+ /* @__PURE__ */ jsx27("path", { d: "M12 9v4" }),
588
+ /* @__PURE__ */ jsx27("path", { d: "M12 17h.01" })
589
+ ]
590
+ }
591
+ );
592
+ }
593
+
594
+ // src/components/Icon/icons/sliders-horizontal.tsx
595
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
596
+ function SlidersHorizontalIcon(props) {
597
+ return /* @__PURE__ */ jsxs21(
598
+ "svg",
599
+ {
600
+ xmlns: "http://www.w3.org/2000/svg",
601
+ viewBox: "0 0 24 24",
602
+ fill: "none",
603
+ stroke: "currentColor",
604
+ strokeWidth: "2",
605
+ strokeLinecap: "round",
606
+ strokeLinejoin: "round",
607
+ ...props,
608
+ children: [
609
+ /* @__PURE__ */ jsx28("line", { x1: "21", x2: "14", y1: "4", y2: "4" }),
610
+ /* @__PURE__ */ jsx28("line", { x1: "10", x2: "3", y1: "4", y2: "4" }),
611
+ /* @__PURE__ */ jsx28("line", { x1: "21", x2: "12", y1: "12", y2: "12" }),
612
+ /* @__PURE__ */ jsx28("line", { x1: "8", x2: "3", y1: "12", y2: "12" }),
613
+ /* @__PURE__ */ jsx28("line", { x1: "21", x2: "16", y1: "20", y2: "20" }),
614
+ /* @__PURE__ */ jsx28("line", { x1: "12", x2: "3", y1: "20", y2: "20" }),
615
+ /* @__PURE__ */ jsx28("line", { x1: "14", x2: "14", y1: "2", y2: "6" }),
616
+ /* @__PURE__ */ jsx28("line", { x1: "8", x2: "8", y1: "10", y2: "14" }),
617
+ /* @__PURE__ */ jsx28("line", { x1: "16", x2: "16", y1: "18", y2: "22" })
618
+ ]
619
+ }
620
+ );
621
+ }
622
+
623
+ // src/components/Icon/icons/terminal.tsx
624
+ import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
625
+ function TerminalIcon(props) {
626
+ return /* @__PURE__ */ jsxs22(
627
+ "svg",
628
+ {
629
+ xmlns: "http://www.w3.org/2000/svg",
630
+ viewBox: "0 0 24 24",
631
+ fill: "none",
632
+ stroke: "currentColor",
633
+ strokeWidth: "2",
634
+ strokeLinecap: "round",
635
+ strokeLinejoin: "round",
636
+ ...props,
637
+ children: [
638
+ /* @__PURE__ */ jsx29("polyline", { points: "4 17 10 11 4 5" }),
639
+ /* @__PURE__ */ jsx29("line", { x1: "12", x2: "20", y1: "19", y2: "19" })
640
+ ]
641
+ }
642
+ );
643
+ }
644
+
645
+ // src/components/Icon/icons/index.ts
646
+ var ICONS = {
647
+ house: HouseIcon,
648
+ settings: SettingsIcon,
649
+ "log-out": LogOutIcon,
650
+ "chevron-right": ChevronRightIcon,
651
+ "chevron-left": ChevronLeftIcon,
652
+ "chevron-down": ChevronDownIcon,
653
+ "chevron-up": ChevronUpIcon,
654
+ x: XIcon,
655
+ check: CheckIcon,
656
+ plus: PlusIcon,
657
+ "trash-2": Trash2Icon,
658
+ pencil: PencilIcon,
659
+ "rotate-ccw": RotateCcwIcon,
660
+ search: SearchIcon,
661
+ user: UserIcon,
662
+ shield: ShieldIcon,
663
+ lock: LockIcon,
664
+ eye: EyeIcon,
665
+ "eye-off": EyeOffIcon,
666
+ mail: MailIcon,
667
+ bell: BellIcon,
668
+ activity: ActivityIcon,
669
+ package: PackageIcon,
670
+ "grid-2x2": Grid2x2Icon,
671
+ info: InfoIcon,
672
+ "alert-triangle": AlertTriangleIcon,
673
+ "sliders-horizontal": SlidersHorizontalIcon,
674
+ terminal: TerminalIcon
675
+ };
676
+
677
+ // src/components/Icon/Icon.tsx
678
+ import styles2 from "./Icon.module.css";
679
+ import { jsx as jsx30 } from "react/jsx-runtime";
680
+ function Icon({
681
+ name,
682
+ size = "md",
683
+ className,
684
+ ...aria
685
+ }) {
686
+ const Svg = ICONS[name];
687
+ const classes = [styles2.root, styles2[size], className].filter(Boolean).join(" ");
688
+ return /* @__PURE__ */ jsx30(Svg, { className: classes, role: aria["aria-label"] ? "img" : void 0, ...aria });
689
+ }
690
+
691
+ // src/components/Toggle/Toggle.tsx
692
+ import styles3 from "./Toggle.module.css";
693
+ import { jsx as jsx31 } from "react/jsx-runtime";
694
+ function Toggle({ checked, onChange, disabled, className, ...rest }) {
695
+ return /* @__PURE__ */ jsx31(
696
+ "button",
697
+ {
698
+ type: "button",
699
+ role: "switch",
700
+ "aria-checked": checked,
701
+ disabled,
702
+ className: [styles3.track, checked ? styles3.on : styles3.off, className].filter(Boolean).join(" "),
703
+ onClick: () => onChange(!checked),
704
+ ...rest,
705
+ children: /* @__PURE__ */ jsx31("span", { className: styles3.thumb })
706
+ }
707
+ );
708
+ }
709
+
710
+ // src/components/SegmentedControl/SegmentedControl.tsx
711
+ import styles4 from "./SegmentedControl.module.css";
712
+ import { jsx as jsx32 } from "react/jsx-runtime";
713
+ function SegmentedControl({
714
+ value,
715
+ onChange,
716
+ options,
717
+ size = "md",
718
+ "aria-label": ariaLabel
719
+ }) {
720
+ return /* @__PURE__ */ jsx32(
721
+ "div",
722
+ {
723
+ role: "radiogroup",
724
+ "aria-label": ariaLabel,
725
+ className: [styles4.track, styles4[size]].join(" "),
726
+ children: options.map((opt) => {
727
+ const active = opt.value === value;
728
+ return /* @__PURE__ */ jsx32(
729
+ "button",
730
+ {
731
+ type: "button",
732
+ role: "radio",
733
+ "aria-checked": active,
734
+ className: [styles4.segment, active ? styles4.active : styles4.inactive].join(" "),
735
+ onClick: () => onChange(opt.value),
736
+ children: opt.label
737
+ },
738
+ opt.value
739
+ );
740
+ })
741
+ }
742
+ );
743
+ }
744
+
745
+ // src/components/Tabs/Tabs.tsx
746
+ import styles5 from "./Tabs.module.css";
747
+ import { jsx as jsx33 } from "react/jsx-runtime";
748
+ function Tabs({ items, value, onChange, "aria-label": ariaLabel }) {
749
+ return /* @__PURE__ */ jsx33("div", { role: "tablist", "aria-label": ariaLabel, className: styles5.tablist, children: items.map((item) => {
750
+ const active = item.value === value;
751
+ return /* @__PURE__ */ jsx33(
752
+ "button",
753
+ {
754
+ type: "button",
755
+ role: "tab",
756
+ "aria-selected": active,
757
+ className: [styles5.tab, active ? styles5.active : styles5.inactive].join(" "),
758
+ onClick: () => onChange(item.value),
759
+ children: item.label
760
+ },
761
+ item.value
762
+ );
763
+ }) });
764
+ }
765
+
766
+ // src/components/Select/Select.tsx
767
+ import styles6 from "./Select.module.css";
768
+ import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
769
+ function Select({ className, size = "md", children, ...rest }) {
770
+ return /* @__PURE__ */ jsxs23(
771
+ "div",
772
+ {
773
+ className: [styles6.wrapper, size === "sm" ? styles6.sm : void 0].filter(Boolean).join(" "),
774
+ children: [
775
+ /* @__PURE__ */ jsx34("select", { className: [styles6.select, className].filter(Boolean).join(" "), ...rest, children }),
776
+ /* @__PURE__ */ jsx34(
777
+ "svg",
778
+ {
779
+ className: styles6.chevron,
780
+ "aria-hidden": "true",
781
+ width: "12",
782
+ height: "12",
783
+ viewBox: "0 0 24 24",
784
+ fill: "none",
785
+ stroke: "currentColor",
786
+ strokeWidth: "2",
787
+ strokeLinecap: "round",
788
+ strokeLinejoin: "round",
789
+ children: /* @__PURE__ */ jsx34("polyline", { points: "6 9 12 15 18 9" })
790
+ }
791
+ )
792
+ ]
793
+ }
794
+ );
795
+ }
796
+
797
+ // src/components/SystemBanner/SystemBanner.tsx
798
+ import styles7 from "./SystemBanner.module.css";
799
+ import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
800
+ function SystemBanner({ variant = "info", onDismiss, children }) {
801
+ return /* @__PURE__ */ jsxs24("div", { role: "status", "aria-live": "polite", className: [styles7.banner, styles7[variant]].join(" "), children: [
802
+ /* @__PURE__ */ jsx35("span", { className: styles7.content, children }),
803
+ onDismiss && /* @__PURE__ */ jsx35(
804
+ "button",
805
+ {
806
+ type: "button",
807
+ className: styles7.dismiss,
808
+ onClick: onDismiss,
809
+ "aria-label": "Dismiss banner",
810
+ children: /* @__PURE__ */ jsx35(
811
+ "svg",
812
+ {
813
+ width: "14",
814
+ height: "14",
815
+ viewBox: "0 0 14 14",
816
+ fill: "none",
817
+ xmlns: "http://www.w3.org/2000/svg",
818
+ "aria-hidden": true,
819
+ children: /* @__PURE__ */ jsx35(
820
+ "path",
821
+ {
822
+ d: "M1 1L13 13M13 1L1 13",
823
+ stroke: "currentColor",
824
+ strokeWidth: "1.5",
825
+ strokeLinecap: "round"
826
+ }
827
+ )
828
+ }
829
+ )
830
+ }
831
+ )
832
+ ] });
833
+ }
834
+
835
+ // src/components/Popover/Popover.tsx
836
+ import { useEffect, useRef } from "react";
837
+ import styles8 from "./Popover.module.css";
838
+ import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
839
+ function Popover({
840
+ trigger,
841
+ open,
842
+ onClose,
843
+ align = "right",
844
+ width = 288,
845
+ "aria-label": ariaLabel,
846
+ children
847
+ }) {
848
+ const containerRef = useRef(null);
849
+ useEffect(() => {
850
+ if (!open) return;
851
+ function handleMouseDown(e) {
852
+ if (!containerRef.current?.contains(e.target)) {
853
+ onClose();
854
+ }
855
+ }
856
+ document.addEventListener("mousedown", handleMouseDown);
857
+ return () => document.removeEventListener("mousedown", handleMouseDown);
858
+ }, [open, onClose]);
859
+ useEffect(() => {
860
+ if (!open) return;
861
+ function handleKeyDown(e) {
862
+ if (e.key === "Escape") onClose();
863
+ }
864
+ document.addEventListener("keydown", handleKeyDown);
865
+ return () => document.removeEventListener("keydown", handleKeyDown);
866
+ }, [open, onClose]);
867
+ return /* @__PURE__ */ jsxs25("div", { ref: containerRef, className: styles8.container, children: [
868
+ trigger,
869
+ open && /* @__PURE__ */ jsx36(
870
+ "div",
871
+ {
872
+ role: "dialog",
873
+ "aria-label": ariaLabel,
874
+ "aria-modal": false,
875
+ className: [styles8.panel, styles8[align]].join(" "),
876
+ style: { width },
877
+ children
878
+ }
879
+ )
880
+ ] });
881
+ }
882
+
883
+ // src/components/Button/Button.tsx
884
+ import styles9 from "./Button.module.css";
885
+ import { jsx as jsx37 } from "react/jsx-runtime";
886
+ function Button({
887
+ variant = "primary",
888
+ size = "md",
889
+ type = "button",
890
+ className,
891
+ children,
892
+ ...rest
893
+ }) {
894
+ const classes = [styles9.button, styles9[variant], styles9[size], className].filter(Boolean).join(" ");
895
+ return /* @__PURE__ */ jsx37("button", { type, className: classes, ...rest, children });
896
+ }
897
+
898
+ // src/components/Input/Input.tsx
899
+ import styles10 from "./Input.module.css";
900
+ import { jsx as jsx38 } from "react/jsx-runtime";
901
+ function Input({ type = "text", className, ...rest }) {
902
+ const classes = [styles10.input, className].filter(Boolean).join(" ");
903
+ return /* @__PURE__ */ jsx38("input", { type, className: classes, ...rest });
904
+ }
905
+
906
+ // src/components/Dialog/Dialog.tsx
907
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
908
+ import styles11 from "./Dialog.module.css";
909
+ import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
910
+ var FOCUSABLE = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
911
+ function Dialog({
912
+ open,
913
+ onClose,
914
+ size = "lg",
915
+ "aria-label": ariaLabel,
916
+ title,
917
+ children
918
+ }) {
919
+ const panelRef = useRef2(null);
920
+ const previouslyFocused = useRef2(null);
921
+ useEffect2(() => {
922
+ if (!open) return;
923
+ previouslyFocused.current = document.activeElement;
924
+ const panel = panelRef.current;
925
+ const first = panel?.querySelector(FOCUSABLE);
926
+ (first ?? panel)?.focus();
927
+ return () => previouslyFocused.current?.focus();
928
+ }, [open]);
929
+ useEffect2(() => {
930
+ if (!open) return;
931
+ function handleKeyDown(e) {
932
+ if (e.key === "Escape") {
933
+ e.stopPropagation();
934
+ onClose();
935
+ return;
936
+ }
937
+ if (e.key !== "Tab") return;
938
+ const panel = panelRef.current;
939
+ if (!panel) return;
940
+ const focusable = [...panel.querySelectorAll(FOCUSABLE)];
941
+ const first = focusable[0];
942
+ const last = focusable.at(-1);
943
+ if (!first || !last) {
944
+ e.preventDefault();
945
+ return;
946
+ }
947
+ const active = document.activeElement;
948
+ if (e.shiftKey && active === first) {
949
+ e.preventDefault();
950
+ last.focus();
951
+ } else if (!e.shiftKey && active === last) {
952
+ e.preventDefault();
953
+ first.focus();
954
+ }
955
+ }
956
+ document.addEventListener("keydown", handleKeyDown);
957
+ return () => document.removeEventListener("keydown", handleKeyDown);
958
+ }, [open, onClose]);
959
+ if (!open) return null;
960
+ return (
961
+ // role="presentation" removes the scrim from the AT (it is purely visual).
962
+ // e.target check lets clicks inside the panel bubble without triggering dismiss.
963
+ /* @__PURE__ */ jsx39(
964
+ "div",
965
+ {
966
+ className: styles11.scrim,
967
+ role: "presentation",
968
+ onClick: (e) => {
969
+ if (e.target === e.currentTarget) onClose();
970
+ },
971
+ onKeyDown: (e) => {
972
+ if (e.key === "Escape") onClose();
973
+ },
974
+ children: /* @__PURE__ */ jsxs26(
975
+ "div",
976
+ {
977
+ ref: panelRef,
978
+ role: "dialog",
979
+ "aria-modal": "true",
980
+ "aria-label": ariaLabel ?? title,
981
+ tabIndex: -1,
982
+ className: [styles11.panel, styles11[size]].join(" "),
983
+ children: [
984
+ /* @__PURE__ */ jsxs26("div", { className: styles11.mobileBar, children: [
985
+ title && /* @__PURE__ */ jsx39("span", { className: styles11.mobileBarTitle, children: title }),
986
+ /* @__PURE__ */ jsx39(
987
+ "button",
988
+ {
989
+ type: "button",
990
+ className: styles11.mobileBarClose,
991
+ "aria-label": "Close",
992
+ onClick: onClose,
993
+ children: "\xD7"
994
+ }
995
+ )
996
+ ] }),
997
+ /* @__PURE__ */ jsx39("button", { type: "button", className: styles11.close, "aria-label": "Close", onClick: onClose, children: "\xD7" }),
998
+ /* @__PURE__ */ jsx39("div", { className: styles11.content, children })
999
+ ]
1000
+ }
1001
+ )
1002
+ }
1003
+ )
1004
+ );
1005
+ }
1006
+
1007
+ // src/components/Drawer/Drawer.tsx
1008
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
1009
+ import styles12 from "./Drawer.module.css";
1010
+ import { jsx as jsx40 } from "react/jsx-runtime";
1011
+ var FOCUSABLE2 = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
1012
+ function Drawer({ open, onClose, "aria-label": ariaLabel, children }) {
1013
+ const panelRef = useRef3(null);
1014
+ const previouslyFocused = useRef3(null);
1015
+ useEffect3(() => {
1016
+ if (!open) return;
1017
+ previouslyFocused.current = document.activeElement;
1018
+ const panel = panelRef.current;
1019
+ const first = panel?.querySelector(FOCUSABLE2);
1020
+ (first ?? panel)?.focus();
1021
+ return () => previouslyFocused.current?.focus();
1022
+ }, [open]);
1023
+ useEffect3(() => {
1024
+ if (!open) return;
1025
+ function handleKeyDown(e) {
1026
+ if (e.key === "Escape") {
1027
+ e.stopPropagation();
1028
+ onClose();
1029
+ return;
1030
+ }
1031
+ if (e.key !== "Tab") return;
1032
+ const panel = panelRef.current;
1033
+ if (!panel) return;
1034
+ const focusable = [...panel.querySelectorAll(FOCUSABLE2)];
1035
+ const first = focusable[0];
1036
+ const last = focusable.at(-1);
1037
+ if (!first || !last) {
1038
+ e.preventDefault();
1039
+ return;
1040
+ }
1041
+ const active = document.activeElement;
1042
+ if (e.shiftKey && active === first) {
1043
+ e.preventDefault();
1044
+ last.focus();
1045
+ } else if (!e.shiftKey && active === last) {
1046
+ e.preventDefault();
1047
+ first.focus();
1048
+ }
1049
+ }
1050
+ document.addEventListener("keydown", handleKeyDown);
1051
+ return () => document.removeEventListener("keydown", handleKeyDown);
1052
+ }, [open, onClose]);
1053
+ if (!open) return null;
1054
+ return (
1055
+ // role="presentation" removes the scrim from the AT (it is purely visual).
1056
+ // e.target check lets clicks inside the panel bubble without triggering dismiss.
1057
+ /* @__PURE__ */ jsx40(
1058
+ "div",
1059
+ {
1060
+ className: styles12.scrim,
1061
+ role: "presentation",
1062
+ onClick: (e) => {
1063
+ if (e.target === e.currentTarget) onClose();
1064
+ },
1065
+ onKeyDown: (e) => {
1066
+ if (e.key === "Escape") onClose();
1067
+ },
1068
+ children: /* @__PURE__ */ jsx40(
1069
+ "div",
1070
+ {
1071
+ ref: panelRef,
1072
+ role: "dialog",
1073
+ "aria-modal": "true",
1074
+ "aria-label": ariaLabel,
1075
+ tabIndex: -1,
1076
+ className: styles12.panel,
1077
+ children
1078
+ }
1079
+ )
1080
+ }
1081
+ )
1082
+ );
1083
+ }
1084
+
1085
+ // src/components/Toast/Toast.tsx
1086
+ import {
1087
+ createContext,
1088
+ useCallback,
1089
+ useContext,
1090
+ useEffect as useEffect4,
1091
+ useId,
1092
+ useMemo,
1093
+ useRef as useRef4,
1094
+ useState
1095
+ } from "react";
1096
+ import styles13 from "./Toast.module.css";
1097
+ import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
1098
+ var ToastContext = createContext(null);
1099
+ function useToast() {
1100
+ const ctx = useContext(ToastContext);
1101
+ if (!ctx) throw new Error("useToast() must be used inside <ToastProvider>");
1102
+ return ctx;
1103
+ }
1104
+ function ToastProvider({ children }) {
1105
+ const [toasts, setToasts] = useState([]);
1106
+ const timers = useRef4(/* @__PURE__ */ new Map());
1107
+ const seedId = useId();
1108
+ const counter = useRef4(0);
1109
+ const dismiss = useCallback((id) => {
1110
+ setToasts((prev) => prev.map((t) => t.id === id ? { ...t, exiting: true } : t));
1111
+ setTimeout(() => {
1112
+ setToasts((prev) => prev.filter((t) => t.id !== id));
1113
+ }, 220);
1114
+ }, []);
1115
+ const show = useCallback(
1116
+ (item) => {
1117
+ const id = `${seedId}-${++counter.current}`;
1118
+ const duration = item.duration ?? 5e3;
1119
+ setToasts((prev) => [...prev, { ...item, id }]);
1120
+ if (duration > 0) {
1121
+ const timer = setTimeout(() => dismiss(id), duration);
1122
+ timers.current.set(id, timer);
1123
+ }
1124
+ return id;
1125
+ },
1126
+ [seedId, dismiss]
1127
+ );
1128
+ useEffect4(() => {
1129
+ const currentTimers = timers.current;
1130
+ return () => {
1131
+ currentTimers.forEach((t) => clearTimeout(t));
1132
+ };
1133
+ }, []);
1134
+ const value = useMemo(() => ({ show, dismiss }), [show, dismiss]);
1135
+ return /* @__PURE__ */ jsxs27(ToastContext.Provider, { value, children: [
1136
+ children,
1137
+ /* @__PURE__ */ jsx41(
1138
+ "ol",
1139
+ {
1140
+ className: styles13.region,
1141
+ "aria-label": "Notifications",
1142
+ "aria-live": "polite",
1143
+ "aria-atomic": "false",
1144
+ children: toasts.map((toast) => /* @__PURE__ */ jsx41(Toast, { ...toast, onDismiss: dismiss }, toast.id))
1145
+ }
1146
+ )
1147
+ ] });
1148
+ }
1149
+ var CATEGORY_ICON = {
1150
+ info: "info",
1151
+ announcement: "info",
1152
+ success: "check",
1153
+ warning: "alert-triangle",
1154
+ error: "alert-triangle",
1155
+ security: "alert-triangle"
1156
+ };
1157
+ function Toast({
1158
+ id,
1159
+ title,
1160
+ message,
1161
+ category = "info",
1162
+ exiting,
1163
+ onDismiss
1164
+ }) {
1165
+ const categoryClass = styles13[category] ?? styles13.info;
1166
+ const iconName = CATEGORY_ICON[category] ?? "info";
1167
+ return /* @__PURE__ */ jsxs27(
1168
+ "li",
1169
+ {
1170
+ role: "status",
1171
+ className: `${styles13.toast} ${String(categoryClass)} ${exiting ? styles13.exiting : ""}`,
1172
+ children: [
1173
+ /* @__PURE__ */ jsx41("span", { className: styles13.icon, "aria-hidden": "true", children: /* @__PURE__ */ jsx41(Icon, { name: iconName, size: "sm", "aria-hidden": true }) }),
1174
+ /* @__PURE__ */ jsxs27("div", { className: styles13.body, children: [
1175
+ /* @__PURE__ */ jsx41("div", { className: styles13.title, children: title }),
1176
+ message && /* @__PURE__ */ jsx41("div", { className: styles13.message, children: message })
1177
+ ] }),
1178
+ /* @__PURE__ */ jsx41(
1179
+ "button",
1180
+ {
1181
+ type: "button",
1182
+ className: styles13.close,
1183
+ "aria-label": "Dismiss notification",
1184
+ onClick: () => onDismiss(id),
1185
+ children: "\u2715"
1186
+ }
1187
+ )
1188
+ ]
1189
+ }
1190
+ );
1191
+ }
1192
+
1193
+ // src/components/Card/Card.tsx
1194
+ import styles14 from "./Card.module.css";
1195
+ import { jsx as jsx42 } from "react/jsx-runtime";
1196
+ var paddingClass = {
1197
+ sm: styles14.paddingSm,
1198
+ md: styles14.paddingMd,
1199
+ lg: styles14.paddingLg
1200
+ };
1201
+ function Card({
1202
+ as: Tag = "div",
1203
+ interactive = false,
1204
+ padding = "md",
1205
+ className,
1206
+ children,
1207
+ ...rest
1208
+ }) {
1209
+ const cls = [styles14.card, paddingClass[padding], interactive && styles14.interactive, className].filter(Boolean).join(" ");
1210
+ return /* @__PURE__ */ jsx42(Tag, { className: cls, ...rest, children });
1211
+ }
1212
+
1213
+ // src/components/FormField/FormField.tsx
1214
+ import { useId as useId2 } from "react";
1215
+ import styles15 from "./FormField.module.css";
1216
+ import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
1217
+ function FormField({
1218
+ label,
1219
+ hint,
1220
+ error,
1221
+ htmlFor,
1222
+ required = false,
1223
+ children,
1224
+ className
1225
+ }) {
1226
+ const hintId = useId2();
1227
+ const errorId = useId2();
1228
+ const describedBy = [hint && hintId, error && errorId].filter(Boolean).join(" ") || void 0;
1229
+ return /* @__PURE__ */ jsxs28("div", { className: [styles15.field, className].filter(Boolean).join(" "), children: [
1230
+ /* @__PURE__ */ jsxs28("label", { className: styles15.label, htmlFor, children: [
1231
+ label,
1232
+ required && /* @__PURE__ */ jsx43("span", { className: styles15.required, "aria-hidden": "true", children: "*" })
1233
+ ] }),
1234
+ /* @__PURE__ */ jsx43("div", { "aria-describedby": describedBy, children }),
1235
+ hint && !error && /* @__PURE__ */ jsx43("p", { id: hintId, className: styles15.hint, children: hint }),
1236
+ error && /* @__PURE__ */ jsx43("p", { id: errorId, className: styles15.error, role: "alert", children: error })
1237
+ ] });
1238
+ }
1239
+
1240
+ // src/components/PageHeader/PageHeader.tsx
1241
+ import styles16 from "./PageHeader.module.css";
1242
+ import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
1243
+ function PageHeader({ title, description, action, className }) {
1244
+ return /* @__PURE__ */ jsxs29("header", { className: [styles16.header, className].filter(Boolean).join(" "), children: [
1245
+ /* @__PURE__ */ jsxs29("div", { className: styles16.text, children: [
1246
+ /* @__PURE__ */ jsx44("h1", { className: styles16.title, children: title }),
1247
+ description && /* @__PURE__ */ jsx44("p", { className: styles16.description, children: description })
1248
+ ] }),
1249
+ action && /* @__PURE__ */ jsx44("div", { className: styles16.action, children: action })
1250
+ ] });
1251
+ }
1252
+
1253
+ // src/components/EmptyState/EmptyState.tsx
1254
+ import styles17 from "./EmptyState.module.css";
1255
+ import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
1256
+ function EmptyState({ icon, heading, description, action, className }) {
1257
+ return /* @__PURE__ */ jsxs30("div", { className: [styles17.root, className].filter(Boolean).join(" "), children: [
1258
+ icon && /* @__PURE__ */ jsx45("span", { className: styles17.icon, children: /* @__PURE__ */ jsx45(Icon, { name: icon, size: "lg", "aria-hidden": true }) }),
1259
+ /* @__PURE__ */ jsx45("h2", { className: styles17.heading, children: heading }),
1260
+ description && /* @__PURE__ */ jsx45("p", { className: styles17.description, children: description }),
1261
+ action
1262
+ ] });
1263
+ }
1264
+
1265
+ // src/components/Spinner/Spinner.tsx
1266
+ import styles18 from "./Spinner.module.css";
1267
+ import { jsx as jsx46 } from "react/jsx-runtime";
1268
+ var sizeClass = {
1269
+ sm: styles18.sm,
1270
+ md: styles18.md,
1271
+ lg: styles18.lg
1272
+ };
1273
+ function Spinner({ size = "md", label = "Loading\u2026", className }) {
1274
+ return /* @__PURE__ */ jsx46(
1275
+ "span",
1276
+ {
1277
+ role: "status",
1278
+ "aria-label": label,
1279
+ className: [styles18.spinner, sizeClass[size], className].filter(Boolean).join(" ")
1280
+ }
1281
+ );
1282
+ }
1283
+
1284
+ // src/components/Avatar/Avatar.tsx
1285
+ import { useState as useState2 } from "react";
1286
+ import styles19 from "./Avatar.module.css";
1287
+ import { jsx as jsx47 } from "react/jsx-runtime";
1288
+ function initials(name) {
1289
+ const parts = name.trim().split(/\s+/);
1290
+ if (parts.length === 1) return (parts[0] ?? "").slice(0, 2).toUpperCase();
1291
+ return ((parts[0]?.[0] ?? "") + (parts[parts.length - 1]?.[0] ?? "")).toUpperCase();
1292
+ }
1293
+ var sizeClass2 = {
1294
+ sm: styles19.sm,
1295
+ md: styles19.md,
1296
+ lg: styles19.lg
1297
+ };
1298
+ function Avatar({ name, src, size = "md", className }) {
1299
+ const [imgFailed, setImgFailed] = useState2(false);
1300
+ const cls = [styles19.avatar, sizeClass2[size], className].filter(Boolean).join(" ");
1301
+ if (src && !imgFailed) {
1302
+ return /* @__PURE__ */ jsx47("span", { className: cls, "aria-label": name, children: /* @__PURE__ */ jsx47("img", { src, alt: name, className: styles19.img, onError: () => setImgFailed(true) }) });
1303
+ }
1304
+ return /* @__PURE__ */ jsx47("span", { className: cls, "aria-label": name, children: initials(name) });
1305
+ }
1306
+
1307
+ // src/components/NavTabs/NavTabs.tsx
1308
+ import styles20 from "./NavTabs.module.css";
1309
+ import { jsx as jsx48 } from "react/jsx-runtime";
1310
+ function NavTabs({ items, className, "aria-label": ariaLabel }) {
1311
+ return /* @__PURE__ */ jsx48(
1312
+ "nav",
1313
+ {
1314
+ className: [styles20.nav, className].filter(Boolean).join(" "),
1315
+ "aria-label": ariaLabel ?? "Page navigation",
1316
+ children: items.map((item) => /* @__PURE__ */ jsx48(
1317
+ "a",
1318
+ {
1319
+ href: item.href,
1320
+ className: [styles20.link, item.active && styles20.active].filter(Boolean).join(" "),
1321
+ "aria-current": item.active ? "page" : void 0,
1322
+ children: item.label
1323
+ },
1324
+ item.href
1325
+ ))
1326
+ }
1327
+ );
1328
+ }
1329
+
1330
+ // src/components/Tooltip/Tooltip.tsx
1331
+ import { useId as useId3 } from "react";
1332
+ import styles21 from "./Tooltip.module.css";
1333
+ import { jsx as jsx49, jsxs as jsxs31 } from "react/jsx-runtime";
1334
+ var sideClass = {
1335
+ top: styles21.top,
1336
+ bottom: styles21.bottom,
1337
+ left: styles21.left,
1338
+ right: styles21.right
1339
+ };
1340
+ function Tooltip({ content, children, side = "top" }) {
1341
+ const tipId = useId3();
1342
+ return /* @__PURE__ */ jsxs31("span", { className: styles21.wrapper, children: [
1343
+ /* @__PURE__ */ jsx49("span", { "aria-describedby": tipId, children }),
1344
+ /* @__PURE__ */ jsx49("span", { id: tipId, role: "tooltip", className: [styles21.tip, sideClass[side]].join(" "), children: content })
1345
+ ] });
1346
+ }
1347
+ export {
1348
+ Avatar,
1349
+ Badge,
1350
+ Button,
1351
+ Card,
1352
+ Dialog,
1353
+ Drawer,
1354
+ EmptyState,
1355
+ FormField,
1356
+ Icon,
1357
+ Input,
1358
+ NavTabs,
1359
+ PageHeader,
1360
+ Popover,
1361
+ SegmentedControl,
1362
+ Select,
1363
+ Spinner,
1364
+ SystemBanner,
1365
+ Tabs,
1366
+ ToastProvider,
1367
+ Toggle,
1368
+ Tooltip,
1369
+ useToast
1370
+ };