@platned/ui 0.1.3 → 0.3.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.
- package/README.md +2 -19
- package/dist/index.cjs +3286 -534
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1522 -104
- package/dist/index.d.ts +1522 -104
- package/dist/index.js +3189 -517
- package/dist/index.js.map +1 -1
- package/dist/sidebar.cjs +73 -147
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.d.cts +20 -1
- package/dist/sidebar.d.ts +20 -1
- package/dist/sidebar.js +99 -158
- package/dist/sidebar.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +8 -5
- package/tailwind-preset.cjs +240 -0
- package/tailwind-preset.js +0 -77
package/dist/index.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import clsx20 from "clsx";
|
|
3
|
-
|
|
4
|
-
// src/components/button.tsx
|
|
1
|
+
// src/components/forms/button.tsx
|
|
5
2
|
import clsx from "clsx";
|
|
6
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
4
|
var variantStyles = {
|
|
8
5
|
primary: clsx(
|
|
9
|
-
"bg-
|
|
10
|
-
"hover:bg-
|
|
11
|
-
"disabled:bg-
|
|
6
|
+
"bg-brand border border-brand text-brand-on-brand",
|
|
7
|
+
"hover:bg-brand-hover",
|
|
8
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
12
9
|
),
|
|
13
10
|
neutral: clsx(
|
|
14
|
-
"bg-
|
|
15
|
-
"hover:bg-
|
|
16
|
-
"disabled:bg-
|
|
11
|
+
"bg-default border border-default text-default",
|
|
12
|
+
"hover:bg-default-hover hover:text-brand",
|
|
13
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
17
14
|
),
|
|
18
15
|
subtle: clsx(
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
16
|
+
// border-transparent holds space so hover border doesn't shift layout
|
|
17
|
+
"bg-transparent border border-transparent text-neutral",
|
|
18
|
+
"hover:border-default hover:text-brand",
|
|
19
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
22
20
|
),
|
|
23
21
|
danger: clsx(
|
|
24
|
-
"bg-
|
|
25
|
-
|
|
26
|
-
"
|
|
22
|
+
"bg-danger border border-danger-secondary text-danger-on-danger",
|
|
23
|
+
// border shifts from danger-secondary → danger-default on hover (Figma spec)
|
|
24
|
+
"hover:bg-danger-hover hover:border-danger",
|
|
25
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
27
26
|
),
|
|
28
27
|
"danger-subtle": clsx(
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
28
|
+
// border-transparent base avoids layout shift when hover border appears
|
|
29
|
+
"bg-transparent border border-transparent text-danger",
|
|
30
|
+
"hover:bg-danger-tertiary-hover hover:border-danger",
|
|
31
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
32
32
|
)
|
|
33
33
|
};
|
|
34
34
|
var sizeStyles = {
|
|
@@ -50,7 +50,7 @@ function Button({
|
|
|
50
50
|
{
|
|
51
51
|
className: clsx(
|
|
52
52
|
"inline-flex items-center justify-center whitespace-nowrap transition-colors",
|
|
53
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
53
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
54
54
|
"disabled:cursor-not-allowed",
|
|
55
55
|
variantStyles[variant],
|
|
56
56
|
sizeStyles[size],
|
|
@@ -66,25 +66,28 @@ function Button({
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
// src/components/icon-button.tsx
|
|
69
|
+
// src/components/forms/icon-button.tsx
|
|
70
70
|
import clsx2 from "clsx";
|
|
71
71
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
72
72
|
var variantStyles2 = {
|
|
73
73
|
primary: clsx2(
|
|
74
|
-
"bg-
|
|
75
|
-
"hover:bg-
|
|
76
|
-
"disabled:bg-
|
|
74
|
+
"bg-brand border border-brand text-brand-on-brand",
|
|
75
|
+
"hover:bg-brand-hover",
|
|
76
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
77
77
|
),
|
|
78
78
|
// Neutral uses secondary background (light gray) for visual weight without a text label
|
|
79
79
|
neutral: clsx2(
|
|
80
|
-
"bg-
|
|
81
|
-
|
|
82
|
-
"
|
|
80
|
+
"bg-default-secondary border border-default text-default",
|
|
81
|
+
// icon turns brand blue on hover (Figma spec)
|
|
82
|
+
"hover:bg-default-secondary-hover hover:text-brand",
|
|
83
|
+
"disabled:bg-disabled disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
83
84
|
),
|
|
84
85
|
subtle: clsx2(
|
|
85
|
-
"bg-transparent text-
|
|
86
|
-
|
|
87
|
-
"
|
|
86
|
+
"bg-transparent text-neutral",
|
|
87
|
+
// hover uses background-default-default-hover (#f5f5f5), icon turns brand blue (Figma spec)
|
|
88
|
+
"hover:bg-default-hover hover:text-brand",
|
|
89
|
+
// disabled needs explicit border since there is no base border
|
|
90
|
+
"disabled:bg-disabled disabled:border disabled:border-disabled disabled:text-disabled-on-disabled"
|
|
88
91
|
)
|
|
89
92
|
};
|
|
90
93
|
var sizeStyles2 = {
|
|
@@ -95,7 +98,7 @@ var sizeStyles2 = {
|
|
|
95
98
|
function IconButton({
|
|
96
99
|
variant = "primary",
|
|
97
100
|
size = "md",
|
|
98
|
-
|
|
101
|
+
children,
|
|
99
102
|
className,
|
|
100
103
|
...props
|
|
101
104
|
}) {
|
|
@@ -104,44 +107,44 @@ function IconButton({
|
|
|
104
107
|
{
|
|
105
108
|
className: clsx2(
|
|
106
109
|
"inline-flex shrink-0 items-center justify-center transition-colors",
|
|
107
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
110
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
108
111
|
"disabled:cursor-not-allowed",
|
|
109
112
|
variantStyles2[variant],
|
|
110
113
|
sizeStyles2[size],
|
|
111
114
|
className
|
|
112
115
|
),
|
|
113
116
|
...props,
|
|
114
|
-
children
|
|
117
|
+
children
|
|
115
118
|
}
|
|
116
119
|
);
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
// src/components/button-group.tsx
|
|
122
|
+
// src/components/forms/button-group.tsx
|
|
120
123
|
import clsx3 from "clsx";
|
|
121
124
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
122
125
|
var containerStyles = {
|
|
123
|
-
primary: "bg-
|
|
124
|
-
neutral: "bg-
|
|
125
|
-
filter: "bg-
|
|
126
|
+
primary: "bg-neutral-tertiary p-1 rounded-2xl",
|
|
127
|
+
neutral: "bg-neutral-tertiary p-1 rounded-2xl",
|
|
128
|
+
filter: "bg-default border border-default p-1 rounded-xl"
|
|
126
129
|
};
|
|
127
130
|
var selectedStyles = {
|
|
128
131
|
primary: clsx3(
|
|
129
|
-
"bg-
|
|
130
|
-
"hover:bg-
|
|
132
|
+
"bg-brand border border-brand text-brand-on-brand",
|
|
133
|
+
"hover:bg-brand-hover"
|
|
131
134
|
),
|
|
132
135
|
neutral: clsx3(
|
|
133
|
-
"bg-
|
|
134
|
-
"hover:bg-
|
|
136
|
+
"bg-default border border-default text-default",
|
|
137
|
+
"hover:bg-default-hover"
|
|
135
138
|
),
|
|
136
139
|
filter: clsx3(
|
|
137
|
-
"bg-
|
|
138
|
-
"hover:bg-
|
|
140
|
+
"bg-brand text-brand-on-brand",
|
|
141
|
+
"hover:bg-brand-hover"
|
|
139
142
|
)
|
|
140
143
|
};
|
|
141
144
|
var unselectedStyles = {
|
|
142
|
-
primary: clsx3("bg-transparent text-
|
|
143
|
-
neutral: clsx3("bg-transparent text-
|
|
144
|
-
filter: clsx3("text-
|
|
145
|
+
primary: clsx3("bg-transparent text-neutral", "hover:bg-neutral-tertiary-hover"),
|
|
146
|
+
neutral: clsx3("bg-transparent text-neutral", "hover:bg-neutral-tertiary-hover"),
|
|
147
|
+
filter: clsx3("text-default-secondary", "hover:text-default")
|
|
145
148
|
};
|
|
146
149
|
var itemSizeStyles = {
|
|
147
150
|
lg: "h-12 px-3 gap-1 rounded-2xl text-body font-semibold [&_svg]:size-5",
|
|
@@ -192,8 +195,8 @@ function ButtonGroup({
|
|
|
192
195
|
onClick: () => onChange(item.value),
|
|
193
196
|
className: clsx3(
|
|
194
197
|
"inline-flex items-center justify-center whitespace-nowrap transition-colors",
|
|
195
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
196
|
-
"disabled:cursor-not-allowed disabled:text-
|
|
198
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
199
|
+
"disabled:cursor-not-allowed disabled:text-disabled",
|
|
197
200
|
(isJustify || isStack) && "w-full",
|
|
198
201
|
itemSizeStyles[size],
|
|
199
202
|
isSelected ? selectedStyles[variant] : unselectedStyles[variant]
|
|
@@ -213,7 +216,7 @@ function ButtonGroup({
|
|
|
213
216
|
);
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
// src/components/avatar.tsx
|
|
219
|
+
// src/components/avatar/avatar.tsx
|
|
217
220
|
import clsx4 from "clsx";
|
|
218
221
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
219
222
|
var sizeStyles3 = {
|
|
@@ -226,16 +229,16 @@ var initialTextStyles = {
|
|
|
226
229
|
md: "text-body-xs font-semibold",
|
|
227
230
|
sm: "text-body-tiny font-semibold"
|
|
228
231
|
};
|
|
229
|
-
|
|
230
|
-
circle
|
|
231
|
-
|
|
232
|
-
}
|
|
232
|
+
function getShapeClass(shape, size) {
|
|
233
|
+
if (shape === "circle") return "rounded-full";
|
|
234
|
+
return size === "sm" ? "rounded" : "rounded-lg";
|
|
235
|
+
}
|
|
233
236
|
function Avatar(props) {
|
|
234
237
|
const { size = "lg", shape = "circle", className } = props;
|
|
235
238
|
const base = clsx4(
|
|
236
239
|
"shrink-0 overflow-hidden",
|
|
237
240
|
sizeStyles3[size],
|
|
238
|
-
|
|
241
|
+
getShapeClass(shape, size),
|
|
239
242
|
className
|
|
240
243
|
);
|
|
241
244
|
if (props.type === "image") {
|
|
@@ -259,7 +262,7 @@ function Avatar(props) {
|
|
|
259
262
|
"span",
|
|
260
263
|
{
|
|
261
264
|
className: clsx4(
|
|
262
|
-
"select-none leading-none text-
|
|
265
|
+
"select-none leading-none text-brand-on-brand",
|
|
263
266
|
initialTextStyles[size]
|
|
264
267
|
),
|
|
265
268
|
children: props.initial.charAt(0).toUpperCase()
|
|
@@ -269,7 +272,7 @@ function Avatar(props) {
|
|
|
269
272
|
);
|
|
270
273
|
}
|
|
271
274
|
|
|
272
|
-
// src/components/avatar-group.tsx
|
|
275
|
+
// src/components/avatar/avatar-group.tsx
|
|
273
276
|
import clsx5 from "clsx";
|
|
274
277
|
import { jsxs as jsxs3 } from "react/jsx-runtime";
|
|
275
278
|
function AvatarGroup({
|
|
@@ -294,7 +297,7 @@ function AvatarGroup({
|
|
|
294
297
|
className: clsx5(
|
|
295
298
|
"flex items-center justify-center",
|
|
296
299
|
"min-w-6 h-6 px-1 rounded-lg",
|
|
297
|
-
"bg-
|
|
300
|
+
"bg-default-secondary text-default-secondary text-body-sm",
|
|
298
301
|
spacing === "overlap" && "drop-shadow-sm"
|
|
299
302
|
),
|
|
300
303
|
children: [
|
|
@@ -308,39 +311,20 @@ function AvatarGroup({
|
|
|
308
311
|
);
|
|
309
312
|
}
|
|
310
313
|
|
|
311
|
-
// src/components/
|
|
314
|
+
// src/components/avatar/avatar-block.tsx
|
|
312
315
|
import clsx6 from "clsx";
|
|
313
316
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
314
|
-
function
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
})
|
|
322
|
-
return /* @__PURE__ */ jsxs4(
|
|
323
|
-
"span",
|
|
324
|
-
{
|
|
325
|
-
className: clsx6(
|
|
326
|
-
"relative flex h-11 w-full items-center gap-3 rounded-xl px-3.5 py-2.5 transition-colors",
|
|
327
|
-
collapsed && "justify-center",
|
|
328
|
-
isActive ? "bg-background-brand text-text-brand-on-brand" : [
|
|
329
|
-
"border border-border-default bg-background-default text-text-default-secondary",
|
|
330
|
-
"hover:bg-background-brand-tertiary-hover hover:border-border-brand-tertiary hover:text-text-brand"
|
|
331
|
-
],
|
|
332
|
-
className
|
|
333
|
-
),
|
|
334
|
-
children: [
|
|
335
|
-
icon !== void 0 && /* @__PURE__ */ jsx5("span", { className: "shrink-0 [&_svg]:size-4", children: icon }),
|
|
336
|
-
!collapsed && /* @__PURE__ */ jsx5("span", { className: "flex-1 min-w-0 truncate text-body-sm font-regular leading-snug", children: label }),
|
|
337
|
-
indicator && /* @__PURE__ */ jsx5("span", { className: "absolute -right-px -top-px size-2 rounded-full bg-background-danger" })
|
|
338
|
-
]
|
|
339
|
-
}
|
|
340
|
-
);
|
|
317
|
+
function AvatarBlock({ children, title, description, className }) {
|
|
318
|
+
return /* @__PURE__ */ jsxs4("div", { className: clsx6("flex items-start gap-3", className), children: [
|
|
319
|
+
/* @__PURE__ */ jsx5("div", { className: "shrink-0", children }),
|
|
320
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
321
|
+
/* @__PURE__ */ jsx5("span", { className: "text-body font-semibold text-default-secondary", children: title }),
|
|
322
|
+
description && /* @__PURE__ */ jsx5("span", { className: "text-body text-default-tertiary", children: description })
|
|
323
|
+
] })
|
|
324
|
+
] });
|
|
341
325
|
}
|
|
342
326
|
|
|
343
|
-
// src/components/input.tsx
|
|
327
|
+
// src/components/forms/input.tsx
|
|
344
328
|
import { forwardRef } from "react";
|
|
345
329
|
import clsx7 from "clsx";
|
|
346
330
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
@@ -358,17 +342,17 @@ var labelText = {
|
|
|
358
342
|
sm: "text-body-tiny"
|
|
359
343
|
};
|
|
360
344
|
var inputBase = {
|
|
361
|
-
lg: "h-12 px-
|
|
362
|
-
md: "h-9 px-
|
|
363
|
-
sm: "h-6 px-
|
|
345
|
+
lg: "h-12 px-5 py-3.5 text-body",
|
|
346
|
+
md: "h-9 px-4 py-2.5 text-body-sm",
|
|
347
|
+
sm: "h-6 px-3 py-[5px] text-body-tiny"
|
|
364
348
|
};
|
|
365
349
|
var leadingPad = {
|
|
366
|
-
lg: "pl-
|
|
350
|
+
lg: "pl-12",
|
|
367
351
|
md: "pl-8",
|
|
368
352
|
sm: "pl-6"
|
|
369
353
|
};
|
|
370
354
|
var trailingPad = {
|
|
371
|
-
lg: "pr-
|
|
355
|
+
lg: "pr-12",
|
|
372
356
|
md: "pr-8",
|
|
373
357
|
sm: "pr-6"
|
|
374
358
|
};
|
|
@@ -377,7 +361,7 @@ var iconWrap = {
|
|
|
377
361
|
md: { left: "left-3", right: "right-3", size: "size-4" },
|
|
378
362
|
sm: { left: "left-2", right: "right-2", size: "size-3" }
|
|
379
363
|
};
|
|
380
|
-
var Input = forwardRef(function Input2({ label, description, error, hint, size = "md", leadingIcon, trailingIcon, className, disabled, id, ...props }, ref) {
|
|
364
|
+
var Input = forwardRef(function Input2({ label, description, error, hint, size = "md", leadingIcon, trailingIcon, trailingAction, className, disabled, id, ...props }, ref) {
|
|
381
365
|
const hasError = !!error;
|
|
382
366
|
const iw = iconWrap[size];
|
|
383
367
|
return /* @__PURE__ */ jsxs5("div", { className: clsx7("flex flex-col", wrapGap[size], className), children: [
|
|
@@ -385,11 +369,11 @@ var Input = forwardRef(function Input2({ label, description, error, hint, size =
|
|
|
385
369
|
"label",
|
|
386
370
|
{
|
|
387
371
|
htmlFor: id,
|
|
388
|
-
className: clsx7(labelText[size], disabled ? "text-
|
|
372
|
+
className: clsx7(labelText[size], disabled ? "text-disabled" : "text-default"),
|
|
389
373
|
children: label
|
|
390
374
|
}
|
|
391
375
|
),
|
|
392
|
-
description && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], disabled ? "text-
|
|
376
|
+
description && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
|
|
393
377
|
/* @__PURE__ */ jsxs5("div", { className: "relative flex items-center", children: [
|
|
394
378
|
leadingIcon && /* @__PURE__ */ jsx6("span", { className: clsx7("pointer-events-none absolute", iw.left, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: leadingIcon }),
|
|
395
379
|
/* @__PURE__ */ jsx6(
|
|
@@ -400,24 +384,25 @@ var Input = forwardRef(function Input2({ label, description, error, hint, size =
|
|
|
400
384
|
disabled,
|
|
401
385
|
className: clsx7(
|
|
402
386
|
"w-full rounded-lg border outline-none transition-colors",
|
|
403
|
-
"bg-
|
|
404
|
-
"placeholder:text-
|
|
387
|
+
"bg-default text-default",
|
|
388
|
+
"placeholder:text-default-tertiary",
|
|
405
389
|
inputBase[size],
|
|
406
390
|
leadingIcon && leadingPad[size],
|
|
407
|
-
trailingIcon && trailingPad[size],
|
|
408
|
-
disabled ? "cursor-not-allowed bg-
|
|
391
|
+
(trailingIcon || trailingAction) && trailingPad[size],
|
|
392
|
+
disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
|
|
409
393
|
),
|
|
410
394
|
...props
|
|
411
395
|
}
|
|
412
396
|
),
|
|
413
|
-
trailingIcon && /* @__PURE__ */ jsx6("span", { className: clsx7("pointer-events-none absolute", iw.right, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: trailingIcon })
|
|
397
|
+
trailingIcon && !trailingAction && /* @__PURE__ */ jsx6("span", { className: clsx7("pointer-events-none absolute", iw.right, iw.size, "flex items-center justify-center text-icon-default-secondary"), children: trailingIcon }),
|
|
398
|
+
trailingAction && /* @__PURE__ */ jsx6("span", { className: clsx7("absolute", iw.right, "flex items-center justify-center text-icon-default-secondary"), children: trailingAction })
|
|
414
399
|
] }),
|
|
415
|
-
hasError && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-
|
|
416
|
-
!hasError && hint && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-
|
|
400
|
+
hasError && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-danger"), children: error }),
|
|
401
|
+
!hasError && hint && /* @__PURE__ */ jsx6("p", { className: clsx7(labelText[size], "text-default"), children: hint })
|
|
417
402
|
] });
|
|
418
403
|
});
|
|
419
404
|
|
|
420
|
-
// src/components/textarea.tsx
|
|
405
|
+
// src/components/forms/textarea.tsx
|
|
421
406
|
import { forwardRef as forwardRef2 } from "react";
|
|
422
407
|
import clsx8 from "clsx";
|
|
423
408
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
@@ -443,11 +428,11 @@ var Textarea = forwardRef2(function Textarea2({ label, description, error, hint,
|
|
|
443
428
|
"label",
|
|
444
429
|
{
|
|
445
430
|
htmlFor: id,
|
|
446
|
-
className: clsx8(labelText2[size], disabled ? "text-
|
|
431
|
+
className: clsx8(labelText2[size], disabled ? "text-disabled" : "text-default"),
|
|
447
432
|
children: label
|
|
448
433
|
}
|
|
449
434
|
),
|
|
450
|
-
description && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], disabled ? "text-
|
|
435
|
+
description && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
|
|
451
436
|
/* @__PURE__ */ jsx7(
|
|
452
437
|
"textarea",
|
|
453
438
|
{
|
|
@@ -456,20 +441,20 @@ var Textarea = forwardRef2(function Textarea2({ label, description, error, hint,
|
|
|
456
441
|
disabled,
|
|
457
442
|
className: clsx8(
|
|
458
443
|
"w-full rounded-lg border outline-none transition-colors resize-y",
|
|
459
|
-
"bg-
|
|
460
|
-
"placeholder:text-
|
|
444
|
+
"bg-default text-default",
|
|
445
|
+
"placeholder:text-default-tertiary",
|
|
461
446
|
textareaBase[size],
|
|
462
|
-
disabled ? "cursor-not-allowed bg-
|
|
447
|
+
disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled placeholder:text-disabled resize-none" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
|
|
463
448
|
),
|
|
464
449
|
...props
|
|
465
450
|
}
|
|
466
451
|
),
|
|
467
|
-
hasError && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-
|
|
468
|
-
!hasError && hint && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-
|
|
452
|
+
hasError && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-danger"), children: error }),
|
|
453
|
+
!hasError && hint && /* @__PURE__ */ jsx7("p", { className: clsx8(labelText2[size], "text-default-secondary"), children: hint })
|
|
469
454
|
] });
|
|
470
455
|
});
|
|
471
456
|
|
|
472
|
-
// src/components/select.tsx
|
|
457
|
+
// src/components/forms/select.tsx
|
|
473
458
|
import { forwardRef as forwardRef3 } from "react";
|
|
474
459
|
import clsx9 from "clsx";
|
|
475
460
|
import { LuChevronDown } from "react-icons/lu";
|
|
@@ -505,11 +490,11 @@ var Select = forwardRef3(function Select2({ label, description, error, hint, siz
|
|
|
505
490
|
"label",
|
|
506
491
|
{
|
|
507
492
|
htmlFor: id,
|
|
508
|
-
className: clsx9(labelText3[size], disabled ? "text-
|
|
493
|
+
className: clsx9(labelText3[size], disabled ? "text-disabled" : "text-default"),
|
|
509
494
|
children: label
|
|
510
495
|
}
|
|
511
496
|
),
|
|
512
|
-
description && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], disabled ? "text-
|
|
497
|
+
description && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
|
|
513
498
|
/* @__PURE__ */ jsxs7("div", { className: "relative flex items-center", children: [
|
|
514
499
|
/* @__PURE__ */ jsxs7(
|
|
515
500
|
"select",
|
|
@@ -519,9 +504,9 @@ var Select = forwardRef3(function Select2({ label, description, error, hint, siz
|
|
|
519
504
|
disabled,
|
|
520
505
|
className: clsx9(
|
|
521
506
|
"w-full appearance-none rounded-lg border outline-none transition-colors pt-0.5",
|
|
522
|
-
"bg-
|
|
507
|
+
"bg-default text-default",
|
|
523
508
|
selectBase[size],
|
|
524
|
-
disabled ? "cursor-not-allowed bg-
|
|
509
|
+
disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
|
|
525
510
|
),
|
|
526
511
|
...props,
|
|
527
512
|
children: [
|
|
@@ -544,49 +529,129 @@ var Select = forwardRef3(function Select2({ label, description, error, hint, siz
|
|
|
544
529
|
}
|
|
545
530
|
)
|
|
546
531
|
] }),
|
|
547
|
-
hasError && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-
|
|
548
|
-
!hasError && hint && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-
|
|
532
|
+
hasError && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-danger"), children: error }),
|
|
533
|
+
!hasError && hint && /* @__PURE__ */ jsx8("p", { className: clsx9(labelText3[size], "text-default-secondary"), children: hint })
|
|
549
534
|
] });
|
|
550
535
|
});
|
|
551
536
|
|
|
552
|
-
// src/components/
|
|
537
|
+
// src/components/forms/date-picker.tsx
|
|
538
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
553
539
|
import clsx10 from "clsx";
|
|
554
|
-
import {
|
|
540
|
+
import { LuCalendar } from "react-icons/lu";
|
|
555
541
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
542
|
+
var wrapGap4 = {
|
|
543
|
+
lg: "gap-2",
|
|
544
|
+
md: "gap-1",
|
|
545
|
+
sm: "gap-0.5"
|
|
546
|
+
};
|
|
547
|
+
var labelText4 = {
|
|
548
|
+
lg: "text-body",
|
|
549
|
+
md: "text-body-sm",
|
|
550
|
+
sm: "text-body-tiny"
|
|
551
|
+
};
|
|
552
|
+
var inputBase2 = {
|
|
553
|
+
lg: "h-12 px-5 py-3.5 pr-12 text-body",
|
|
554
|
+
md: "h-9 px-4 py-2.5 pr-8 text-body-sm",
|
|
555
|
+
sm: "h-6 px-3 py-[5px] pr-6 text-body-tiny"
|
|
556
|
+
};
|
|
557
|
+
var iconWrap2 = {
|
|
558
|
+
lg: { right: "right-4", size: "size-5" },
|
|
559
|
+
md: { right: "right-3", size: "size-4" },
|
|
560
|
+
sm: { right: "right-2", size: "size-3" }
|
|
561
|
+
};
|
|
562
|
+
var DatePicker = forwardRef4(function DatePicker2({ label, description, error, hint, size = "md", className, disabled, id, ...props }, ref) {
|
|
563
|
+
const hasError = !!error;
|
|
564
|
+
const iw = iconWrap2[size];
|
|
565
|
+
return /* @__PURE__ */ jsxs8("div", { className: clsx10("flex flex-col", wrapGap4[size], className), children: [
|
|
566
|
+
label && /* @__PURE__ */ jsx9(
|
|
567
|
+
"label",
|
|
568
|
+
{
|
|
569
|
+
htmlFor: id,
|
|
570
|
+
className: clsx10(labelText4[size], disabled ? "text-disabled" : "text-default"),
|
|
571
|
+
children: label
|
|
572
|
+
}
|
|
573
|
+
),
|
|
574
|
+
description && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], disabled ? "text-disabled" : "text-default-secondary"), children: description }),
|
|
575
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative flex items-center", children: [
|
|
576
|
+
/* @__PURE__ */ jsx9(
|
|
577
|
+
"input",
|
|
578
|
+
{
|
|
579
|
+
ref,
|
|
580
|
+
id,
|
|
581
|
+
type: "date",
|
|
582
|
+
disabled,
|
|
583
|
+
className: clsx10(
|
|
584
|
+
"w-full rounded-lg border outline-none transition-colors",
|
|
585
|
+
"bg-default text-default",
|
|
586
|
+
"[&::-webkit-calendar-picker-indicator]:opacity-0",
|
|
587
|
+
"[&::-webkit-calendar-picker-indicator]:absolute",
|
|
588
|
+
"[&::-webkit-calendar-picker-indicator]:right-0",
|
|
589
|
+
"[&::-webkit-calendar-picker-indicator]:h-full",
|
|
590
|
+
"[&::-webkit-calendar-picker-indicator]:w-10",
|
|
591
|
+
"[&::-webkit-calendar-picker-indicator]:cursor-pointer",
|
|
592
|
+
inputBase2[size],
|
|
593
|
+
disabled ? "cursor-not-allowed bg-disabled border-disabled text-disabled" : hasError ? "border-danger-secondary focus:border-danger-secondary focus:ring-1 focus:ring-danger-secondary" : "border-default focus:border-brand-secondary focus:ring-1 focus:ring-brand-secondary"
|
|
594
|
+
),
|
|
595
|
+
...props
|
|
596
|
+
}
|
|
597
|
+
),
|
|
598
|
+
/* @__PURE__ */ jsx9(
|
|
599
|
+
"span",
|
|
600
|
+
{
|
|
601
|
+
className: clsx10(
|
|
602
|
+
"pointer-events-none absolute",
|
|
603
|
+
iw.right,
|
|
604
|
+
iw.size,
|
|
605
|
+
"flex items-center justify-center",
|
|
606
|
+
disabled ? "text-icon-disabled" : "text-icon-default-secondary"
|
|
607
|
+
),
|
|
608
|
+
children: /* @__PURE__ */ jsx9(LuCalendar, { className: "size-full" })
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
] }),
|
|
612
|
+
hasError && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], "text-danger"), children: error }),
|
|
613
|
+
!hasError && hint && /* @__PURE__ */ jsx9("p", { className: clsx10(labelText4[size], "text-default"), children: hint })
|
|
614
|
+
] });
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// src/components/forms/stepper.tsx
|
|
618
|
+
import clsx11 from "clsx";
|
|
619
|
+
import { LuCheck, LuChevronRight } from "react-icons/lu";
|
|
620
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
556
621
|
function StepIndicator({ status }) {
|
|
557
622
|
if (status === "complete") {
|
|
558
|
-
return /* @__PURE__ */
|
|
623
|
+
return /* @__PURE__ */ jsx10("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-brand text-white", children: /* @__PURE__ */ jsx10(LuCheck, { size: 11, "aria-hidden": true }) });
|
|
559
624
|
}
|
|
560
625
|
if (status === "active") {
|
|
561
|
-
return /* @__PURE__ */
|
|
626
|
+
return /* @__PURE__ */ jsx10("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full border-2 border-brand-emphasis", children: /* @__PURE__ */ jsx10("span", { className: "size-2.5 rounded-full bg-brand" }) });
|
|
562
627
|
}
|
|
563
|
-
return /* @__PURE__ */
|
|
628
|
+
return /* @__PURE__ */ jsx10("span", { className: "size-5 shrink-0 rounded-full border-2 border-disabled", "aria-hidden": "true" });
|
|
564
629
|
}
|
|
565
630
|
function ChevronSeparator() {
|
|
566
|
-
return /* @__PURE__ */
|
|
631
|
+
return /* @__PURE__ */ jsx10(LuChevronRight, { className: "mx-1 size-4 shrink-0 text-default-tertiary", "aria-hidden": true });
|
|
567
632
|
}
|
|
568
633
|
var labelClass = {
|
|
569
|
-
complete: "text-
|
|
570
|
-
active: "text-
|
|
571
|
-
upcoming: "text-
|
|
634
|
+
complete: "text-brand font-semibold",
|
|
635
|
+
active: "text-brand font-semibold",
|
|
636
|
+
upcoming: "text-disabled font-regular"
|
|
572
637
|
};
|
|
573
638
|
function Stepper({ steps, className }) {
|
|
574
|
-
return /* @__PURE__ */
|
|
639
|
+
return /* @__PURE__ */ jsx10(
|
|
575
640
|
"ol",
|
|
576
641
|
{
|
|
577
|
-
className:
|
|
642
|
+
className: clsx11("flex items-center overflow-x-auto", className),
|
|
578
643
|
"aria-label": "Progress",
|
|
579
|
-
children: steps.map((step, i) => /* @__PURE__ */
|
|
644
|
+
children: steps.map((step, i) => /* @__PURE__ */ jsxs9(
|
|
580
645
|
"li",
|
|
581
646
|
{
|
|
582
647
|
className: "flex items-center",
|
|
583
648
|
"aria-current": step.status === "active" ? "step" : void 0,
|
|
584
649
|
children: [
|
|
585
|
-
/* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
587
|
-
/* @__PURE__ */
|
|
650
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-1.5", children: [
|
|
651
|
+
/* @__PURE__ */ jsx10(StepIndicator, { status: step.status }),
|
|
652
|
+
/* @__PURE__ */ jsx10("span", { className: clsx11("text-body-xs whitespace-nowrap", labelClass[step.status]), children: step.label })
|
|
588
653
|
] }),
|
|
589
|
-
i < steps.length - 1 && /* @__PURE__ */
|
|
654
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx10(ChevronSeparator, {})
|
|
590
655
|
]
|
|
591
656
|
},
|
|
592
657
|
i
|
|
@@ -595,9 +660,10 @@ function Stepper({ steps, className }) {
|
|
|
595
660
|
);
|
|
596
661
|
}
|
|
597
662
|
|
|
598
|
-
// src/components/multiselect-card.tsx
|
|
599
|
-
import
|
|
600
|
-
import {
|
|
663
|
+
// src/components/forms/multiselect-card.tsx
|
|
664
|
+
import clsx12 from "clsx";
|
|
665
|
+
import { LuCheck as LuCheck2 } from "react-icons/lu";
|
|
666
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
601
667
|
function MultiSelectCard({
|
|
602
668
|
icon,
|
|
603
669
|
title,
|
|
@@ -606,299 +672,245 @@ function MultiSelectCard({
|
|
|
606
672
|
onToggle,
|
|
607
673
|
className
|
|
608
674
|
}) {
|
|
609
|
-
return /* @__PURE__ */
|
|
675
|
+
return /* @__PURE__ */ jsxs10(
|
|
610
676
|
"button",
|
|
611
677
|
{
|
|
612
678
|
type: "button",
|
|
613
679
|
role: "checkbox",
|
|
614
680
|
"aria-checked": selected,
|
|
615
681
|
onClick: onToggle,
|
|
616
|
-
className:
|
|
682
|
+
className: clsx12(
|
|
617
683
|
"relative w-full rounded-2xl border-2 p-4 text-left transition-all",
|
|
618
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
619
|
-
selected ? "border-
|
|
684
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
685
|
+
selected ? "border-brand bg-brand-tertiary" : "border-default bg-default hover:border-default-secondary",
|
|
620
686
|
className
|
|
621
687
|
),
|
|
622
688
|
children: [
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
689
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-start justify-between gap-2", children: [
|
|
690
|
+
/* @__PURE__ */ jsx11(
|
|
625
691
|
"span",
|
|
626
692
|
{
|
|
627
|
-
className:
|
|
693
|
+
className: clsx12(
|
|
628
694
|
"flex size-10 shrink-0 items-center justify-center rounded-xl",
|
|
629
|
-
selected ? "bg-
|
|
695
|
+
selected ? "bg-brand" : "bg-brand-tertiary"
|
|
630
696
|
),
|
|
631
|
-
children: /* @__PURE__ */
|
|
697
|
+
children: /* @__PURE__ */ jsx11("span", { className: clsx12("size-5", selected ? "text-icon-brand-on-brand" : "text-icon-brand"), children: icon })
|
|
632
698
|
}
|
|
633
699
|
),
|
|
634
|
-
selected ? /* @__PURE__ */
|
|
635
|
-
"path",
|
|
636
|
-
{
|
|
637
|
-
d: "M1 4L3.9 7L10 1",
|
|
638
|
-
stroke: "white",
|
|
639
|
-
strokeWidth: "1.5",
|
|
640
|
-
strokeLinecap: "round",
|
|
641
|
-
strokeLinejoin: "round"
|
|
642
|
-
}
|
|
643
|
-
) }) }) : /* @__PURE__ */ jsx10(
|
|
700
|
+
selected ? /* @__PURE__ */ jsx11("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-brand text-icon-brand-on-brand", children: /* @__PURE__ */ jsx11(LuCheck2, { className: "size-3", strokeWidth: 2.5, "aria-hidden": true }) }) : /* @__PURE__ */ jsx11(
|
|
644
701
|
"span",
|
|
645
702
|
{
|
|
646
|
-
className: "size-5 shrink-0 rounded-full border-2 border-
|
|
703
|
+
className: "size-5 shrink-0 rounded-full border-2 border-default",
|
|
647
704
|
"aria-hidden": "true"
|
|
648
705
|
}
|
|
649
706
|
)
|
|
650
707
|
] }),
|
|
651
|
-
/* @__PURE__ */
|
|
652
|
-
/* @__PURE__ */
|
|
708
|
+
/* @__PURE__ */ jsxs10("div", { className: "mt-3", children: [
|
|
709
|
+
/* @__PURE__ */ jsx11(
|
|
653
710
|
"p",
|
|
654
711
|
{
|
|
655
|
-
className:
|
|
712
|
+
className: clsx12(
|
|
656
713
|
"text-body-sm font-semibold",
|
|
657
|
-
selected ? "text-
|
|
714
|
+
selected ? "text-brand" : "text-default"
|
|
658
715
|
),
|
|
659
716
|
children: title
|
|
660
717
|
}
|
|
661
718
|
),
|
|
662
|
-
description && /* @__PURE__ */
|
|
719
|
+
description && /* @__PURE__ */ jsx11("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: description })
|
|
663
720
|
] })
|
|
664
721
|
]
|
|
665
722
|
}
|
|
666
723
|
);
|
|
667
724
|
}
|
|
668
725
|
|
|
669
|
-
// src/components/
|
|
670
|
-
import clsx12 from "clsx";
|
|
671
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
672
|
-
function DataTable({
|
|
673
|
-
columns,
|
|
674
|
-
rows,
|
|
675
|
-
getRowKey,
|
|
676
|
-
className,
|
|
677
|
-
onRowClick
|
|
678
|
-
}) {
|
|
679
|
-
return /* @__PURE__ */ jsxs10(
|
|
680
|
-
"div",
|
|
681
|
-
{
|
|
682
|
-
className: clsx12(
|
|
683
|
-
"overflow-hidden rounded-xl border border-border-default bg-background-default",
|
|
684
|
-
className
|
|
685
|
-
),
|
|
686
|
-
children: [
|
|
687
|
-
/* @__PURE__ */ jsx11("div", { className: "flex items-center bg-background-default-secondary px-4 py-3", children: columns.map((col) => /* @__PURE__ */ jsx11("div", { className: clsx12("overflow-hidden", col.grow ? "flex-1 min-w-0" : "shrink-0"), style: col.grow ? { minWidth: col.width } : { width: col.width }, children: /* @__PURE__ */ jsx11("span", { className: "text-body-xs font-medium text-text-default-secondary whitespace-nowrap", children: col.header }) }, col.key)) }),
|
|
688
|
-
/* @__PURE__ */ jsx11("div", { children: rows.map((row, i) => /* @__PURE__ */ jsx11(
|
|
689
|
-
"div",
|
|
690
|
-
{
|
|
691
|
-
className: clsx12(
|
|
692
|
-
"flex items-center px-4 py-[14px] transition-colors hover:bg-background-default-secondary/50",
|
|
693
|
-
i > 0 && "border-t border-[#ececec]",
|
|
694
|
-
onRowClick && "cursor-pointer"
|
|
695
|
-
),
|
|
696
|
-
onClick: onRowClick ? () => onRowClick(row) : void 0,
|
|
697
|
-
children: columns.map((col) => /* @__PURE__ */ jsx11("div", { className: clsx12("overflow-hidden", col.grow ? "flex-1 min-w-0" : "shrink-0"), style: col.grow ? { minWidth: col.width } : { width: col.width }, children: col.render(row) }, col.key))
|
|
698
|
-
},
|
|
699
|
-
getRowKey(row, i)
|
|
700
|
-
)) })
|
|
701
|
-
]
|
|
702
|
-
}
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
function TableCellLeadText({
|
|
706
|
-
primary,
|
|
707
|
-
secondary
|
|
708
|
-
}) {
|
|
709
|
-
return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-0.5", children: [
|
|
710
|
-
/* @__PURE__ */ jsx11("span", { className: "text-body-sm font-medium text-text-default leading-snug", children: primary }),
|
|
711
|
-
secondary && /* @__PURE__ */ jsx11("span", { className: "text-body-xs font-normal text-text-default-secondary leading-tight", children: secondary })
|
|
712
|
-
] });
|
|
713
|
-
}
|
|
714
|
-
function TableCellText({
|
|
715
|
-
children,
|
|
716
|
-
muted = true
|
|
717
|
-
}) {
|
|
718
|
-
return /* @__PURE__ */ jsx11(
|
|
719
|
-
"span",
|
|
720
|
-
{
|
|
721
|
-
className: clsx12(
|
|
722
|
-
"text-body-xs font-normal leading-snug whitespace-nowrap",
|
|
723
|
-
muted ? "text-text-default-secondary" : "text-text-default"
|
|
724
|
-
),
|
|
725
|
-
children
|
|
726
|
-
}
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
function TableCellBadge({ label }) {
|
|
730
|
-
return /* @__PURE__ */ jsx11("span", { className: "inline-flex items-center rounded-md border border-border-default bg-background-default-secondary px-2 py-0.5 text-body-tiny font-medium text-text-default-secondary whitespace-nowrap", children: label });
|
|
731
|
-
}
|
|
732
|
-
function TableCellStatusPill({
|
|
733
|
-
label,
|
|
734
|
-
dotColor,
|
|
735
|
-
backgroundColor,
|
|
736
|
-
textColor
|
|
737
|
-
}) {
|
|
738
|
-
return /* @__PURE__ */ jsxs10(
|
|
739
|
-
"span",
|
|
740
|
-
{
|
|
741
|
-
className: "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-body-xs font-medium leading-tight whitespace-nowrap",
|
|
742
|
-
style: { backgroundColor, color: textColor },
|
|
743
|
-
children: [
|
|
744
|
-
/* @__PURE__ */ jsx11("span", { className: "size-1.5 shrink-0 rounded-full", style: { backgroundColor: dotColor } }),
|
|
745
|
-
label
|
|
746
|
-
]
|
|
747
|
-
}
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
|
-
function TableCellProgress({
|
|
751
|
-
percent,
|
|
752
|
-
barColor
|
|
753
|
-
}) {
|
|
754
|
-
const color = barColor ?? "#0c2d58";
|
|
755
|
-
const clamped = Math.min(100, Math.max(0, percent));
|
|
756
|
-
return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-1", children: [
|
|
757
|
-
/* @__PURE__ */ jsx11("div", { className: "h-1.5 w-16 overflow-hidden rounded-full bg-background-default-secondary", children: /* @__PURE__ */ jsx11(
|
|
758
|
-
"div",
|
|
759
|
-
{
|
|
760
|
-
className: "h-full rounded-full transition-all",
|
|
761
|
-
style: { width: `${clamped}%`, backgroundColor: color }
|
|
762
|
-
}
|
|
763
|
-
) }),
|
|
764
|
-
/* @__PURE__ */ jsxs10("span", { className: "text-body-tiny text-text-default-secondary leading-none", children: [
|
|
765
|
-
percent,
|
|
766
|
-
"%"
|
|
767
|
-
] })
|
|
768
|
-
] });
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// src/components/stat-tile.tsx
|
|
726
|
+
// src/components/forms/toggle.tsx
|
|
772
727
|
import clsx13 from "clsx";
|
|
773
728
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
774
|
-
|
|
729
|
+
var SIZE = {
|
|
730
|
+
sm: { track: "h-5 w-9", knob: "size-4", translate: "translate-x-4" },
|
|
731
|
+
md: { track: "h-6 w-11", knob: "size-5", translate: "translate-x-5" }
|
|
732
|
+
};
|
|
733
|
+
function Toggle({
|
|
734
|
+
checked,
|
|
735
|
+
onChange,
|
|
736
|
+
label,
|
|
737
|
+
size = "md",
|
|
738
|
+
disabled = false,
|
|
739
|
+
id,
|
|
740
|
+
"aria-label": ariaLabel,
|
|
741
|
+
"aria-labelledby": ariaLabelledBy,
|
|
742
|
+
className
|
|
743
|
+
}) {
|
|
744
|
+
const s = SIZE[size];
|
|
775
745
|
return /* @__PURE__ */ jsxs11(
|
|
776
|
-
"div",
|
|
777
|
-
{
|
|
778
|
-
className: clsx13(
|
|
779
|
-
"flex flex-col gap-2 rounded-xl border border-border-default bg-background-default p-4",
|
|
780
|
-
className
|
|
781
|
-
),
|
|
782
|
-
children: [
|
|
783
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5", children: [
|
|
784
|
-
dotColor && /* @__PURE__ */ jsx12("span", { className: "size-2 shrink-0 rounded-full", style: { backgroundColor: dotColor } }),
|
|
785
|
-
/* @__PURE__ */ jsx12("span", { className: "text-body-xs font-medium text-text-default-secondary whitespace-nowrap", children: label })
|
|
786
|
-
] }),
|
|
787
|
-
/* @__PURE__ */ jsx12("span", { className: "text-heading font-semibold text-text-default leading-none", children: value })
|
|
788
|
-
]
|
|
789
|
-
}
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// src/components/toggle.tsx
|
|
794
|
-
import clsx14 from "clsx";
|
|
795
|
-
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
796
|
-
function Toggle({ checked, onChange, label, disabled = false }) {
|
|
797
|
-
return /* @__PURE__ */ jsxs12(
|
|
798
746
|
"button",
|
|
799
747
|
{
|
|
800
748
|
type: "button",
|
|
801
749
|
role: "switch",
|
|
750
|
+
id,
|
|
802
751
|
"aria-checked": checked,
|
|
752
|
+
"aria-label": label ? void 0 : ariaLabel,
|
|
753
|
+
"aria-labelledby": ariaLabelledBy,
|
|
803
754
|
disabled,
|
|
804
755
|
onClick: () => onChange(!checked),
|
|
805
|
-
className:
|
|
806
|
-
"flex items-center gap-2",
|
|
807
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
808
|
-
disabled && "cursor-not-allowed opacity-50"
|
|
756
|
+
className: clsx13(
|
|
757
|
+
"group flex items-center gap-2",
|
|
758
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
759
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
760
|
+
className
|
|
809
761
|
),
|
|
810
762
|
children: [
|
|
811
|
-
/* @__PURE__ */
|
|
763
|
+
/* @__PURE__ */ jsx12(
|
|
812
764
|
"span",
|
|
813
765
|
{
|
|
814
|
-
className:
|
|
815
|
-
"relative inline-flex
|
|
816
|
-
|
|
766
|
+
className: clsx13(
|
|
767
|
+
"relative inline-flex shrink-0 rounded-full transition-colors",
|
|
768
|
+
s.track,
|
|
769
|
+
// The unchecked track is borderless per the spec. A border here would also
|
|
770
|
+
// shift the knob's rendered inset by 1px between states, since the knob is
|
|
771
|
+
// positioned against the padding box.
|
|
772
|
+
disabled ? "bg-disabled" : checked ? "bg-brand group-hover:bg-brand-hover" : "bg-default-secondary group-hover:bg-default-secondary-hover"
|
|
817
773
|
),
|
|
818
|
-
children: /* @__PURE__ */
|
|
774
|
+
children: /* @__PURE__ */ jsx12(
|
|
819
775
|
"span",
|
|
820
776
|
{
|
|
821
|
-
className:
|
|
822
|
-
"absolute left-0.5 top-0.5
|
|
823
|
-
|
|
777
|
+
className: clsx13(
|
|
778
|
+
"absolute left-0.5 top-0.5 rounded-full bg-default shadow-sm transition-transform",
|
|
779
|
+
s.knob,
|
|
780
|
+
checked ? s.translate : "translate-x-0"
|
|
824
781
|
)
|
|
825
782
|
}
|
|
826
783
|
)
|
|
827
784
|
}
|
|
828
785
|
),
|
|
829
|
-
label && /* @__PURE__ */
|
|
786
|
+
label && /* @__PURE__ */ jsx12("span", { className: "text-body-xs text-default", children: label })
|
|
830
787
|
]
|
|
831
788
|
}
|
|
832
789
|
);
|
|
833
790
|
}
|
|
834
791
|
|
|
835
|
-
// src/components/file-drop-zone.tsx
|
|
792
|
+
// src/components/forms/file-drop-zone.tsx
|
|
836
793
|
import { useRef, useState } from "react";
|
|
837
|
-
import
|
|
794
|
+
import clsx14 from "clsx";
|
|
838
795
|
import { LuUpload } from "react-icons/lu";
|
|
839
|
-
import { Fragment, jsx as
|
|
840
|
-
|
|
796
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
797
|
+
var DEFAULT_ACCEPT = ".pdf,.jpg,.jpeg,.png";
|
|
798
|
+
var DEFAULT_MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
799
|
+
function formatSize(bytes) {
|
|
800
|
+
const mb = bytes / (1024 * 1024);
|
|
801
|
+
return `${Number.isInteger(mb) ? mb : mb.toFixed(1)} MB`;
|
|
802
|
+
}
|
|
803
|
+
function matchesAccept(file, accept) {
|
|
804
|
+
const extensions = accept.split(",").map((part) => part.trim().toLowerCase()).filter((part) => part.startsWith("."));
|
|
805
|
+
if (extensions.length === 0) {
|
|
806
|
+
return true;
|
|
807
|
+
}
|
|
808
|
+
return extensions.some((extension) => file.name.toLowerCase().endsWith(extension));
|
|
809
|
+
}
|
|
810
|
+
function FileDropZone({
|
|
811
|
+
className,
|
|
812
|
+
description = "Drag & drop or browse \xB7 PDF, JPG, PNG \xB7 up to 10 MB",
|
|
813
|
+
accept = DEFAULT_ACCEPT,
|
|
814
|
+
maxSizeBytes = DEFAULT_MAX_SIZE_BYTES,
|
|
815
|
+
onFileSelected,
|
|
816
|
+
disabled = false
|
|
817
|
+
}) {
|
|
841
818
|
const inputRef = useRef(null);
|
|
842
819
|
const [isDragging, setIsDragging] = useState(false);
|
|
843
|
-
|
|
844
|
-
|
|
820
|
+
const [error, setError] = useState(null);
|
|
821
|
+
function handleFiles(files) {
|
|
822
|
+
const file = files?.[0];
|
|
823
|
+
if (!file) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (!matchesAccept(file, accept)) {
|
|
827
|
+
setError(`Unsupported file type. Allowed: ${accept}.`);
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (file.size > maxSizeBytes) {
|
|
831
|
+
setError(`That file is ${formatSize(file.size)}. The limit is ${formatSize(maxSizeBytes)}.`);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
setError(null);
|
|
835
|
+
onFileSelected?.(file);
|
|
836
|
+
}
|
|
837
|
+
return /* @__PURE__ */ jsxs12(Fragment, { children: [
|
|
838
|
+
/* @__PURE__ */ jsx13(
|
|
845
839
|
"input",
|
|
846
840
|
{
|
|
847
841
|
ref: inputRef,
|
|
848
842
|
type: "file",
|
|
849
|
-
accept
|
|
843
|
+
accept,
|
|
850
844
|
className: "sr-only",
|
|
851
|
-
tabIndex: -1
|
|
845
|
+
tabIndex: -1,
|
|
846
|
+
disabled,
|
|
847
|
+
onChange: (e) => {
|
|
848
|
+
handleFiles(e.target.files);
|
|
849
|
+
e.target.value = "";
|
|
850
|
+
}
|
|
852
851
|
}
|
|
853
852
|
),
|
|
854
|
-
/* @__PURE__ */
|
|
853
|
+
/* @__PURE__ */ jsxs12(
|
|
855
854
|
"div",
|
|
856
855
|
{
|
|
857
856
|
role: "button",
|
|
858
|
-
tabIndex: 0,
|
|
859
|
-
|
|
860
|
-
|
|
857
|
+
tabIndex: disabled ? -1 : 0,
|
|
858
|
+
"aria-disabled": disabled,
|
|
859
|
+
onClick: () => {
|
|
860
|
+
if (!disabled) inputRef.current?.click();
|
|
861
|
+
},
|
|
862
|
+
onKeyDown: (e) => {
|
|
863
|
+
if (!disabled && (e.key === "Enter" || e.key === " ")) {
|
|
864
|
+
e.preventDefault();
|
|
865
|
+
inputRef.current?.click();
|
|
866
|
+
}
|
|
867
|
+
},
|
|
861
868
|
onDragOver: (e) => {
|
|
862
869
|
e.preventDefault();
|
|
863
|
-
setIsDragging(true);
|
|
870
|
+
if (!disabled) setIsDragging(true);
|
|
864
871
|
},
|
|
865
872
|
onDragEnter: (e) => {
|
|
866
873
|
e.preventDefault();
|
|
867
|
-
setIsDragging(true);
|
|
874
|
+
if (!disabled) setIsDragging(true);
|
|
868
875
|
},
|
|
869
876
|
onDragLeave: () => setIsDragging(false),
|
|
870
877
|
onDrop: (e) => {
|
|
871
878
|
e.preventDefault();
|
|
872
879
|
setIsDragging(false);
|
|
880
|
+
if (!disabled) handleFiles(e.dataTransfer.files);
|
|
873
881
|
},
|
|
874
|
-
className:
|
|
875
|
-
"flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4
|
|
876
|
-
|
|
882
|
+
className: clsx14(
|
|
883
|
+
"flex flex-col items-center justify-center gap-1 rounded-lg border-2 border-dashed py-4 px-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-1",
|
|
884
|
+
disabled ? "cursor-not-allowed border-disabled bg-disabled" : clsx14(
|
|
885
|
+
"cursor-pointer",
|
|
886
|
+
isDragging ? "border-brand bg-brand-tertiary" : "border-default bg-default-secondary hover:border-brand hover:bg-brand-tertiary"
|
|
887
|
+
),
|
|
877
888
|
className
|
|
878
889
|
),
|
|
879
890
|
children: [
|
|
880
|
-
/* @__PURE__ */
|
|
881
|
-
/* @__PURE__ */
|
|
882
|
-
/* @__PURE__ */
|
|
891
|
+
/* @__PURE__ */ jsx13("span", { className: disabled ? "text-disabled" : isDragging ? "text-brand" : "text-default-secondary", children: /* @__PURE__ */ jsx13(LuUpload, { className: "size-5" }) }),
|
|
892
|
+
/* @__PURE__ */ jsx13("span", { className: clsx14("text-body-sm font-medium", disabled ? "text-disabled" : "text-default"), children: "Upload file" }),
|
|
893
|
+
/* @__PURE__ */ jsx13("span", { className: "text-body-xs text-default-secondary text-center", children: description })
|
|
883
894
|
]
|
|
884
895
|
}
|
|
885
|
-
)
|
|
896
|
+
),
|
|
897
|
+
error && /* @__PURE__ */ jsx13("span", { role: "alert", className: "text-body-xs text-danger", children: error })
|
|
886
898
|
] });
|
|
887
899
|
}
|
|
888
900
|
|
|
889
|
-
// src/components/form-card.tsx
|
|
890
|
-
import
|
|
901
|
+
// src/components/forms/form-card.tsx
|
|
902
|
+
import clsx15 from "clsx";
|
|
891
903
|
import { LuArrowLeft, LuArrowRight } from "react-icons/lu";
|
|
892
|
-
import { jsx as
|
|
904
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
893
905
|
function FormCard({
|
|
894
906
|
children,
|
|
895
907
|
className
|
|
896
908
|
}) {
|
|
897
|
-
return /* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsx14(
|
|
898
910
|
"div",
|
|
899
911
|
{
|
|
900
|
-
className:
|
|
901
|
-
"overflow-hidden rounded-xl border border-
|
|
912
|
+
className: clsx15(
|
|
913
|
+
"overflow-hidden rounded-xl border border-default bg-default",
|
|
902
914
|
className
|
|
903
915
|
),
|
|
904
916
|
children
|
|
@@ -906,9 +918,9 @@ function FormCard({
|
|
|
906
918
|
);
|
|
907
919
|
}
|
|
908
920
|
function FormCardHeader({ title, subtitle }) {
|
|
909
|
-
return /* @__PURE__ */
|
|
910
|
-
/* @__PURE__ */
|
|
911
|
-
subtitle && /* @__PURE__ */
|
|
921
|
+
return /* @__PURE__ */ jsxs13("div", { className: "border-b border-default px-7 py-6", children: [
|
|
922
|
+
/* @__PURE__ */ jsx14("h2", { className: "text-heading-sm font-semibold text-default leading-snug", children: title }),
|
|
923
|
+
subtitle && /* @__PURE__ */ jsx14("p", { className: "mt-1 text-body-xs text-default-secondary", children: subtitle })
|
|
912
924
|
] });
|
|
913
925
|
}
|
|
914
926
|
function FormCardFooter({
|
|
@@ -916,131 +928,104 @@ function FormCardFooter({
|
|
|
916
928
|
onBack,
|
|
917
929
|
onContinue,
|
|
918
930
|
continueLabel = "Continue",
|
|
919
|
-
backDisabled = false
|
|
931
|
+
backDisabled = false,
|
|
932
|
+
continueDisabled = false
|
|
920
933
|
}) {
|
|
921
|
-
return /* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
!backDisabled && /* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
934
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-t border-default px-7 py-5", children: [
|
|
935
|
+
/* @__PURE__ */ jsx14(Button, { variant: "neutral", size: "md", onClick: onSaveDraft, disabled: !onSaveDraft, children: "Save as draft" }),
|
|
936
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
937
|
+
!backDisabled && /* @__PURE__ */ jsx14(Button, { variant: "neutral", size: "md", leadingIcon: /* @__PURE__ */ jsx14(LuArrowLeft, { size: 16 }), onClick: onBack, children: "Back" }),
|
|
938
|
+
/* @__PURE__ */ jsx14(Button, { variant: "primary", size: "md", trailingIcon: /* @__PURE__ */ jsx14(LuArrowRight, { size: 16 }), onClick: onContinue, disabled: continueDisabled, children: continueLabel })
|
|
926
939
|
] })
|
|
927
940
|
] });
|
|
928
941
|
}
|
|
929
942
|
|
|
930
|
-
// src/components/
|
|
931
|
-
import
|
|
932
|
-
import {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
943
|
+
// src/components/status/badge.tsx
|
|
944
|
+
import clsx16 from "clsx";
|
|
945
|
+
import { LuX } from "react-icons/lu";
|
|
946
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
947
|
+
var defaultClasses = {
|
|
948
|
+
gray: "bg-badge-gray text-badge-gray",
|
|
949
|
+
red: "bg-badge-red text-badge-red",
|
|
950
|
+
yellow: "bg-badge-yellow text-badge-yellow",
|
|
951
|
+
lime: "bg-badge-lime text-badge-lime",
|
|
952
|
+
green: "bg-badge-green text-badge-green",
|
|
953
|
+
teal: "bg-badge-teal text-badge-teal",
|
|
954
|
+
blue: "bg-badge-blue text-badge-blue",
|
|
955
|
+
pink: "bg-badge-pink text-badge-pink",
|
|
956
|
+
slate: "bg-badge-slate text-badge-slate"
|
|
939
957
|
};
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
958
|
+
var subtleClasses = {
|
|
959
|
+
gray: "border border-badge-gray text-default-secondary",
|
|
960
|
+
red: "border border-badge-red text-default-secondary",
|
|
961
|
+
yellow: "border border-badge-yellow text-default-secondary",
|
|
962
|
+
lime: "border border-badge-lime text-default-secondary",
|
|
963
|
+
green: "border border-badge-green text-default-secondary",
|
|
964
|
+
teal: "border border-badge-teal text-default-secondary",
|
|
965
|
+
blue: "border border-badge-blue text-default-secondary",
|
|
966
|
+
pink: "border border-badge-pink text-default-secondary",
|
|
967
|
+
slate: "border border-badge-slate text-default-secondary"
|
|
968
|
+
};
|
|
969
|
+
function Badge({
|
|
970
|
+
label,
|
|
971
|
+
color = "gray",
|
|
972
|
+
size = "sm",
|
|
973
|
+
variant = "default",
|
|
974
|
+
indicator = false,
|
|
975
|
+
onClose,
|
|
976
|
+
className
|
|
951
977
|
}) {
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
cfg.style
|
|
966
|
-
),
|
|
967
|
-
children: cfg.label
|
|
968
|
-
}
|
|
969
|
-
)
|
|
970
|
-
] }),
|
|
971
|
-
/* @__PURE__ */ jsx16("p", { className: "text-body-xs text-text-default-secondary", children: description }),
|
|
972
|
-
hasFile ? /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 rounded-lg border border-border-default bg-background-default px-3 py-2.5", children: [
|
|
973
|
-
/* @__PURE__ */ jsx16(FileTypeBadge, { type: fileType }),
|
|
974
|
-
/* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
975
|
-
/* @__PURE__ */ jsx16("span", { className: "truncate text-body-sm font-medium text-text-default", children: fileName }),
|
|
976
|
-
fileSize && /* @__PURE__ */ jsx16("span", { className: "text-body-xs text-text-default-secondary", children: fileSize })
|
|
977
|
-
] }),
|
|
978
|
-
/* @__PURE__ */ jsxs15("div", { className: "flex shrink-0 items-center gap-4", children: [
|
|
979
|
-
/* @__PURE__ */ jsx16(
|
|
980
|
-
"button",
|
|
978
|
+
const isDefault = variant === "default";
|
|
979
|
+
return /* @__PURE__ */ jsxs14(
|
|
980
|
+
"span",
|
|
981
|
+
{
|
|
982
|
+
className: clsx16(
|
|
983
|
+
"inline-flex items-center rounded-full px-2 py-0.5",
|
|
984
|
+
size === "sm" ? "gap-1" : "gap-1.5",
|
|
985
|
+
isDefault ? defaultClasses[color] : subtleClasses[color],
|
|
986
|
+
className
|
|
987
|
+
),
|
|
988
|
+
children: [
|
|
989
|
+
indicator && /* @__PURE__ */ jsx15(
|
|
990
|
+
"span",
|
|
981
991
|
{
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
992
|
+
className: clsx16(
|
|
993
|
+
"shrink-0 rounded-full bg-current",
|
|
994
|
+
size === "sm" ? "h-1.5 w-1.5" : "h-2 w-2"
|
|
995
|
+
)
|
|
996
|
+
}
|
|
997
|
+
),
|
|
998
|
+
/* @__PURE__ */ jsx15(
|
|
999
|
+
"span",
|
|
1000
|
+
{
|
|
1001
|
+
className: clsx16(
|
|
1002
|
+
"whitespace-nowrap",
|
|
1003
|
+
size === "sm" ? clsx16("text-body-tiny", isDefault && "font-semibold") : "text-body-xs"
|
|
1004
|
+
),
|
|
1005
|
+
children: label
|
|
985
1006
|
}
|
|
986
1007
|
),
|
|
987
|
-
/* @__PURE__ */
|
|
1008
|
+
onClose && /* @__PURE__ */ jsx15(
|
|
988
1009
|
"button",
|
|
989
1010
|
{
|
|
990
1011
|
type: "button",
|
|
991
|
-
|
|
992
|
-
|
|
1012
|
+
onClick: onClose,
|
|
1013
|
+
className: clsx16(
|
|
1014
|
+
"inline-flex shrink-0 items-center justify-center rounded-full opacity-60 transition-opacity hover:opacity-100",
|
|
1015
|
+
size === "sm" ? "h-3 w-3" : "h-4 w-4"
|
|
1016
|
+
),
|
|
1017
|
+
"aria-label": "Remove",
|
|
1018
|
+
children: /* @__PURE__ */ jsx15(LuX, { className: "h-full w-full", strokeWidth: 2.5, "aria-hidden": true })
|
|
993
1019
|
}
|
|
994
1020
|
)
|
|
995
|
-
]
|
|
996
|
-
] }) : /* @__PURE__ */ jsx16(FileDropZone, {})
|
|
997
|
-
] });
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// src/components/modal.tsx
|
|
1001
|
-
import clsx18 from "clsx";
|
|
1002
|
-
import { LuX } from "react-icons/lu";
|
|
1003
|
-
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1004
|
-
function Modal({ isOpen, onClose, title, subtitle, children, footer, maxWidth = "max-w-[540px]" }) {
|
|
1005
|
-
if (!isOpen) return null;
|
|
1006
|
-
return /* @__PURE__ */ jsx17(
|
|
1007
|
-
"div",
|
|
1008
|
-
{
|
|
1009
|
-
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
|
|
1010
|
-
onClick: (e) => {
|
|
1011
|
-
if (e.target === e.currentTarget) onClose();
|
|
1012
|
-
},
|
|
1013
|
-
children: /* @__PURE__ */ jsxs16("div", { className: clsx18("w-full mx-4 rounded-2xl bg-white shadow-xl", maxWidth), children: [
|
|
1014
|
-
/* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between px-6 py-5", children: [
|
|
1015
|
-
/* @__PURE__ */ jsxs16("div", { children: [
|
|
1016
|
-
/* @__PURE__ */ jsx17("h2", { className: "text-heading-sm font-semibold text-text-default", children: title }),
|
|
1017
|
-
subtitle && /* @__PURE__ */ jsx17("p", { className: "mt-0.5 text-body-xs text-text-default-secondary", children: subtitle })
|
|
1018
|
-
] }),
|
|
1019
|
-
/* @__PURE__ */ jsx17(
|
|
1020
|
-
IconButton,
|
|
1021
|
-
{
|
|
1022
|
-
variant: "subtle",
|
|
1023
|
-
size: "sm",
|
|
1024
|
-
"aria-label": "Close dialog",
|
|
1025
|
-
icon: /* @__PURE__ */ jsx17(LuX, { size: 16 }),
|
|
1026
|
-
onClick: onClose
|
|
1027
|
-
}
|
|
1028
|
-
)
|
|
1029
|
-
] }),
|
|
1030
|
-
/* @__PURE__ */ jsx17("hr", { className: "border-border-default" }),
|
|
1031
|
-
/* @__PURE__ */ jsx17("div", { className: "px-6 py-5", children }),
|
|
1032
|
-
footer && /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
1033
|
-
/* @__PURE__ */ jsx17("hr", { className: "border-border-default" }),
|
|
1034
|
-
/* @__PURE__ */ jsx17("div", { className: "flex items-center justify-end gap-2 px-6 py-4", children: footer })
|
|
1035
|
-
] })
|
|
1036
|
-
] })
|
|
1021
|
+
]
|
|
1037
1022
|
}
|
|
1038
1023
|
);
|
|
1039
1024
|
}
|
|
1040
1025
|
|
|
1041
|
-
// src/components/role-badge.tsx
|
|
1042
|
-
import
|
|
1043
|
-
import { jsx as
|
|
1026
|
+
// src/components/status/role-badge.tsx
|
|
1027
|
+
import clsx17 from "clsx";
|
|
1028
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1044
1029
|
var ROLE_COLORS = {
|
|
1045
1030
|
"Super Admin": { bg: "#e9eff7", text: "#0c2d58" },
|
|
1046
1031
|
"Admin": { bg: "#e9eff7", text: "#0c2d58" },
|
|
@@ -1054,12 +1039,19 @@ var ROLE_COLORS = {
|
|
|
1054
1039
|
"User": { bg: "#e9eff7", text: "#0c2d58" }
|
|
1055
1040
|
};
|
|
1056
1041
|
var FALLBACK = { bg: "#f5f5f5", text: "#757575" };
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1042
|
+
var HEX6 = /^#[0-9a-fA-F]{6}$/;
|
|
1043
|
+
function resolveColors(role, color) {
|
|
1044
|
+
if (color && HEX6.test(color)) {
|
|
1045
|
+
return { bg: `${color}1F`, text: color };
|
|
1046
|
+
}
|
|
1047
|
+
return ROLE_COLORS[role] ?? FALLBACK;
|
|
1048
|
+
}
|
|
1049
|
+
function RoleBadge({ role, size = "sm", color }) {
|
|
1050
|
+
const colors = resolveColors(role, color);
|
|
1051
|
+
return /* @__PURE__ */ jsx16(
|
|
1060
1052
|
"span",
|
|
1061
1053
|
{
|
|
1062
|
-
className:
|
|
1054
|
+
className: clsx17(
|
|
1063
1055
|
"inline-flex items-center rounded-full font-medium whitespace-nowrap",
|
|
1064
1056
|
size === "sm" ? "px-2 py-0.5 text-body-tiny" : "px-3 py-1 text-body-xs"
|
|
1065
1057
|
),
|
|
@@ -1069,10 +1061,10 @@ function RoleBadge({ role, size = "sm" }) {
|
|
|
1069
1061
|
);
|
|
1070
1062
|
}
|
|
1071
1063
|
|
|
1072
|
-
// src/components/role-combo-box.tsx
|
|
1064
|
+
// src/components/forms/role-combo-box.tsx
|
|
1073
1065
|
import { useEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
1074
1066
|
import { LuChevronDown as LuChevronDown2 } from "react-icons/lu";
|
|
1075
|
-
import { Fragment as
|
|
1067
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1076
1068
|
var ROLE_COMBO_OPTIONS = [
|
|
1077
1069
|
{ role: "Reviewer", description: "Reviews onboarding requests" },
|
|
1078
1070
|
{ role: "Admin", description: "Full org control" },
|
|
@@ -1111,21 +1103,32 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
|
|
|
1111
1103
|
const otherOptions = options.filter(
|
|
1112
1104
|
(o) => o.role !== value && o.role.toLowerCase().includes(query.toLowerCase())
|
|
1113
1105
|
);
|
|
1114
|
-
return /* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1106
|
+
return /* @__PURE__ */ jsxs15("div", { className: "relative", ref: containerRef, children: [
|
|
1107
|
+
/* @__PURE__ */ jsxs15(
|
|
1116
1108
|
"div",
|
|
1117
1109
|
{
|
|
1118
1110
|
role: "combobox",
|
|
1119
1111
|
"aria-expanded": open,
|
|
1120
1112
|
"aria-haspopup": "listbox",
|
|
1121
1113
|
onClick: openDropdown,
|
|
1122
|
-
|
|
1114
|
+
tabIndex: 0,
|
|
1115
|
+
onKeyDown: (e) => {
|
|
1116
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1117
|
+
e.preventDefault();
|
|
1118
|
+
openDropdown();
|
|
1119
|
+
}
|
|
1120
|
+
if (e.key === "Escape") {
|
|
1121
|
+
setOpen(false);
|
|
1122
|
+
setQuery("");
|
|
1123
|
+
}
|
|
1124
|
+
},
|
|
1125
|
+
className: `flex h-11 cursor-pointer items-center gap-2 rounded-lg border-[1.5px] pl-2.5 pr-3 transition-colors ${open ? "border-blue-500" : "border-default hover:border-brand-tertiary"}`,
|
|
1123
1126
|
children: [
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
value === "User" && !open && /* @__PURE__ */
|
|
1127
|
-
open && /* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1127
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-1 min-w-0 items-center gap-1.5 overflow-hidden", children: [
|
|
1128
|
+
/* @__PURE__ */ jsx17(RoleBadge, { role: value, size: "sm" }),
|
|
1129
|
+
value === "User" && !open && /* @__PURE__ */ jsx17("span", { className: "rounded border border-default bg-default-secondary px-1.5 py-0.5 text-body-tiny font-medium text-default-secondary", children: "DEFAULT" }),
|
|
1130
|
+
open && /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
1131
|
+
/* @__PURE__ */ jsx17(
|
|
1129
1132
|
"input",
|
|
1130
1133
|
{
|
|
1131
1134
|
ref: inputRef,
|
|
@@ -1133,24 +1136,24 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
|
|
|
1133
1136
|
value: query,
|
|
1134
1137
|
onChange: (e) => setQuery(e.target.value),
|
|
1135
1138
|
onClick: (e) => e.stopPropagation(),
|
|
1136
|
-
className: "min-w-0 flex-1 bg-transparent text-body-xs text-
|
|
1139
|
+
className: "min-w-0 flex-1 bg-transparent text-body-xs text-default outline-none",
|
|
1137
1140
|
"aria-label": "Search roles"
|
|
1138
1141
|
}
|
|
1139
1142
|
),
|
|
1140
|
-
/* @__PURE__ */
|
|
1143
|
+
/* @__PURE__ */ jsx17("span", { className: "mx-0.5 h-[18px] w-px shrink-0 bg-divider", "aria-hidden": true })
|
|
1141
1144
|
] })
|
|
1142
1145
|
] }),
|
|
1143
|
-
/* @__PURE__ */
|
|
1146
|
+
/* @__PURE__ */ jsx17("span", { className: "shrink-0 text-default-secondary", children: /* @__PURE__ */ jsx17(LuChevronDown2, { size: 14 }) })
|
|
1144
1147
|
]
|
|
1145
1148
|
}
|
|
1146
1149
|
),
|
|
1147
|
-
open && /* @__PURE__ */
|
|
1150
|
+
open && /* @__PURE__ */ jsxs15(
|
|
1148
1151
|
"div",
|
|
1149
1152
|
{
|
|
1150
1153
|
role: "listbox",
|
|
1151
|
-
className: "absolute left-0 right-0 top-full z-20 mt-1 flex max-h-64 flex-col gap-0.5 overflow-y-auto rounded-xl border border-
|
|
1154
|
+
className: "absolute left-0 right-0 top-full z-20 mt-1 flex max-h-64 flex-col gap-0.5 overflow-y-auto rounded-xl border border-default bg-white p-1.5 shadow-lg",
|
|
1152
1155
|
children: [
|
|
1153
|
-
selectedEntry && /* @__PURE__ */
|
|
1156
|
+
selectedEntry && /* @__PURE__ */ jsxs15(
|
|
1154
1157
|
"div",
|
|
1155
1158
|
{
|
|
1156
1159
|
role: "option",
|
|
@@ -1158,31 +1161,38 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
|
|
|
1158
1161
|
className: "flex cursor-pointer items-center gap-2.5 rounded-md bg-blue-50 px-2.5 py-2",
|
|
1159
1162
|
onClick: () => select(selectedEntry.role),
|
|
1160
1163
|
children: [
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
+
/* @__PURE__ */ jsx17(RoleBadge, { role: selectedEntry.role, size: "sm" }),
|
|
1165
|
+
/* @__PURE__ */ jsx17("span", { className: "flex-1 text-body-xs text-default-secondary", children: selectedEntry.description }),
|
|
1166
|
+
/* @__PURE__ */ jsx17("span", { className: "shrink-0 text-sm font-bold text-blue-600", children: "\u2713" })
|
|
1164
1167
|
]
|
|
1165
1168
|
}
|
|
1166
1169
|
),
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
otherOptions.length > 0 && /* @__PURE__ */
|
|
1169
|
-
/* @__PURE__ */
|
|
1170
|
-
otherOptions.map((opt) => /* @__PURE__ */
|
|
1170
|
+
/* @__PURE__ */ jsx17("div", { className: "h-px bg-divider" }),
|
|
1171
|
+
otherOptions.length > 0 && /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
1172
|
+
/* @__PURE__ */ jsx17("div", { className: "px-2.5 pb-1 pt-1.5", children: /* @__PURE__ */ jsx17("span", { className: "text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: "Other roles" }) }),
|
|
1173
|
+
otherOptions.map((opt) => /* @__PURE__ */ jsxs15(
|
|
1171
1174
|
"div",
|
|
1172
1175
|
{
|
|
1173
1176
|
role: "option",
|
|
1174
1177
|
"aria-selected": false,
|
|
1175
|
-
className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2.5 py-2 hover:bg-
|
|
1178
|
+
className: "flex cursor-pointer items-center gap-2.5 rounded-md px-2.5 py-2 hover:bg-default-secondary",
|
|
1176
1179
|
onClick: () => select(opt.role),
|
|
1180
|
+
tabIndex: 0,
|
|
1181
|
+
onKeyDown: (e) => {
|
|
1182
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1183
|
+
e.preventDefault();
|
|
1184
|
+
select(opt.role);
|
|
1185
|
+
}
|
|
1186
|
+
},
|
|
1177
1187
|
children: [
|
|
1178
|
-
/* @__PURE__ */
|
|
1179
|
-
/* @__PURE__ */
|
|
1188
|
+
/* @__PURE__ */ jsx17(RoleBadge, { role: opt.role, size: "sm" }),
|
|
1189
|
+
/* @__PURE__ */ jsx17("span", { className: "text-body-xs text-default-secondary", children: opt.description })
|
|
1180
1190
|
]
|
|
1181
1191
|
},
|
|
1182
1192
|
opt.role
|
|
1183
1193
|
))
|
|
1184
1194
|
] }),
|
|
1185
|
-
otherOptions.length === 0 && query && /* @__PURE__ */
|
|
1195
|
+
otherOptions.length === 0 && query && /* @__PURE__ */ jsxs15("p", { className: "px-2.5 py-2 text-body-xs text-default-secondary", children: [
|
|
1186
1196
|
'No roles match "',
|
|
1187
1197
|
query,
|
|
1188
1198
|
'"'
|
|
@@ -1193,92 +1203,2754 @@ function RoleComboBox({ value, onChange, options = ROLE_COMBO_OPTIONS }) {
|
|
|
1193
1203
|
] });
|
|
1194
1204
|
}
|
|
1195
1205
|
|
|
1196
|
-
// src/
|
|
1197
|
-
import
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1206
|
+
// src/components/status/status-badge.tsx
|
|
1207
|
+
import clsx18 from "clsx";
|
|
1208
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1209
|
+
var TONE_STYLES = {
|
|
1210
|
+
neutral: "bg-status-neutral text-status-neutral",
|
|
1211
|
+
info: "bg-status-info text-status-info",
|
|
1212
|
+
warning: "bg-status-warning text-status-warning",
|
|
1213
|
+
caution: "bg-status-caution text-status-caution",
|
|
1214
|
+
accent: "bg-status-accent text-status-accent",
|
|
1215
|
+
positive: "bg-status-positive text-status-positive",
|
|
1216
|
+
danger: "bg-status-danger text-status-danger"
|
|
1217
|
+
};
|
|
1218
|
+
var DOT_STYLES = {
|
|
1219
|
+
neutral: "bg-status-dot-neutral",
|
|
1220
|
+
info: "bg-status-dot-info",
|
|
1221
|
+
warning: "bg-status-dot-warning",
|
|
1222
|
+
caution: "bg-status-dot-caution",
|
|
1223
|
+
accent: "bg-status-dot-accent",
|
|
1224
|
+
positive: "bg-status-dot-positive",
|
|
1225
|
+
danger: "bg-status-dot-danger"
|
|
1226
|
+
};
|
|
1227
|
+
var SIZE_STYLES = {
|
|
1228
|
+
sm: "px-2 py-0.5 text-body-tiny",
|
|
1229
|
+
md: "px-2.5 py-1 text-body-xs"
|
|
1230
|
+
};
|
|
1231
|
+
function StatusBadge({
|
|
1232
|
+
label,
|
|
1233
|
+
tone = "neutral",
|
|
1234
|
+
size = "md",
|
|
1235
|
+
dot = true,
|
|
1236
|
+
icon,
|
|
1237
|
+
className
|
|
1238
|
+
}) {
|
|
1239
|
+
return /* @__PURE__ */ jsxs16(
|
|
1240
|
+
"span",
|
|
1241
|
+
{
|
|
1242
|
+
className: clsx18(
|
|
1243
|
+
"inline-flex items-center gap-1.5 rounded-full font-medium leading-tight whitespace-nowrap",
|
|
1244
|
+
SIZE_STYLES[size],
|
|
1245
|
+
TONE_STYLES[tone],
|
|
1246
|
+
className
|
|
1247
|
+
),
|
|
1248
|
+
children: [
|
|
1249
|
+
icon ? /* @__PURE__ */ jsx18("span", { className: "shrink-0", children: icon }) : dot && /* @__PURE__ */ jsx18("span", { className: clsx18("size-1.5 shrink-0 rounded-full", DOT_STYLES[tone]) }),
|
|
1250
|
+
label
|
|
1251
|
+
]
|
|
1252
|
+
}
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
// src/components/status/status-dot.tsx
|
|
1257
|
+
import clsx19 from "clsx";
|
|
1258
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1259
|
+
var dotTones = {
|
|
1260
|
+
brand: "bg-brand",
|
|
1261
|
+
positive: "bg-positive",
|
|
1262
|
+
warning: "bg-warning",
|
|
1263
|
+
danger: "bg-danger",
|
|
1264
|
+
neutral: "bg-neutral",
|
|
1265
|
+
default: "bg-default-tertiary"
|
|
1266
|
+
};
|
|
1267
|
+
function StatusDot({ tone = "default", color, className }) {
|
|
1268
|
+
return /* @__PURE__ */ jsx19(
|
|
1269
|
+
"span",
|
|
1270
|
+
{
|
|
1271
|
+
className: clsx19("inline-block size-1.5 shrink-0 rounded-full", !color && dotTones[tone], className),
|
|
1272
|
+
style: color ? { backgroundColor: color } : void 0
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
// src/components/status/status-chip.tsx
|
|
1278
|
+
import clsx20 from "clsx";
|
|
1279
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1280
|
+
function StatusChip({ label, count, tone = "default", dotColor, bg, className }) {
|
|
1281
|
+
return /* @__PURE__ */ jsxs17(
|
|
1282
|
+
"span",
|
|
1283
|
+
{
|
|
1284
|
+
className: clsx20(
|
|
1285
|
+
"inline-flex items-center gap-1.5 rounded-full px-2.5 py-1",
|
|
1286
|
+
!bg && "bg-default-secondary",
|
|
1287
|
+
className
|
|
1288
|
+
),
|
|
1289
|
+
style: bg ? { backgroundColor: bg } : void 0,
|
|
1290
|
+
children: [
|
|
1291
|
+
/* @__PURE__ */ jsx20(StatusDot, { tone, color: dotColor }),
|
|
1292
|
+
/* @__PURE__ */ jsx20("span", { className: "text-body-xs font-medium text-default", children: count }),
|
|
1293
|
+
/* @__PURE__ */ jsx20("span", { className: "text-body-xs text-default-secondary", children: label })
|
|
1294
|
+
]
|
|
1295
|
+
}
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// src/components/status/count-badge.tsx
|
|
1300
|
+
import clsx21 from "clsx";
|
|
1301
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1302
|
+
function CountBadge({ count, label, tone = "positive", className }) {
|
|
1303
|
+
return /* @__PURE__ */ jsxs18(
|
|
1304
|
+
"span",
|
|
1305
|
+
{
|
|
1306
|
+
className: clsx21(
|
|
1307
|
+
"inline-flex items-center gap-1.5 rounded-full border border-default px-2.5 py-1 text-body-xs font-medium text-default",
|
|
1308
|
+
className
|
|
1309
|
+
),
|
|
1310
|
+
children: [
|
|
1311
|
+
/* @__PURE__ */ jsx21(StatusDot, { tone }),
|
|
1312
|
+
count,
|
|
1313
|
+
label && /* @__PURE__ */ jsx21("span", { className: "text-default-secondary", children: label })
|
|
1314
|
+
]
|
|
1315
|
+
}
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// src/components/status/tag-pill.tsx
|
|
1320
|
+
import clsx22 from "clsx";
|
|
1321
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1322
|
+
var toneStyles = {
|
|
1323
|
+
default: "bg-default-secondary text-default-secondary",
|
|
1324
|
+
brand: "bg-brand-tertiary text-brand",
|
|
1325
|
+
positive: "bg-positive-tertiary text-positive",
|
|
1326
|
+
warning: "bg-warning-tertiary text-warning",
|
|
1327
|
+
danger: "bg-danger-tertiary text-danger"
|
|
1328
|
+
};
|
|
1329
|
+
function TagPill({ label, tone = "default", bg, color, className }) {
|
|
1330
|
+
return /* @__PURE__ */ jsx22(
|
|
1331
|
+
"span",
|
|
1332
|
+
{
|
|
1333
|
+
className: clsx22(
|
|
1334
|
+
"inline-flex items-center rounded-full px-2 py-0.5 text-body-xs font-medium",
|
|
1335
|
+
!bg && !color && toneStyles[tone],
|
|
1336
|
+
className
|
|
1337
|
+
),
|
|
1338
|
+
style: {
|
|
1339
|
+
...bg ? { backgroundColor: bg } : void 0,
|
|
1340
|
+
...color ? { color } : void 0
|
|
1341
|
+
},
|
|
1342
|
+
children: label
|
|
1343
|
+
}
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
// src/components/status/trail-chip.tsx
|
|
1348
|
+
import clsx23 from "clsx";
|
|
1349
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1350
|
+
var DOT = {
|
|
1351
|
+
neutral: "bg-status-dot-neutral",
|
|
1352
|
+
info: "bg-status-dot-info",
|
|
1353
|
+
warning: "bg-status-dot-warning",
|
|
1354
|
+
caution: "bg-status-dot-caution",
|
|
1355
|
+
accent: "bg-status-dot-accent",
|
|
1356
|
+
positive: "bg-status-dot-positive",
|
|
1357
|
+
danger: "bg-status-dot-danger"
|
|
1358
|
+
};
|
|
1359
|
+
function TrailChip({ label, value, tone = "info", dotColor, className }) {
|
|
1360
|
+
return /* @__PURE__ */ jsxs19(
|
|
1361
|
+
"div",
|
|
1362
|
+
{
|
|
1363
|
+
className: clsx23(
|
|
1364
|
+
"flex items-center gap-2 rounded-full border border-default bg-default px-3 py-1.5",
|
|
1365
|
+
className
|
|
1366
|
+
),
|
|
1367
|
+
children: [
|
|
1368
|
+
/* @__PURE__ */ jsx23(
|
|
1369
|
+
"span",
|
|
1370
|
+
{
|
|
1371
|
+
className: clsx23("size-1.5 shrink-0 rounded-full", !dotColor && DOT[tone]),
|
|
1372
|
+
style: dotColor ? { backgroundColor: dotColor } : void 0
|
|
1373
|
+
}
|
|
1374
|
+
),
|
|
1375
|
+
/* @__PURE__ */ jsx23("span", { className: "text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: label }),
|
|
1376
|
+
/* @__PURE__ */ jsx23("span", { className: "text-body-xs font-medium text-default", children: value })
|
|
1377
|
+
]
|
|
1378
|
+
}
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// src/components/status/user-status-pill.tsx
|
|
1383
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1384
|
+
var STATUS_META = {
|
|
1385
|
+
active: { label: "Active", tone: "positive" },
|
|
1386
|
+
// `caution` (pale yellow), not `warning` (orange) — Pending is one step below a
|
|
1387
|
+
// warning on the severity ramp, and reads as waiting rather than at risk.
|
|
1388
|
+
pending: { label: "Pending", tone: "caution" },
|
|
1389
|
+
deactivated: { label: "Deactivated", tone: "danger" }
|
|
1390
|
+
};
|
|
1391
|
+
function UserStatusPill({ status }) {
|
|
1392
|
+
const { label, tone } = STATUS_META[status];
|
|
1393
|
+
return /* @__PURE__ */ jsx24(StatusBadge, { label, tone });
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// src/components/status/check-indicator.tsx
|
|
1397
|
+
import clsx24 from "clsx";
|
|
1398
|
+
import { LuCheck as LuCheck3, LuCircleAlert, LuLoaderCircle, LuMinus, LuX as LuX2 } from "react-icons/lu";
|
|
1399
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1400
|
+
var STATUS_STYLES = {
|
|
1401
|
+
passed: "bg-status-check-passed border-status-check-passed text-status-check-passed",
|
|
1402
|
+
in_progress: "bg-status-check-progress border-status-check-progress text-status-check-progress",
|
|
1403
|
+
action_required: "bg-status-check-failed border-status-check-failed text-status-check-failed",
|
|
1404
|
+
failed: "bg-status-check-failed border-status-check-failed text-status-check-failed",
|
|
1405
|
+
pending: "bg-status-check-pending border-status-check-pending text-status-check-pending",
|
|
1406
|
+
waived: "bg-status-check-pending border-status-check-pending text-status-check-pending"
|
|
1407
|
+
};
|
|
1408
|
+
function StatusGlyph({ status }) {
|
|
1409
|
+
switch (status) {
|
|
1410
|
+
case "passed":
|
|
1411
|
+
return /* @__PURE__ */ jsx25(LuCheck3, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
|
|
1412
|
+
case "failed":
|
|
1413
|
+
return /* @__PURE__ */ jsx25(LuX2, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
|
|
1414
|
+
case "waived":
|
|
1415
|
+
return /* @__PURE__ */ jsx25(LuMinus, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
|
|
1416
|
+
case "in_progress":
|
|
1417
|
+
return /* @__PURE__ */ jsx25(LuLoaderCircle, { className: "size-3", strokeWidth: 3, "aria-hidden": true });
|
|
1418
|
+
case "action_required":
|
|
1419
|
+
return /* @__PURE__ */ jsx25(LuCircleAlert, { className: "size-3.5", strokeWidth: 2.5, "aria-hidden": true });
|
|
1420
|
+
case "pending":
|
|
1421
|
+
return null;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
function CheckIndicator({ status, label, className }) {
|
|
1425
|
+
return /* @__PURE__ */ jsx25(
|
|
1426
|
+
"div",
|
|
1427
|
+
{
|
|
1428
|
+
className: clsx24(
|
|
1429
|
+
"flex size-[22px] shrink-0 items-center justify-center rounded-full border-[1.5px]",
|
|
1430
|
+
STATUS_STYLES[status],
|
|
1431
|
+
className
|
|
1432
|
+
),
|
|
1433
|
+
role: label ? "img" : void 0,
|
|
1434
|
+
"aria-label": label,
|
|
1435
|
+
"aria-hidden": label ? void 0 : true,
|
|
1436
|
+
children: /* @__PURE__ */ jsx25(StatusGlyph, { status })
|
|
1437
|
+
}
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
// src/components/status/entity-icon-badge.tsx
|
|
1442
|
+
import clsx25 from "clsx";
|
|
1443
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1444
|
+
var sizeStyles4 = {
|
|
1445
|
+
sm: "size-8",
|
|
1446
|
+
md: "size-10"
|
|
1447
|
+
};
|
|
1448
|
+
var shapeStyles = {
|
|
1449
|
+
square: { sm: "rounded-lg", md: "rounded-xl" },
|
|
1450
|
+
circle: { sm: "rounded-full", md: "rounded-full" }
|
|
1451
|
+
};
|
|
1452
|
+
var toneStyles2 = {
|
|
1453
|
+
default: "bg-default-secondary text-icon-default",
|
|
1454
|
+
brand: "bg-brand-tertiary text-icon-brand",
|
|
1455
|
+
positive: "bg-positive-tertiary text-icon-positive",
|
|
1456
|
+
warning: "bg-warning-tertiary text-icon-warning",
|
|
1457
|
+
danger: "bg-danger-tertiary text-icon-danger",
|
|
1458
|
+
neutral: "bg-neutral-tertiary text-icon-neutral"
|
|
1459
|
+
};
|
|
1460
|
+
function EntityIconBadge({ size = "sm", tone = "default", shape = "square", bg, iconColor, children, className }) {
|
|
1461
|
+
return /* @__PURE__ */ jsx26(
|
|
1462
|
+
"span",
|
|
1463
|
+
{
|
|
1464
|
+
className: clsx25(
|
|
1465
|
+
"inline-flex shrink-0 items-center justify-center",
|
|
1466
|
+
sizeStyles4[size],
|
|
1467
|
+
shapeStyles[shape][size],
|
|
1468
|
+
!bg && !iconColor && toneStyles2[tone],
|
|
1469
|
+
className
|
|
1470
|
+
),
|
|
1471
|
+
style: {
|
|
1472
|
+
...bg ? { backgroundColor: bg } : void 0,
|
|
1473
|
+
...iconColor ? { color: iconColor } : void 0
|
|
1474
|
+
},
|
|
1475
|
+
children
|
|
1476
|
+
}
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
// src/components/forms/checkbox.tsx
|
|
1481
|
+
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
1482
|
+
import clsx26 from "clsx";
|
|
1483
|
+
import { LuCheck as LuCheck4, LuMinus as LuMinus2 } from "react-icons/lu";
|
|
1484
|
+
import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1485
|
+
function Checkbox({
|
|
1486
|
+
checked,
|
|
1487
|
+
onChange,
|
|
1488
|
+
label,
|
|
1489
|
+
disabled = false,
|
|
1490
|
+
indeterminate = false,
|
|
1491
|
+
className
|
|
1492
|
+
}) {
|
|
1493
|
+
const inputRef = useRef3(null);
|
|
1494
|
+
useEffect2(() => {
|
|
1495
|
+
if (inputRef.current) inputRef.current.indeterminate = indeterminate;
|
|
1496
|
+
}, [indeterminate]);
|
|
1497
|
+
return /* @__PURE__ */ jsxs20(
|
|
1498
|
+
"label",
|
|
1499
|
+
{
|
|
1500
|
+
className: clsx26(
|
|
1501
|
+
"group inline-flex items-start gap-2.5",
|
|
1502
|
+
disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer",
|
|
1503
|
+
className
|
|
1504
|
+
),
|
|
1505
|
+
children: [
|
|
1506
|
+
/* @__PURE__ */ jsx27(
|
|
1507
|
+
"input",
|
|
1508
|
+
{
|
|
1509
|
+
ref: inputRef,
|
|
1510
|
+
type: "checkbox",
|
|
1511
|
+
checked,
|
|
1512
|
+
disabled,
|
|
1513
|
+
onChange: (e) => onChange(e.target.checked),
|
|
1514
|
+
className: "peer sr-only"
|
|
1515
|
+
}
|
|
1516
|
+
),
|
|
1517
|
+
/* @__PURE__ */ jsx27(
|
|
1518
|
+
"span",
|
|
1519
|
+
{
|
|
1520
|
+
"aria-hidden": true,
|
|
1521
|
+
className: clsx26(
|
|
1522
|
+
"mt-px flex size-[18px] shrink-0 items-center justify-center rounded-[4px] border-[1.5px] transition-colors",
|
|
1523
|
+
"peer-focus-visible:ring-2 peer-focus-visible:ring-brand peer-focus-visible:ring-offset-1",
|
|
1524
|
+
checked || indeterminate ? "border-brand-emphasis bg-brand text-brand-on-brand" : "border-default-secondary bg-default"
|
|
1525
|
+
),
|
|
1526
|
+
children: indeterminate ? /* @__PURE__ */ jsx27(LuMinus2, { className: "size-3", strokeWidth: 3 }) : checked ? /* @__PURE__ */ jsx27(LuCheck4, { className: "size-3", strokeWidth: 3 }) : null
|
|
1527
|
+
}
|
|
1528
|
+
),
|
|
1529
|
+
label && /* @__PURE__ */ jsx27("span", { className: "text-body-xs text-default", children: label })
|
|
1530
|
+
]
|
|
1531
|
+
}
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// src/components/forms/segmented-control.tsx
|
|
1536
|
+
import clsx27 from "clsx";
|
|
1537
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1538
|
+
function SegmentedControl({ options, value, onChange, className }) {
|
|
1539
|
+
return /* @__PURE__ */ jsx28(
|
|
1540
|
+
"div",
|
|
1541
|
+
{
|
|
1542
|
+
className: clsx27(
|
|
1543
|
+
"inline-flex items-center rounded-xl border border-default bg-default-secondary p-0.5",
|
|
1544
|
+
className
|
|
1545
|
+
),
|
|
1546
|
+
children: options.map((opt) => /* @__PURE__ */ jsx28(
|
|
1547
|
+
"button",
|
|
1548
|
+
{
|
|
1549
|
+
type: "button",
|
|
1550
|
+
onClick: () => onChange?.(opt.value),
|
|
1551
|
+
className: clsx27(
|
|
1552
|
+
"rounded-lg px-3.5 py-1.5 text-body-xs font-medium transition-colors",
|
|
1553
|
+
opt.value === value ? "bg-default shadow-panel text-default" : "text-default-secondary hover:text-default"
|
|
1554
|
+
),
|
|
1555
|
+
children: opt.label
|
|
1556
|
+
},
|
|
1557
|
+
opt.value
|
|
1558
|
+
))
|
|
1559
|
+
}
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// src/components/overlays/modal.tsx
|
|
1564
|
+
import { useRef as useRef4 } from "react";
|
|
1565
|
+
import { LuCircleCheckBig, LuInfo, LuOctagonAlert, LuTriangleAlert, LuX as LuX3 } from "react-icons/lu";
|
|
1566
|
+
|
|
1567
|
+
// src/lib/cn.ts
|
|
1568
|
+
import { clsx as clsx28 } from "clsx";
|
|
1569
|
+
import { twMerge } from "tailwind-merge";
|
|
1570
|
+
function cn(...inputs) {
|
|
1571
|
+
return twMerge(clsx28(inputs));
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
// src/components/overlays/overlay.ts
|
|
1575
|
+
import { useEffect as useEffect3 } from "react";
|
|
1576
|
+
var OVERLAY_SCRIM = "bg-overlay";
|
|
1577
|
+
var FOCUSABLE = [
|
|
1578
|
+
"a[href]",
|
|
1579
|
+
"button:not([disabled])",
|
|
1580
|
+
"input:not([disabled])",
|
|
1581
|
+
"select:not([disabled])",
|
|
1582
|
+
"textarea:not([disabled])",
|
|
1583
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
1584
|
+
].join(",");
|
|
1585
|
+
function focusableWithin(root) {
|
|
1586
|
+
return Array.from(root.querySelectorAll(FOCUSABLE)).filter(
|
|
1587
|
+
(el) => el.offsetParent !== null || el === root
|
|
1588
|
+
);
|
|
1589
|
+
}
|
|
1590
|
+
function useOverlayDismiss(onClose, panelRef) {
|
|
1591
|
+
useEffect3(() => {
|
|
1592
|
+
function onKeyDown(e) {
|
|
1593
|
+
const panel = panelRef.current;
|
|
1594
|
+
if (e.key === "Escape") {
|
|
1595
|
+
e.stopPropagation();
|
|
1596
|
+
onClose();
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
if (e.key !== "Tab" || !panel) return;
|
|
1600
|
+
const items = focusableWithin(panel);
|
|
1601
|
+
if (items.length === 0) return;
|
|
1602
|
+
const first = items[0];
|
|
1603
|
+
const last = items[items.length - 1];
|
|
1604
|
+
const active = document.activeElement;
|
|
1605
|
+
if (e.shiftKey && (active === first || !panel.contains(active))) {
|
|
1606
|
+
e.preventDefault();
|
|
1607
|
+
last.focus();
|
|
1608
|
+
} else if (!e.shiftKey && active === last) {
|
|
1609
|
+
e.preventDefault();
|
|
1610
|
+
first.focus();
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
document.addEventListener("keydown", onKeyDown);
|
|
1614
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
1615
|
+
}, [onClose, panelRef]);
|
|
1616
|
+
useEffect3(() => {
|
|
1617
|
+
const previouslyFocused = document.activeElement;
|
|
1618
|
+
const panel = panelRef.current;
|
|
1619
|
+
if (panel) {
|
|
1620
|
+
const target = focusableWithin(panel)[0] ?? panel;
|
|
1621
|
+
target.focus({ preventScroll: true });
|
|
1622
|
+
}
|
|
1623
|
+
return () => previouslyFocused?.focus?.({ preventScroll: true });
|
|
1624
|
+
}, [panelRef]);
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// src/components/overlays/modal.tsx
|
|
1628
|
+
import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1629
|
+
var SIZE2 = {
|
|
1630
|
+
sm: "sm:max-w-[420px]",
|
|
1631
|
+
md: "sm:max-w-[540px]",
|
|
1632
|
+
lg: "sm:max-w-[640px]",
|
|
1633
|
+
xl: "sm:max-w-[800px]"
|
|
1634
|
+
};
|
|
1635
|
+
var TONE_ICON = {
|
|
1636
|
+
info: /* @__PURE__ */ jsx29(LuInfo, { className: "size-5" }),
|
|
1637
|
+
positive: /* @__PURE__ */ jsx29(LuCircleCheckBig, { className: "size-5" }),
|
|
1638
|
+
warning: /* @__PURE__ */ jsx29(LuTriangleAlert, { className: "size-5" }),
|
|
1639
|
+
danger: /* @__PURE__ */ jsx29(LuOctagonAlert, { className: "size-5" })
|
|
1640
|
+
};
|
|
1641
|
+
var TONE_BADGE = {
|
|
1642
|
+
info: "brand",
|
|
1643
|
+
positive: "positive",
|
|
1644
|
+
warning: "warning",
|
|
1645
|
+
danger: "danger"
|
|
1646
|
+
};
|
|
1647
|
+
var FOOTER_ALIGN = {
|
|
1648
|
+
start: "justify-start",
|
|
1649
|
+
between: "justify-between",
|
|
1650
|
+
end: "justify-end"
|
|
1651
|
+
};
|
|
1652
|
+
function Modal(props) {
|
|
1653
|
+
if (!props.isOpen) return null;
|
|
1654
|
+
return /* @__PURE__ */ jsx29(ModalShell, { ...props });
|
|
1655
|
+
}
|
|
1656
|
+
function ModalShell({
|
|
1657
|
+
onClose,
|
|
1658
|
+
label,
|
|
1659
|
+
children,
|
|
1660
|
+
size = "md",
|
|
1661
|
+
showClose = true,
|
|
1662
|
+
className
|
|
1663
|
+
}) {
|
|
1664
|
+
const panelRef = useRef4(null);
|
|
1665
|
+
useOverlayDismiss(onClose, panelRef);
|
|
1666
|
+
return /* @__PURE__ */ jsx29(
|
|
1667
|
+
"div",
|
|
1668
|
+
{
|
|
1669
|
+
className: cn("fixed inset-0 z-50 flex items-end justify-center sm:items-center", OVERLAY_SCRIM),
|
|
1670
|
+
onClick: (e) => {
|
|
1671
|
+
if (e.target === e.currentTarget) onClose();
|
|
1672
|
+
},
|
|
1673
|
+
children: /* @__PURE__ */ jsxs21(
|
|
1674
|
+
"div",
|
|
1675
|
+
{
|
|
1676
|
+
ref: panelRef,
|
|
1677
|
+
role: "dialog",
|
|
1678
|
+
"aria-modal": "true",
|
|
1679
|
+
"aria-label": label,
|
|
1680
|
+
className: cn(
|
|
1681
|
+
"relative max-h-[92dvh] w-full overflow-y-auto bg-default shadow-xl",
|
|
1682
|
+
"rounded-t-2xl pb-[env(safe-area-inset-bottom)] sm:mx-4 sm:rounded-2xl sm:pb-0",
|
|
1683
|
+
SIZE2[size],
|
|
1684
|
+
className
|
|
1685
|
+
),
|
|
1686
|
+
children: [
|
|
1687
|
+
showClose && /* @__PURE__ */ jsx29(
|
|
1688
|
+
IconButton,
|
|
1689
|
+
{
|
|
1690
|
+
variant: "subtle",
|
|
1691
|
+
size: "sm",
|
|
1692
|
+
"aria-label": "Close dialog",
|
|
1693
|
+
onClick: onClose,
|
|
1694
|
+
className: "absolute right-6 top-5 z-10",
|
|
1695
|
+
children: /* @__PURE__ */ jsx29(LuX3, { size: 16 })
|
|
1696
|
+
}
|
|
1697
|
+
),
|
|
1698
|
+
children
|
|
1699
|
+
]
|
|
1700
|
+
}
|
|
1701
|
+
)
|
|
1702
|
+
}
|
|
1703
|
+
);
|
|
1704
|
+
}
|
|
1705
|
+
function ModalHeader({
|
|
1706
|
+
children,
|
|
1707
|
+
tone = "default",
|
|
1708
|
+
divider = true,
|
|
1709
|
+
className,
|
|
1710
|
+
...rest
|
|
1711
|
+
}) {
|
|
1712
|
+
return /* @__PURE__ */ jsxs21(
|
|
1713
|
+
"div",
|
|
1714
|
+
{
|
|
1715
|
+
className: cn(
|
|
1716
|
+
// pr-14 reserves the floating close button's column (24px gutter + 24px
|
|
1717
|
+
// button + gap), which the old flex-between header used to hold open.
|
|
1718
|
+
"flex items-start gap-3 px-6 py-5 pr-14",
|
|
1719
|
+
divider && "border-b border-default",
|
|
1720
|
+
className
|
|
1721
|
+
),
|
|
1722
|
+
...rest,
|
|
1723
|
+
children: [
|
|
1724
|
+
tone !== "default" && /* @__PURE__ */ jsx29(EntityIconBadge, { size: "md", shape: "circle", tone: TONE_BADGE[tone], children: TONE_ICON[tone] }),
|
|
1725
|
+
/* @__PURE__ */ jsx29("div", { className: "min-w-0 flex-1", children })
|
|
1726
|
+
]
|
|
1727
|
+
}
|
|
1728
|
+
);
|
|
1729
|
+
}
|
|
1730
|
+
function ModalTitle({ children, className, ...rest }) {
|
|
1731
|
+
return /* @__PURE__ */ jsx29("h2", { className: cn("text-heading-sm font-semibold text-default", className), ...rest, children });
|
|
1732
|
+
}
|
|
1733
|
+
function ModalDescription({ children, className, ...rest }) {
|
|
1734
|
+
return /* @__PURE__ */ jsx29("p", { className: cn("mt-0.5 text-body-xs text-default-secondary", className), ...rest, children });
|
|
1735
|
+
}
|
|
1736
|
+
function ModalBody({ children, className, ...rest }) {
|
|
1737
|
+
return /* @__PURE__ */ jsx29("div", { className: cn("px-6 py-5", className), ...rest, children });
|
|
1738
|
+
}
|
|
1739
|
+
function ModalFooter({
|
|
1740
|
+
children,
|
|
1741
|
+
align = "end",
|
|
1742
|
+
divider = true,
|
|
1743
|
+
className,
|
|
1744
|
+
...rest
|
|
1745
|
+
}) {
|
|
1746
|
+
return /* @__PURE__ */ jsx29(
|
|
1747
|
+
"div",
|
|
1748
|
+
{
|
|
1749
|
+
className: cn(
|
|
1750
|
+
"flex items-center gap-2 px-6 py-4",
|
|
1751
|
+
FOOTER_ALIGN[align],
|
|
1752
|
+
divider && "border-t border-default",
|
|
1753
|
+
className
|
|
1754
|
+
),
|
|
1755
|
+
...rest,
|
|
1756
|
+
children
|
|
1757
|
+
}
|
|
1758
|
+
);
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// src/components/overlays/drawer.tsx
|
|
1762
|
+
import { useRef as useRef5 } from "react";
|
|
1763
|
+
import clsx29 from "clsx";
|
|
1764
|
+
import { LuX as LuX4 } from "react-icons/lu";
|
|
1765
|
+
import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1766
|
+
function Drawer(props) {
|
|
1767
|
+
if (!props.isOpen) return null;
|
|
1768
|
+
return /* @__PURE__ */ jsx30(DrawerShell, { ...props });
|
|
1769
|
+
}
|
|
1770
|
+
function DrawerShell({
|
|
1771
|
+
onClose,
|
|
1772
|
+
header,
|
|
1773
|
+
children,
|
|
1774
|
+
footer,
|
|
1775
|
+
footerAlign = "end",
|
|
1776
|
+
width = "w-[440px] max-w-[90vw]",
|
|
1777
|
+
label,
|
|
1778
|
+
className
|
|
1779
|
+
}) {
|
|
1780
|
+
const panelRef = useRef5(null);
|
|
1781
|
+
useOverlayDismiss(onClose, panelRef);
|
|
1782
|
+
return /* @__PURE__ */ jsx30(
|
|
1783
|
+
"div",
|
|
1784
|
+
{
|
|
1785
|
+
className: clsx29("fixed inset-0 z-50 flex justify-end", OVERLAY_SCRIM),
|
|
1786
|
+
onClick: (e) => {
|
|
1787
|
+
if (e.target === e.currentTarget) onClose();
|
|
1788
|
+
},
|
|
1789
|
+
children: /* @__PURE__ */ jsxs22(
|
|
1790
|
+
"aside",
|
|
1791
|
+
{
|
|
1792
|
+
ref: panelRef,
|
|
1793
|
+
role: "dialog",
|
|
1794
|
+
"aria-modal": "true",
|
|
1795
|
+
"aria-label": label,
|
|
1796
|
+
className: clsx29("relative flex h-full flex-col bg-default shadow-2xl", width, className),
|
|
1797
|
+
children: [
|
|
1798
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-start justify-between gap-3 border-b border-default p-6", children: [
|
|
1799
|
+
/* @__PURE__ */ jsx30("div", { className: "min-w-0", children: header }),
|
|
1800
|
+
/* @__PURE__ */ jsx30(IconButton, { variant: "subtle", size: "sm", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx30(LuX4, { size: 18 }) })
|
|
1801
|
+
] }),
|
|
1802
|
+
/* @__PURE__ */ jsx30("div", { className: "flex-1 space-y-6 overflow-y-auto p-6", children }),
|
|
1803
|
+
footer && /* @__PURE__ */ jsx30(
|
|
1804
|
+
"div",
|
|
1805
|
+
{
|
|
1806
|
+
className: clsx29(
|
|
1807
|
+
"flex items-center gap-2 border-t border-default px-6 py-4",
|
|
1808
|
+
footerAlign === "between" ? "justify-between" : "justify-end"
|
|
1809
|
+
),
|
|
1810
|
+
children: footer
|
|
1811
|
+
}
|
|
1812
|
+
)
|
|
1813
|
+
]
|
|
1814
|
+
}
|
|
1815
|
+
)
|
|
1816
|
+
}
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
// src/components/overlays/confirm-dialog.tsx
|
|
1821
|
+
import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1822
|
+
function ConfirmDialog({
|
|
1823
|
+
isOpen,
|
|
1824
|
+
title,
|
|
1825
|
+
subtitle,
|
|
1826
|
+
tone = "default",
|
|
1827
|
+
size = "md",
|
|
1828
|
+
confirmLabel = "Confirm",
|
|
1829
|
+
cancelLabel = "Cancel",
|
|
1830
|
+
confirmVariant = "primary",
|
|
1831
|
+
isConfirming = false,
|
|
1832
|
+
confirmingLabel = "Working\u2026",
|
|
1833
|
+
children,
|
|
1834
|
+
className,
|
|
1835
|
+
onConfirm,
|
|
1836
|
+
onClose
|
|
1837
|
+
}) {
|
|
1838
|
+
return /* @__PURE__ */ jsxs23(Modal, { isOpen, onClose, label: title, size, className, children: [
|
|
1839
|
+
/* @__PURE__ */ jsxs23(ModalHeader, { tone, divider: Boolean(children), children: [
|
|
1840
|
+
/* @__PURE__ */ jsx31(ModalTitle, { children: title }),
|
|
1841
|
+
subtitle && /* @__PURE__ */ jsx31(ModalDescription, { children: subtitle })
|
|
1842
|
+
] }),
|
|
1843
|
+
children && /* @__PURE__ */ jsx31(ModalBody, { children }),
|
|
1844
|
+
/* @__PURE__ */ jsxs23(ModalFooter, { children: [
|
|
1845
|
+
/* @__PURE__ */ jsx31(Button, { variant: "neutral", size: "md", onClick: onClose, children: cancelLabel }),
|
|
1846
|
+
/* @__PURE__ */ jsx31(Button, { variant: confirmVariant, size: "md", disabled: isConfirming, onClick: onConfirm, children: isConfirming ? confirmingLabel : confirmLabel })
|
|
1847
|
+
] })
|
|
1848
|
+
] });
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
// src/components/overlays/note-confirm-modal.tsx
|
|
1852
|
+
import { useState as useState3 } from "react";
|
|
1853
|
+
import { jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1854
|
+
function NoteConfirmModal({ isOpen, ...rest }) {
|
|
1855
|
+
if (!isOpen) return null;
|
|
1856
|
+
return /* @__PURE__ */ jsx32(NoteConfirmModalShell, { ...rest });
|
|
1857
|
+
}
|
|
1858
|
+
function NoteConfirmModalShell({
|
|
1859
|
+
title,
|
|
1860
|
+
subtitle,
|
|
1861
|
+
tone = "default",
|
|
1862
|
+
size = "md",
|
|
1863
|
+
confirmLabel,
|
|
1864
|
+
cancelLabel = "Cancel",
|
|
1865
|
+
confirmVariant = "primary",
|
|
1866
|
+
requireNote = false,
|
|
1867
|
+
notePlaceholder = "Add a note\u2026",
|
|
1868
|
+
submittingLabel = "Saving\u2026",
|
|
1869
|
+
isSubmitting = false,
|
|
1870
|
+
className,
|
|
1871
|
+
onClose,
|
|
1872
|
+
onConfirm
|
|
1873
|
+
}) {
|
|
1874
|
+
const [note, setNote] = useState3("");
|
|
1875
|
+
const disabled = isSubmitting || requireNote && !note.trim();
|
|
1876
|
+
return /* @__PURE__ */ jsxs24(Modal, { isOpen: true, onClose, label: title, size, className, children: [
|
|
1877
|
+
/* @__PURE__ */ jsxs24(ModalHeader, { tone, children: [
|
|
1878
|
+
/* @__PURE__ */ jsx32(ModalTitle, { children: title }),
|
|
1879
|
+
subtitle && /* @__PURE__ */ jsx32(ModalDescription, { children: subtitle })
|
|
1880
|
+
] }),
|
|
1881
|
+
/* @__PURE__ */ jsx32(ModalBody, { children: /* @__PURE__ */ jsx32(
|
|
1882
|
+
Textarea,
|
|
1883
|
+
{
|
|
1884
|
+
value: note,
|
|
1885
|
+
onChange: (e) => setNote(e.target.value),
|
|
1886
|
+
placeholder: notePlaceholder,
|
|
1887
|
+
rows: 4
|
|
1888
|
+
}
|
|
1889
|
+
) }),
|
|
1890
|
+
/* @__PURE__ */ jsxs24(ModalFooter, { children: [
|
|
1891
|
+
/* @__PURE__ */ jsx32(Button, { variant: "neutral", size: "md", onClick: onClose, children: cancelLabel }),
|
|
1892
|
+
/* @__PURE__ */ jsx32(Button, { variant: confirmVariant, size: "md", disabled, onClick: () => onConfirm(note.trim()), children: isSubmitting ? submittingLabel : confirmLabel })
|
|
1893
|
+
] })
|
|
1894
|
+
] });
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
// src/components/overlays/dropdown-menu.tsx
|
|
1898
|
+
import { useEffect as useEffect4, useRef as useRef6, useState as useState4 } from "react";
|
|
1899
|
+
import clsx30 from "clsx";
|
|
1900
|
+
import { LuEllipsis } from "react-icons/lu";
|
|
1901
|
+
import { jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1902
|
+
function DropdownMenu({
|
|
1903
|
+
items,
|
|
1904
|
+
trigger,
|
|
1905
|
+
label,
|
|
1906
|
+
align = "right",
|
|
1907
|
+
className
|
|
1908
|
+
}) {
|
|
1909
|
+
const [open, setOpen] = useState4(false);
|
|
1910
|
+
const rootRef = useRef6(null);
|
|
1911
|
+
useEffect4(() => {
|
|
1912
|
+
if (!open) return;
|
|
1913
|
+
function handleOutside(e) {
|
|
1914
|
+
const root = rootRef.current;
|
|
1915
|
+
if (root && !root.contains(e.target)) setOpen(false);
|
|
1916
|
+
}
|
|
1917
|
+
function handleKey(e) {
|
|
1918
|
+
if (e.key === "Escape") setOpen(false);
|
|
1919
|
+
}
|
|
1920
|
+
document.addEventListener("mousedown", handleOutside);
|
|
1921
|
+
document.addEventListener("keydown", handleKey);
|
|
1922
|
+
return () => {
|
|
1923
|
+
document.removeEventListener("mousedown", handleOutside);
|
|
1924
|
+
document.removeEventListener("keydown", handleKey);
|
|
1925
|
+
};
|
|
1926
|
+
}, [open]);
|
|
1927
|
+
const visible = items.filter((item) => item.label);
|
|
1928
|
+
return /* @__PURE__ */ jsxs25(
|
|
1929
|
+
"div",
|
|
1930
|
+
{
|
|
1931
|
+
ref: rootRef,
|
|
1932
|
+
className: clsx30("relative", className),
|
|
1933
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1934
|
+
children: [
|
|
1935
|
+
/* @__PURE__ */ jsx33(
|
|
1936
|
+
"button",
|
|
1937
|
+
{
|
|
1938
|
+
type: "button",
|
|
1939
|
+
"aria-label": label,
|
|
1940
|
+
"aria-haspopup": "menu",
|
|
1941
|
+
"aria-expanded": open,
|
|
1942
|
+
onClick: (e) => {
|
|
1943
|
+
e.stopPropagation();
|
|
1944
|
+
setOpen((v) => !v);
|
|
1945
|
+
},
|
|
1946
|
+
className: clsx30(
|
|
1947
|
+
"rounded-md border border-default bg-default text-body-xs font-medium leading-none text-default transition-colors hover:bg-default-secondary",
|
|
1948
|
+
trigger ? "p-1.5" : "px-2.5 py-1.5"
|
|
1949
|
+
),
|
|
1950
|
+
children: trigger ?? /* @__PURE__ */ jsx33(LuEllipsis, { className: "size-4" })
|
|
1951
|
+
}
|
|
1952
|
+
),
|
|
1953
|
+
open && /* @__PURE__ */ jsx33(
|
|
1954
|
+
"div",
|
|
1955
|
+
{
|
|
1956
|
+
role: "menu",
|
|
1957
|
+
className: clsx30(
|
|
1958
|
+
"absolute top-full z-20 mt-1 min-w-[148px] rounded-lg border border-default bg-default py-1 shadow-lg",
|
|
1959
|
+
align === "right" ? "right-0" : "left-0"
|
|
1960
|
+
),
|
|
1961
|
+
children: visible.map((item, i) => /* @__PURE__ */ jsxs25("div", { children: [
|
|
1962
|
+
item.separatorBefore && i > 0 && /* @__PURE__ */ jsx33("div", { className: "my-1 h-px bg-divider" }),
|
|
1963
|
+
/* @__PURE__ */ jsx33(
|
|
1964
|
+
"button",
|
|
1965
|
+
{
|
|
1966
|
+
type: "button",
|
|
1967
|
+
role: "menuitem",
|
|
1968
|
+
disabled: item.disabled,
|
|
1969
|
+
className: clsx30(
|
|
1970
|
+
"flex w-full items-center px-3 py-2 text-left text-body-sm transition-colors",
|
|
1971
|
+
item.disabled && "cursor-not-allowed opacity-50",
|
|
1972
|
+
item.tone === "danger" ? "text-danger hover:bg-danger-tertiary" : "text-default hover:bg-default-secondary"
|
|
1973
|
+
),
|
|
1974
|
+
onClick: (e) => {
|
|
1975
|
+
e.stopPropagation();
|
|
1976
|
+
setOpen(false);
|
|
1977
|
+
item.onSelect();
|
|
1978
|
+
},
|
|
1979
|
+
children: item.label
|
|
1980
|
+
}
|
|
1981
|
+
)
|
|
1982
|
+
] }, item.label))
|
|
1983
|
+
}
|
|
1984
|
+
)
|
|
1985
|
+
]
|
|
1986
|
+
}
|
|
1987
|
+
);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// src/components/cards/card.tsx
|
|
1991
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
1992
|
+
var RADIUS = {
|
|
1993
|
+
lg: "rounded-lg",
|
|
1994
|
+
xl: "rounded-xl",
|
|
1995
|
+
"2xl": "rounded-2xl"
|
|
1996
|
+
};
|
|
1997
|
+
var TONE = {
|
|
1998
|
+
default: "border-default bg-default",
|
|
1999
|
+
brand: "border-brand-tertiary bg-brand-tertiary",
|
|
2000
|
+
positive: "border-positive-tertiary bg-positive-tertiary",
|
|
2001
|
+
warning: "border-warning-tertiary bg-warning-tertiary",
|
|
2002
|
+
// The one asymmetry: danger keeps the strong `border-danger` rather than the
|
|
2003
|
+
// tertiary border, because it is the only tone that has to read as an alarm from
|
|
2004
|
+
// across a dashboard. Byte-identical to the deleted AlertCard's danger surface.
|
|
2005
|
+
danger: "border-danger bg-danger-tertiary"
|
|
2006
|
+
};
|
|
2007
|
+
var BOX = {
|
|
2008
|
+
sm: "px-3 py-2",
|
|
2009
|
+
md: "px-4 py-3",
|
|
2010
|
+
lg: "px-5 py-4"
|
|
2011
|
+
};
|
|
2012
|
+
var BODY_BOX = {
|
|
2013
|
+
sm: "gap-3 p-3",
|
|
2014
|
+
md: "gap-4 p-4",
|
|
2015
|
+
lg: "gap-5 p-5"
|
|
2016
|
+
};
|
|
2017
|
+
var TITLE_SIZE = {
|
|
2018
|
+
sm: "text-body-xs",
|
|
2019
|
+
md: "text-body-sm",
|
|
2020
|
+
lg: "text-subheading-sm"
|
|
2021
|
+
};
|
|
2022
|
+
var FOOTER_ALIGN2 = {
|
|
2023
|
+
start: "justify-start",
|
|
2024
|
+
between: "justify-between",
|
|
2025
|
+
end: "justify-end"
|
|
2026
|
+
};
|
|
2027
|
+
function Card({ children, radius = "2xl", tone = "default", className, ...rest }) {
|
|
2028
|
+
return /* @__PURE__ */ jsx34(
|
|
2029
|
+
"div",
|
|
2030
|
+
{
|
|
2031
|
+
"data-slot": "card",
|
|
2032
|
+
className: cn("flex flex-col overflow-hidden border", RADIUS[radius], TONE[tone], className),
|
|
2033
|
+
...rest,
|
|
2034
|
+
children
|
|
2035
|
+
}
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
2038
|
+
function CardHeader({
|
|
2039
|
+
children,
|
|
2040
|
+
size = "md",
|
|
2041
|
+
divider = true,
|
|
2042
|
+
className,
|
|
2043
|
+
...rest
|
|
2044
|
+
}) {
|
|
2045
|
+
return /* @__PURE__ */ jsx34(
|
|
2046
|
+
"div",
|
|
2047
|
+
{
|
|
2048
|
+
"data-slot": "card-header",
|
|
2049
|
+
className: cn(
|
|
2050
|
+
"grid auto-rows-min items-center gap-x-3 gap-y-0.5",
|
|
2051
|
+
"has-[[data-slot=card-action]]:grid-cols-[1fr_auto]",
|
|
2052
|
+
BOX[size],
|
|
2053
|
+
divider && "border-b border-default",
|
|
2054
|
+
className
|
|
2055
|
+
),
|
|
2056
|
+
...rest,
|
|
2057
|
+
children
|
|
2058
|
+
}
|
|
2059
|
+
);
|
|
2060
|
+
}
|
|
2061
|
+
function CardTitle({ children, size = "md", as: Tag = "p", className, ...rest }) {
|
|
2062
|
+
return /* @__PURE__ */ jsx34(
|
|
2063
|
+
Tag,
|
|
2064
|
+
{
|
|
2065
|
+
"data-slot": "card-title",
|
|
2066
|
+
className: cn("min-w-0 font-semibold text-default", TITLE_SIZE[size], className),
|
|
2067
|
+
...rest,
|
|
2068
|
+
children
|
|
2069
|
+
}
|
|
2070
|
+
);
|
|
2071
|
+
}
|
|
2072
|
+
function CardDescription({ children, className, ...rest }) {
|
|
2073
|
+
return /* @__PURE__ */ jsx34(
|
|
2074
|
+
"p",
|
|
2075
|
+
{
|
|
2076
|
+
"data-slot": "card-description",
|
|
2077
|
+
className: cn("min-w-0 text-body-tiny text-default-secondary", className),
|
|
2078
|
+
...rest,
|
|
2079
|
+
children
|
|
2080
|
+
}
|
|
2081
|
+
);
|
|
2082
|
+
}
|
|
2083
|
+
function CardAction({ children, className, ...rest }) {
|
|
2084
|
+
return /* @__PURE__ */ jsx34(
|
|
2085
|
+
"div",
|
|
2086
|
+
{
|
|
2087
|
+
"data-slot": "card-action",
|
|
2088
|
+
className: cn("col-start-2 row-span-2 row-start-1 shrink-0 self-center justify-self-end", className),
|
|
2089
|
+
...rest,
|
|
2090
|
+
children
|
|
2091
|
+
}
|
|
2092
|
+
);
|
|
2093
|
+
}
|
|
2094
|
+
function CardBody({ children, size = "md", className, ...rest }) {
|
|
2095
|
+
return /* @__PURE__ */ jsx34("div", { "data-slot": "card-body", className: cn("flex flex-col", BODY_BOX[size], className), ...rest, children });
|
|
2096
|
+
}
|
|
2097
|
+
function CardFooter({
|
|
2098
|
+
children,
|
|
2099
|
+
size = "md",
|
|
2100
|
+
divider = true,
|
|
2101
|
+
align = "end",
|
|
2102
|
+
className,
|
|
2103
|
+
...rest
|
|
2104
|
+
}) {
|
|
2105
|
+
return /* @__PURE__ */ jsx34(
|
|
2106
|
+
"div",
|
|
2107
|
+
{
|
|
2108
|
+
"data-slot": "card-footer",
|
|
2109
|
+
className: cn(
|
|
2110
|
+
"flex items-center gap-2",
|
|
2111
|
+
BOX[size],
|
|
2112
|
+
FOOTER_ALIGN2[align],
|
|
2113
|
+
divider && "border-t border-default",
|
|
2114
|
+
className
|
|
2115
|
+
),
|
|
2116
|
+
...rest,
|
|
2117
|
+
children
|
|
2118
|
+
}
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// src/components/chrome/page-heading.tsx
|
|
2123
|
+
import clsx31 from "clsx";
|
|
2124
|
+
import { jsx as jsx35, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2125
|
+
var TITLE = {
|
|
2126
|
+
page: "text-2xl font-semibold text-default",
|
|
2127
|
+
toolbar: "text-heading-sm font-semibold leading-snug text-default",
|
|
2128
|
+
section: "text-lg font-semibold text-default"
|
|
2129
|
+
};
|
|
2130
|
+
var SUBTITLE = {
|
|
2131
|
+
page: "mt-1 text-body-sm text-default-secondary",
|
|
2132
|
+
toolbar: "text-body-xs text-default-secondary",
|
|
2133
|
+
section: "mt-1 text-body-sm text-default-secondary"
|
|
2134
|
+
};
|
|
2135
|
+
function PageHeading({
|
|
2136
|
+
title,
|
|
2137
|
+
subtitle,
|
|
2138
|
+
size = "page",
|
|
2139
|
+
as,
|
|
2140
|
+
actions,
|
|
2141
|
+
truncateTitle,
|
|
2142
|
+
className
|
|
2143
|
+
}) {
|
|
2144
|
+
const Tag = as ?? (size === "section" ? "h2" : "h1");
|
|
2145
|
+
const heading = /* @__PURE__ */ jsxs26("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
2146
|
+
/* @__PURE__ */ jsx35(Tag, { className: clsx31(TITLE[size], truncateTitle && "truncate"), children: title }),
|
|
2147
|
+
subtitle && /* @__PURE__ */ jsx35("p", { className: SUBTITLE[size], children: subtitle })
|
|
2148
|
+
] });
|
|
2149
|
+
if (!actions) return className ? /* @__PURE__ */ jsx35("div", { className, children: heading }) : heading;
|
|
2150
|
+
return /* @__PURE__ */ jsxs26("div", { className: clsx31("flex items-start justify-between gap-4", className), children: [
|
|
2151
|
+
heading,
|
|
2152
|
+
/* @__PURE__ */ jsx35("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
2153
|
+
] });
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
// src/components/chrome/page-toolbar.tsx
|
|
2157
|
+
import clsx32 from "clsx";
|
|
2158
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
2159
|
+
var SIZE3 = {
|
|
2160
|
+
sm: "min-h-[56px] px-4 py-2.5 md:px-7",
|
|
2161
|
+
md: "min-h-[72px] px-4 py-4 md:px-7"
|
|
2162
|
+
};
|
|
2163
|
+
function PageToolbar({ children, wrap, size = "md", className }) {
|
|
2164
|
+
return /* @__PURE__ */ jsx36(
|
|
2165
|
+
"div",
|
|
2166
|
+
{
|
|
2167
|
+
className: clsx32(
|
|
2168
|
+
"flex shrink-0 items-center justify-between gap-4 border-b border-default bg-default",
|
|
2169
|
+
SIZE3[size],
|
|
2170
|
+
wrap && "flex-wrap gap-2",
|
|
2171
|
+
className
|
|
2172
|
+
),
|
|
2173
|
+
children
|
|
2174
|
+
}
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// src/components/chrome/filter-bar.tsx
|
|
2179
|
+
import clsx33 from "clsx";
|
|
2180
|
+
import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2181
|
+
var GAP = {
|
|
2182
|
+
sm: "gap-2",
|
|
2183
|
+
md: "gap-3"
|
|
2184
|
+
};
|
|
2185
|
+
function FilterBar({ children, trailing, size = "md", className }) {
|
|
2186
|
+
return /* @__PURE__ */ jsxs27("div", { className: clsx33("flex flex-wrap items-center", GAP[size], className), children: [
|
|
2187
|
+
children,
|
|
2188
|
+
trailing && /* @__PURE__ */ jsx37("div", { className: "ml-auto flex items-center gap-2", children: trailing })
|
|
2189
|
+
] });
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
// src/components/chrome/tabs.tsx
|
|
2193
|
+
import clsx34 from "clsx";
|
|
2194
|
+
import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2195
|
+
var SIZE4 = {
|
|
2196
|
+
underline: {
|
|
2197
|
+
sm: { strip: "gap-4", tab: "px-0.5 py-1.5 text-body-xs" },
|
|
2198
|
+
md: { strip: "gap-6", tab: "px-0.5 py-2.5 text-body-sm" }
|
|
2199
|
+
},
|
|
2200
|
+
pill: {
|
|
2201
|
+
sm: { strip: "gap-1", tab: "rounded-md px-2.5 py-1.5 text-body-tiny" },
|
|
2202
|
+
md: { strip: "gap-1.5", tab: "rounded-lg px-3.5 py-2 text-body-xs" }
|
|
2203
|
+
}
|
|
2204
|
+
};
|
|
2205
|
+
function Tabs({
|
|
2206
|
+
items,
|
|
2207
|
+
value,
|
|
2208
|
+
onChange,
|
|
2209
|
+
variant = "underline",
|
|
2210
|
+
size = "md",
|
|
2211
|
+
className
|
|
2212
|
+
}) {
|
|
2213
|
+
const isPill = variant === "pill";
|
|
2214
|
+
const s = SIZE4[variant][size];
|
|
2215
|
+
return /* @__PURE__ */ jsx38(
|
|
2216
|
+
"div",
|
|
2217
|
+
{
|
|
2218
|
+
role: "tablist",
|
|
2219
|
+
className: clsx34(
|
|
2220
|
+
"flex shrink-0 overflow-x-auto",
|
|
2221
|
+
s.strip,
|
|
2222
|
+
!isPill && "border-b border-default",
|
|
2223
|
+
className
|
|
2224
|
+
),
|
|
2225
|
+
children: items.map((tab) => {
|
|
2226
|
+
const active = tab.key === value;
|
|
2227
|
+
return /* @__PURE__ */ jsxs28(
|
|
2228
|
+
"button",
|
|
2229
|
+
{
|
|
2230
|
+
type: "button",
|
|
2231
|
+
role: "tab",
|
|
2232
|
+
"aria-selected": active,
|
|
2233
|
+
onClick: () => onChange(tab.key),
|
|
2234
|
+
className: clsx34(
|
|
2235
|
+
"flex shrink-0 items-center gap-1.5 whitespace-nowrap transition-colors",
|
|
2236
|
+
s.tab,
|
|
2237
|
+
isPill ? clsx34(
|
|
2238
|
+
"font-medium",
|
|
2239
|
+
active ? "bg-brand text-brand-on-brand" : "text-default-secondary hover:bg-default-secondary"
|
|
2240
|
+
) : clsx34(
|
|
2241
|
+
"leading-snug",
|
|
2242
|
+
active ? "border-b-2 border-brand-emphasis font-semibold text-brand-emphasis" : "font-normal text-default-secondary hover:text-default"
|
|
2243
|
+
)
|
|
2244
|
+
),
|
|
2245
|
+
children: [
|
|
2246
|
+
tab.label,
|
|
2247
|
+
tab.count !== void 0 && /* @__PURE__ */ jsx38(
|
|
2248
|
+
"span",
|
|
2249
|
+
{
|
|
2250
|
+
className: clsx34(
|
|
2251
|
+
"rounded-md px-1.5 py-px text-body-tiny font-medium leading-snug",
|
|
2252
|
+
active && isPill ? "bg-brand-hover text-brand-on-brand" : "bg-default-secondary text-default-secondary"
|
|
2253
|
+
),
|
|
2254
|
+
children: tab.count
|
|
2255
|
+
}
|
|
2256
|
+
)
|
|
2257
|
+
]
|
|
2258
|
+
},
|
|
2259
|
+
tab.key
|
|
2260
|
+
);
|
|
2261
|
+
})
|
|
2262
|
+
}
|
|
2263
|
+
);
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// src/components/chrome/nav-item.tsx
|
|
2267
|
+
import clsx35 from "clsx";
|
|
2268
|
+
import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2269
|
+
var SIZE5 = {
|
|
2270
|
+
sm: { box: "h-9 gap-2 rounded-lg px-2.5 py-1.5", label: "text-body-xs" },
|
|
2271
|
+
md: { box: "h-11 gap-3 rounded-xl px-3.5 py-2.5", label: "text-body-sm" }
|
|
2272
|
+
};
|
|
2273
|
+
function NavItem({
|
|
2274
|
+
icon,
|
|
2275
|
+
label,
|
|
2276
|
+
isActive = false,
|
|
2277
|
+
indicator = false,
|
|
2278
|
+
collapsed = false,
|
|
2279
|
+
size = "md",
|
|
2280
|
+
className
|
|
2281
|
+
}) {
|
|
2282
|
+
const s = SIZE5[size];
|
|
2283
|
+
return /* @__PURE__ */ jsxs29(
|
|
2284
|
+
"span",
|
|
2285
|
+
{
|
|
2286
|
+
className: clsx35(
|
|
2287
|
+
"relative flex w-full items-center transition-colors",
|
|
2288
|
+
s.box,
|
|
2289
|
+
collapsed && "justify-center",
|
|
2290
|
+
isActive ? "bg-brand text-brand-on-brand" : [
|
|
2291
|
+
"border border-default bg-default text-default-secondary",
|
|
2292
|
+
"hover:bg-brand-tertiary-hover hover:border-brand-tertiary hover:text-brand"
|
|
2293
|
+
],
|
|
2294
|
+
className
|
|
2295
|
+
),
|
|
2296
|
+
children: [
|
|
2297
|
+
icon !== void 0 && /* @__PURE__ */ jsx39("span", { className: "shrink-0 [&_svg]:size-4", children: icon }),
|
|
2298
|
+
!collapsed && /* @__PURE__ */ jsx39("span", { className: clsx35("min-w-0 flex-1 truncate font-regular leading-snug", s.label), children: label }),
|
|
2299
|
+
indicator && /* @__PURE__ */ jsx39("span", { className: "absolute -right-px -top-px size-2 rounded-full bg-danger" })
|
|
2300
|
+
]
|
|
2301
|
+
}
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// src/components/chrome/eyebrow-label.tsx
|
|
2306
|
+
import clsx36 from "clsx";
|
|
2307
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2308
|
+
function EyebrowLabel({ children, variant = "uppercase", className }) {
|
|
2309
|
+
return /* @__PURE__ */ jsx40(
|
|
2310
|
+
"p",
|
|
2311
|
+
{
|
|
2312
|
+
className: clsx36(
|
|
2313
|
+
"text-body-tiny font-semibold tracking-wide text-default-secondary",
|
|
2314
|
+
variant === "uppercase" && "uppercase",
|
|
2315
|
+
className
|
|
2316
|
+
),
|
|
2317
|
+
children
|
|
2318
|
+
}
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
// src/components/widgets/widget-header.tsx
|
|
2323
|
+
import clsx38 from "clsx";
|
|
2324
|
+
|
|
2325
|
+
// src/components/widgets/widget-title.tsx
|
|
2326
|
+
import clsx37 from "clsx";
|
|
2327
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
2328
|
+
var sizeStyles5 = {
|
|
2329
|
+
sm: "text-subheading-sm font-semibold leading-none",
|
|
2330
|
+
md: "text-[18px] font-bold leading-normal",
|
|
2331
|
+
lg: "text-subheading font-semibold leading-[1.2]"
|
|
2332
|
+
};
|
|
2333
|
+
function WidgetTitle({ children, size = "sm", className }) {
|
|
2334
|
+
return /* @__PURE__ */ jsx41("h3", { className: clsx37(sizeStyles5[size], "text-default", className), children });
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// src/components/widgets/widget-header.tsx
|
|
2338
|
+
import { jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2339
|
+
var eyebrowStyles = {
|
|
2340
|
+
uppercase: "text-body-tiny font-medium uppercase tracking-[0.66px] text-default-secondary",
|
|
2341
|
+
plain: "text-body-xs leading-[1.4] text-default-secondary"
|
|
2342
|
+
};
|
|
2343
|
+
function WidgetHeader({
|
|
2344
|
+
eyebrow,
|
|
2345
|
+
eyebrowVariant = "uppercase",
|
|
2346
|
+
title,
|
|
2347
|
+
titleSize,
|
|
2348
|
+
subtitle,
|
|
2349
|
+
badge,
|
|
2350
|
+
action,
|
|
2351
|
+
className
|
|
2352
|
+
}) {
|
|
2353
|
+
return /* @__PURE__ */ jsxs30("div", { className: clsx38("flex items-start justify-between gap-2", className), children: [
|
|
2354
|
+
/* @__PURE__ */ jsxs30("div", { className: "min-w-0 flex-1", children: [
|
|
2355
|
+
eyebrow && /* @__PURE__ */ jsx42("p", { className: eyebrowStyles[eyebrowVariant], children: eyebrow }),
|
|
2356
|
+
/* @__PURE__ */ jsx42(WidgetTitle, { size: titleSize, children: title }),
|
|
2357
|
+
subtitle && /* @__PURE__ */ jsx42("p", { className: "mt-1 text-body-xs text-default-secondary leading-snug", children: subtitle })
|
|
2358
|
+
] }),
|
|
2359
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
2360
|
+
badge,
|
|
2361
|
+
action
|
|
2362
|
+
] })
|
|
2363
|
+
] });
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
// src/components/widgets/widget-footer.tsx
|
|
2367
|
+
import clsx39 from "clsx";
|
|
2368
|
+
import { jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2369
|
+
function WidgetFooter({ caption, subcaption, action, className }) {
|
|
2370
|
+
return /* @__PURE__ */ jsxs31("div", { className: clsx39("flex items-center gap-3", className), children: [
|
|
2371
|
+
caption && /* @__PURE__ */ jsxs31("div", { className: "flex items-stretch gap-3 flex-1 min-w-0", children: [
|
|
2372
|
+
/* @__PURE__ */ jsx43("div", { className: "w-0.5 shrink-0 self-stretch rounded-full bg-brand" }),
|
|
2373
|
+
/* @__PURE__ */ jsxs31("div", { className: "min-w-0", children: [
|
|
2374
|
+
/* @__PURE__ */ jsx43("p", { className: "text-body-sm font-medium text-default leading-snug", children: caption }),
|
|
2375
|
+
subcaption && /* @__PURE__ */ jsx43("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: subcaption })
|
|
2376
|
+
] })
|
|
2377
|
+
] }),
|
|
2378
|
+
action && /* @__PURE__ */ jsx43("div", { className: "ml-auto shrink-0", children: action })
|
|
2379
|
+
] });
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
// src/components/stats/stat-tile.tsx
|
|
2383
|
+
import clsx40 from "clsx";
|
|
2384
|
+
import { jsx as jsx44, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2385
|
+
var DOT_TONE = {
|
|
2386
|
+
neutral: "bg-status-dot-neutral",
|
|
2387
|
+
info: "bg-status-dot-info",
|
|
2388
|
+
warning: "bg-status-dot-warning",
|
|
2389
|
+
caution: "bg-status-dot-caution",
|
|
2390
|
+
accent: "bg-status-dot-accent",
|
|
2391
|
+
positive: "bg-status-dot-positive",
|
|
2392
|
+
danger: "bg-status-dot-danger"
|
|
2393
|
+
};
|
|
2394
|
+
function StatTile({ label, value, tone, dotColor, className }) {
|
|
2395
|
+
const showDot = Boolean(tone || dotColor);
|
|
2396
|
+
return /* @__PURE__ */ jsxs32(
|
|
2397
|
+
"div",
|
|
2398
|
+
{
|
|
2399
|
+
className: clsx40(
|
|
2400
|
+
"flex flex-col gap-2 rounded-xl border border-default bg-default p-4",
|
|
2401
|
+
className
|
|
2402
|
+
),
|
|
2403
|
+
children: [
|
|
2404
|
+
/* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1.5", children: [
|
|
2405
|
+
showDot && /* @__PURE__ */ jsx44(
|
|
2406
|
+
"span",
|
|
2407
|
+
{
|
|
2408
|
+
className: clsx40("size-2 shrink-0 rounded-full", tone && DOT_TONE[tone]),
|
|
2409
|
+
style: tone ? void 0 : { backgroundColor: dotColor }
|
|
2410
|
+
}
|
|
2411
|
+
),
|
|
2412
|
+
/* @__PURE__ */ jsx44("span", { className: "text-body-xs font-medium text-default-secondary whitespace-nowrap", children: label })
|
|
2413
|
+
] }),
|
|
2414
|
+
/* @__PURE__ */ jsx44("span", { className: "text-heading font-semibold text-default leading-none", children: value })
|
|
2415
|
+
]
|
|
2416
|
+
}
|
|
2417
|
+
);
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
// src/components/stats/stat-number.tsx
|
|
2421
|
+
import clsx41 from "clsx";
|
|
2422
|
+
import { jsx as jsx45, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2423
|
+
var sizeStyles6 = {
|
|
2424
|
+
sm: "text-subtitle",
|
|
2425
|
+
md: "text-subtitle-lg",
|
|
2426
|
+
lg: "text-title"
|
|
2427
|
+
};
|
|
2428
|
+
var weightStyles = {
|
|
2429
|
+
medium: "font-medium",
|
|
2430
|
+
bold: "font-bold"
|
|
2431
|
+
};
|
|
2432
|
+
function StatNumber({ value, unit, size = "md", weight = "bold", color, className }) {
|
|
2433
|
+
return /* @__PURE__ */ jsxs33(
|
|
2434
|
+
"p",
|
|
2435
|
+
{
|
|
2436
|
+
className: clsx41(sizeStyles6[size], weightStyles[weight], "leading-none", !color && "text-default", className),
|
|
2437
|
+
style: color ? { color } : void 0,
|
|
2438
|
+
children: [
|
|
2439
|
+
value,
|
|
2440
|
+
unit && /* @__PURE__ */ jsx45("span", { className: "ml-1 text-subheading font-medium text-default-secondary", children: unit })
|
|
2441
|
+
]
|
|
2442
|
+
}
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
// src/components/stats/score-value.tsx
|
|
2447
|
+
import clsx42 from "clsx";
|
|
2448
|
+
import { jsx as jsx46, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2449
|
+
var DEFAULT_SCORE_THRESHOLDS = { danger: 80, warning: 65, neutral: 50 };
|
|
2450
|
+
function getScoreTone(score, {
|
|
2451
|
+
direction = "higher-is-worse",
|
|
2452
|
+
thresholds = DEFAULT_SCORE_THRESHOLDS
|
|
2453
|
+
} = {}) {
|
|
2454
|
+
const v = direction === "higher-is-better" ? 100 - score : score;
|
|
2455
|
+
if (v >= thresholds.danger) return "danger";
|
|
2456
|
+
if (v >= thresholds.warning) return "warning";
|
|
2457
|
+
if (v >= thresholds.neutral) return "neutral";
|
|
2458
|
+
return "positive";
|
|
2459
|
+
}
|
|
2460
|
+
var SIZE6 = {
|
|
2461
|
+
sm: "text-body-xs",
|
|
2462
|
+
md: "text-body-sm",
|
|
2463
|
+
lg: "text-subheading-sm",
|
|
2464
|
+
xl: "text-subheading",
|
|
2465
|
+
"2xl": "text-subtitle"
|
|
2466
|
+
};
|
|
2467
|
+
var WEIGHT = {
|
|
2468
|
+
normal: "font-normal",
|
|
2469
|
+
semibold: "font-semibold",
|
|
2470
|
+
bold: "font-bold"
|
|
2471
|
+
};
|
|
2472
|
+
var TONE2 = {
|
|
2473
|
+
brand: "text-brand",
|
|
2474
|
+
positive: "text-positive",
|
|
2475
|
+
warning: "text-warning",
|
|
2476
|
+
danger: "text-danger",
|
|
2477
|
+
neutral: "text-default-secondary",
|
|
2478
|
+
default: "text-default"
|
|
2479
|
+
};
|
|
2480
|
+
function ScoreValue({
|
|
2481
|
+
value,
|
|
2482
|
+
label,
|
|
2483
|
+
size = "md",
|
|
2484
|
+
weight = "bold",
|
|
2485
|
+
tone = "auto",
|
|
2486
|
+
direction = "higher-is-worse",
|
|
2487
|
+
thresholds = DEFAULT_SCORE_THRESHOLDS,
|
|
2488
|
+
className
|
|
2489
|
+
}) {
|
|
2490
|
+
const numeric = typeof value === "number" ? value : Number(value);
|
|
2491
|
+
const resolved = tone === "auto" ? Number.isFinite(numeric) ? getScoreTone(numeric, { direction, thresholds }) : "default" : tone;
|
|
2492
|
+
return /* @__PURE__ */ jsxs34("span", { className: clsx42("inline-flex items-baseline gap-1", className), children: [
|
|
2493
|
+
/* @__PURE__ */ jsx46("span", { className: clsx42(SIZE6[size], WEIGHT[weight], TONE2[resolved]), children: value }),
|
|
2494
|
+
label && /* @__PURE__ */ jsx46("span", { className: "text-body-xs text-default-secondary whitespace-nowrap", children: label })
|
|
2495
|
+
] });
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
// src/components/stats/tile-grid.tsx
|
|
2499
|
+
import clsx43 from "clsx";
|
|
2500
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2501
|
+
var COLUMNS = {
|
|
2502
|
+
sm: {
|
|
2503
|
+
2: "grid-cols-2",
|
|
2504
|
+
3: "grid-cols-2 sm:grid-cols-3",
|
|
2505
|
+
4: "grid-cols-2 sm:grid-cols-4",
|
|
2506
|
+
5: "grid-cols-2 sm:grid-cols-5",
|
|
2507
|
+
6: "grid-cols-2 sm:grid-cols-6"
|
|
2508
|
+
},
|
|
2509
|
+
md: {
|
|
2510
|
+
2: "grid-cols-2",
|
|
2511
|
+
3: "grid-cols-2 md:grid-cols-3",
|
|
2512
|
+
4: "grid-cols-2 md:grid-cols-4",
|
|
2513
|
+
5: "grid-cols-2 md:grid-cols-5",
|
|
2514
|
+
6: "grid-cols-2 sm:grid-cols-3 md:grid-cols-6"
|
|
2515
|
+
},
|
|
2516
|
+
lg: {
|
|
2517
|
+
2: "grid-cols-2",
|
|
2518
|
+
3: "grid-cols-2 lg:grid-cols-3",
|
|
2519
|
+
4: "grid-cols-2 lg:grid-cols-4",
|
|
2520
|
+
5: "grid-cols-2 lg:grid-cols-5",
|
|
2521
|
+
6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6"
|
|
2522
|
+
}
|
|
2523
|
+
};
|
|
2524
|
+
function TileGrid({
|
|
2525
|
+
children,
|
|
2526
|
+
columns = 4,
|
|
2527
|
+
at = "lg",
|
|
2528
|
+
className
|
|
2529
|
+
}) {
|
|
2530
|
+
return /* @__PURE__ */ jsx47("div", { className: clsx43("grid gap-3", COLUMNS[at][columns], className), children });
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
// src/components/charts/chart-tone.ts
|
|
2534
|
+
var CHART_TONE = {
|
|
2535
|
+
brand: "var(--color-background-brand-default)",
|
|
2536
|
+
info: "var(--status-info-dot)",
|
|
2537
|
+
positive: "var(--color-background-positive-default)",
|
|
2538
|
+
warning: "var(--color-background-warning-default)",
|
|
2539
|
+
danger: "var(--color-background-danger-default)",
|
|
2540
|
+
neutral: "var(--color-background-neutral-default)"
|
|
2541
|
+
};
|
|
2542
|
+
var CHART_TRACK = "var(--color-background-default-tertiary)";
|
|
2543
|
+
var CHART_SEQUENCE = ["brand", "info", "positive", "warning", "danger", "neutral"];
|
|
2544
|
+
function resolveChartColor(color, tone, index = 0) {
|
|
2545
|
+
if (color) return color;
|
|
2546
|
+
if (tone) return CHART_TONE[tone];
|
|
2547
|
+
return CHART_TONE[CHART_SEQUENCE[index % CHART_SEQUENCE.length]];
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// src/components/charts/bar-chart.tsx
|
|
2551
|
+
import clsx44 from "clsx";
|
|
2552
|
+
import { jsx as jsx48, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2553
|
+
var SIZE7 = {
|
|
2554
|
+
sm: { band: 14, gap: 6, label: "text-body-tiny" },
|
|
2555
|
+
md: { band: 20, gap: 8, label: "text-body-xs" },
|
|
2556
|
+
lg: { band: 28, gap: 10, label: "text-body-xs" }
|
|
2557
|
+
};
|
|
2558
|
+
function BarChart({
|
|
2559
|
+
categories,
|
|
2560
|
+
series,
|
|
2561
|
+
orientation = "horizontal",
|
|
2562
|
+
stacked = false,
|
|
2563
|
+
size = "md",
|
|
2564
|
+
length = 240,
|
|
2565
|
+
showLabels = true,
|
|
2566
|
+
showValues = false,
|
|
2567
|
+
radius = 3,
|
|
2568
|
+
label,
|
|
2569
|
+
className
|
|
2570
|
+
}) {
|
|
2571
|
+
const { band, gap, label: labelClass2 } = SIZE7[size];
|
|
2572
|
+
if (categories.length === 0 || series.length === 0) return null;
|
|
2573
|
+
const perCategory = stacked ? band : band * series.length + gap * (series.length - 1);
|
|
2574
|
+
const categoryTotals = categories.map(
|
|
2575
|
+
(_, ci) => stacked ? series.reduce((sum, s) => sum + Math.max(0, s.values[ci] ?? 0), 0) : Math.max(...series.map((s) => Math.max(0, s.values[ci] ?? 0)))
|
|
2576
|
+
);
|
|
2577
|
+
const max = Math.max(...categoryTotals, 1);
|
|
2578
|
+
const horizontal = orientation === "horizontal";
|
|
2579
|
+
return /* @__PURE__ */ jsx48(
|
|
2580
|
+
"div",
|
|
2581
|
+
{
|
|
2582
|
+
className: clsx44("flex w-full min-w-0", horizontal ? "flex-col gap-2" : "flex-row items-end gap-3", className),
|
|
2583
|
+
role: label ? "img" : void 0,
|
|
2584
|
+
"aria-label": label,
|
|
2585
|
+
children: categories.map((category, ci) => {
|
|
2586
|
+
const bars = series.map((s, si) => ({
|
|
2587
|
+
key: s.label,
|
|
2588
|
+
value: Math.max(0, s.values[ci] ?? 0),
|
|
2589
|
+
color: resolveChartColor(s.color, s.tone, si)
|
|
2590
|
+
}));
|
|
2591
|
+
return /* @__PURE__ */ jsxs35(
|
|
2592
|
+
"div",
|
|
2593
|
+
{
|
|
2594
|
+
className: clsx44("flex min-w-0", horizontal ? "flex-col gap-1" : "h-full flex-col justify-end gap-1.5"),
|
|
2595
|
+
style: horizontal ? void 0 : { width: perCategory },
|
|
2596
|
+
children: [
|
|
2597
|
+
showLabels && horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("truncate text-default-secondary", labelClass2), children: category }),
|
|
2598
|
+
/* @__PURE__ */ jsxs35(
|
|
2599
|
+
"div",
|
|
2600
|
+
{
|
|
2601
|
+
className: clsx44("flex", horizontal ? "items-center gap-2" : "w-full flex-1 items-end justify-center"),
|
|
2602
|
+
style: horizontal ? void 0 : { height: length },
|
|
2603
|
+
children: [
|
|
2604
|
+
/* @__PURE__ */ jsx48(
|
|
2605
|
+
"div",
|
|
2606
|
+
{
|
|
2607
|
+
className: clsx44("flex min-w-0", stacked ? "gap-0" : ""),
|
|
2608
|
+
style: horizontal ? { width: length, flexDirection: stacked ? "row" : "column", gap: stacked ? 0 : gap } : {
|
|
2609
|
+
height: "100%",
|
|
2610
|
+
width: perCategory,
|
|
2611
|
+
flexDirection: stacked ? "column-reverse" : "row",
|
|
2612
|
+
alignItems: "flex-end",
|
|
2613
|
+
gap: stacked ? 0 : gap
|
|
2614
|
+
},
|
|
2615
|
+
children: bars.map((bar) => {
|
|
2616
|
+
const extent = `${bar.value / max * 100}%`;
|
|
2617
|
+
return /* @__PURE__ */ jsx48(
|
|
2618
|
+
"div",
|
|
2619
|
+
{
|
|
2620
|
+
title: `${category} \xB7 ${bar.key}: ${bar.value}`,
|
|
2621
|
+
className: "transition-all",
|
|
2622
|
+
style: {
|
|
2623
|
+
backgroundColor: bar.color,
|
|
2624
|
+
borderRadius: radius,
|
|
2625
|
+
...horizontal ? { width: extent, height: stacked ? band : band } : { height: extent, width: stacked ? perCategory : band }
|
|
2626
|
+
}
|
|
2627
|
+
},
|
|
2628
|
+
bar.key
|
|
2629
|
+
);
|
|
2630
|
+
})
|
|
2631
|
+
}
|
|
2632
|
+
),
|
|
2633
|
+
showValues && horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("shrink-0 tabular-nums text-default-secondary", labelClass2), children: categoryTotals[ci] })
|
|
2634
|
+
]
|
|
2635
|
+
}
|
|
2636
|
+
),
|
|
2637
|
+
showLabels && !horizontal && /* @__PURE__ */ jsx48("span", { className: clsx44("truncate text-center text-default-secondary", labelClass2), children: category })
|
|
2638
|
+
]
|
|
2639
|
+
},
|
|
2640
|
+
category
|
|
2641
|
+
);
|
|
2642
|
+
})
|
|
2643
|
+
}
|
|
2644
|
+
);
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
// src/components/charts/donut-chart.tsx
|
|
2648
|
+
import clsx45 from "clsx";
|
|
2649
|
+
import { jsx as jsx49, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2650
|
+
var SIZE8 = {
|
|
2651
|
+
sm: { box: 88, thickness: 10 },
|
|
2652
|
+
md: { box: 128, thickness: 14 },
|
|
2653
|
+
lg: { box: 180, thickness: 20 }
|
|
2654
|
+
};
|
|
2655
|
+
function DonutChart({
|
|
2656
|
+
segments,
|
|
2657
|
+
size = "md",
|
|
2658
|
+
thickness,
|
|
2659
|
+
centerValue,
|
|
2660
|
+
centerLabel,
|
|
2661
|
+
gap = 2,
|
|
2662
|
+
label,
|
|
2663
|
+
className
|
|
2664
|
+
}) {
|
|
2665
|
+
const { box, thickness: presetThickness } = SIZE8[size];
|
|
2666
|
+
const ring = thickness ?? presetThickness;
|
|
2667
|
+
const radius = (box - ring) / 2;
|
|
2668
|
+
const circumference = 2 * Math.PI * radius;
|
|
2669
|
+
const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);
|
|
2670
|
+
const visible = segments.filter((s) => s.value > 0);
|
|
2671
|
+
const gapLength = visible.length > 1 ? gap / 360 * circumference : 0;
|
|
2672
|
+
let offset = 0;
|
|
2673
|
+
return /* @__PURE__ */ jsxs36("div", { className: clsx45("relative inline-flex shrink-0 items-center justify-center", className), children: [
|
|
2674
|
+
/* @__PURE__ */ jsxs36(
|
|
2675
|
+
"svg",
|
|
2676
|
+
{
|
|
2677
|
+
width: box,
|
|
2678
|
+
height: box,
|
|
2679
|
+
viewBox: `0 0 ${box} ${box}`,
|
|
2680
|
+
role: label ? "img" : void 0,
|
|
2681
|
+
"aria-label": label,
|
|
2682
|
+
"aria-hidden": label ? void 0 : true,
|
|
2683
|
+
className: "block -rotate-90",
|
|
2684
|
+
children: [
|
|
2685
|
+
/* @__PURE__ */ jsx49("circle", { cx: box / 2, cy: box / 2, r: radius, fill: "none", stroke: CHART_TRACK, strokeWidth: ring }),
|
|
2686
|
+
total > 0 && segments.map((segment, i) => {
|
|
2687
|
+
const fraction = Math.max(0, segment.value) / total;
|
|
2688
|
+
const length = Math.max(0, fraction * circumference - gapLength);
|
|
2689
|
+
const dash = `${length} ${circumference - length}`;
|
|
2690
|
+
const thisOffset = offset;
|
|
2691
|
+
offset += fraction * circumference;
|
|
2692
|
+
if (segment.value <= 0) return null;
|
|
2693
|
+
return /* @__PURE__ */ jsx49(
|
|
2694
|
+
"circle",
|
|
2695
|
+
{
|
|
2696
|
+
cx: box / 2,
|
|
2697
|
+
cy: box / 2,
|
|
2698
|
+
r: radius,
|
|
2699
|
+
fill: "none",
|
|
2700
|
+
stroke: resolveChartColor(segment.color, segment.tone, i),
|
|
2701
|
+
strokeWidth: ring,
|
|
2702
|
+
strokeDasharray: dash,
|
|
2703
|
+
strokeDashoffset: -thisOffset,
|
|
2704
|
+
strokeLinecap: "butt"
|
|
2705
|
+
},
|
|
2706
|
+
segment.label
|
|
2707
|
+
);
|
|
2708
|
+
})
|
|
2709
|
+
]
|
|
2710
|
+
}
|
|
2711
|
+
),
|
|
2712
|
+
(centerValue != null || centerLabel != null) && /* @__PURE__ */ jsxs36("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center", children: [
|
|
2713
|
+
centerValue != null && /* @__PURE__ */ jsx49("span", { className: "text-subheading-sm font-bold leading-none text-default", children: centerValue }),
|
|
2714
|
+
centerLabel != null && /* @__PURE__ */ jsx49("span", { className: "mt-0.5 text-body-tiny text-default-secondary", children: centerLabel })
|
|
2715
|
+
] })
|
|
2716
|
+
] });
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
// src/components/charts/radial-gauge.tsx
|
|
2720
|
+
import clsx46 from "clsx";
|
|
2721
|
+
import { jsx as jsx50, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2722
|
+
var SIZE9 = {
|
|
2723
|
+
sm: { box: 72, thickness: 8, value: "text-body-sm" },
|
|
2724
|
+
md: { box: 104, thickness: 11, value: "text-subheading-sm" },
|
|
2725
|
+
lg: { box: 148, thickness: 15, value: "text-subheading" }
|
|
2726
|
+
};
|
|
2727
|
+
function RadialGauge({
|
|
2728
|
+
value,
|
|
2729
|
+
max = 100,
|
|
2730
|
+
size = "md",
|
|
2731
|
+
tone = "brand",
|
|
2732
|
+
color,
|
|
2733
|
+
thickness,
|
|
2734
|
+
sweep = 270,
|
|
2735
|
+
children,
|
|
2736
|
+
centerLabel,
|
|
2737
|
+
label,
|
|
2738
|
+
className
|
|
2739
|
+
}) {
|
|
2740
|
+
const preset = SIZE9[size];
|
|
2741
|
+
const box = preset.box;
|
|
2742
|
+
const ring = thickness ?? preset.thickness;
|
|
2743
|
+
const radius = (box - ring) / 2;
|
|
2744
|
+
const circumference = 2 * Math.PI * radius;
|
|
2745
|
+
const clampedSweep = Math.min(360, Math.max(1, sweep));
|
|
2746
|
+
const arc = clampedSweep / 360 * circumference;
|
|
2747
|
+
const fraction = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;
|
|
2748
|
+
const stroke = resolveChartColor(color, tone);
|
|
2749
|
+
const rotation = -90 + (360 - clampedSweep) / 2;
|
|
2750
|
+
return /* @__PURE__ */ jsxs37("div", { className: clsx46("relative inline-flex shrink-0 items-center justify-center", className), children: [
|
|
2751
|
+
/* @__PURE__ */ jsxs37(
|
|
2752
|
+
"svg",
|
|
2753
|
+
{
|
|
2754
|
+
width: box,
|
|
2755
|
+
height: box,
|
|
2756
|
+
viewBox: `0 0 ${box} ${box}`,
|
|
2757
|
+
role: label ? "img" : void 0,
|
|
2758
|
+
"aria-label": label,
|
|
2759
|
+
"aria-hidden": label ? void 0 : true,
|
|
2760
|
+
className: "block",
|
|
2761
|
+
style: { transform: `rotate(${rotation}deg)` },
|
|
2762
|
+
children: [
|
|
2763
|
+
/* @__PURE__ */ jsx50(
|
|
2764
|
+
"circle",
|
|
2765
|
+
{
|
|
2766
|
+
cx: box / 2,
|
|
2767
|
+
cy: box / 2,
|
|
2768
|
+
r: radius,
|
|
2769
|
+
fill: "none",
|
|
2770
|
+
stroke: CHART_TRACK,
|
|
2771
|
+
strokeWidth: ring,
|
|
2772
|
+
strokeDasharray: `${arc} ${circumference - arc}`,
|
|
2773
|
+
strokeLinecap: "round"
|
|
2774
|
+
}
|
|
2775
|
+
),
|
|
2776
|
+
/* @__PURE__ */ jsx50(
|
|
2777
|
+
"circle",
|
|
2778
|
+
{
|
|
2779
|
+
cx: box / 2,
|
|
2780
|
+
cy: box / 2,
|
|
2781
|
+
r: radius,
|
|
2782
|
+
fill: "none",
|
|
2783
|
+
stroke,
|
|
2784
|
+
strokeWidth: ring,
|
|
2785
|
+
strokeDasharray: `${arc * fraction} ${circumference - arc * fraction}`,
|
|
2786
|
+
strokeLinecap: "round",
|
|
2787
|
+
className: "transition-all"
|
|
2788
|
+
}
|
|
2789
|
+
)
|
|
2790
|
+
]
|
|
2791
|
+
}
|
|
2792
|
+
),
|
|
2793
|
+
/* @__PURE__ */ jsxs37("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center", children: [
|
|
2794
|
+
children === void 0 ? /* @__PURE__ */ jsx50("span", { className: clsx46("font-bold leading-none text-default", preset.value), children: value }) : children,
|
|
2795
|
+
centerLabel != null && /* @__PURE__ */ jsx50("span", { className: "mt-0.5 text-body-tiny text-default-secondary", children: centerLabel })
|
|
2796
|
+
] })
|
|
2797
|
+
] });
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
// src/components/charts/sparkline.tsx
|
|
2801
|
+
import { useId } from "react";
|
|
2802
|
+
import clsx47 from "clsx";
|
|
2803
|
+
import { Fragment as Fragment3, jsx as jsx51, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2804
|
+
var SIZE10 = {
|
|
2805
|
+
sm: { width: 80, height: 24 },
|
|
2806
|
+
md: { width: 120, height: 36 },
|
|
2807
|
+
lg: { width: 200, height: 56 }
|
|
2808
|
+
};
|
|
2809
|
+
function Sparkline({
|
|
2810
|
+
data,
|
|
2811
|
+
variant = "line",
|
|
2812
|
+
tone = "brand",
|
|
2813
|
+
color,
|
|
2814
|
+
size = "md",
|
|
2815
|
+
width,
|
|
2816
|
+
height,
|
|
2817
|
+
strokeWidth = 1.5,
|
|
2818
|
+
showEndDot = false,
|
|
2819
|
+
label,
|
|
2820
|
+
className
|
|
2821
|
+
}) {
|
|
2822
|
+
const gradientId = useId();
|
|
2823
|
+
if (data.length < 2) return null;
|
|
2824
|
+
const w = width ?? SIZE10[size].width;
|
|
2825
|
+
const h = height ?? SIZE10[size].height;
|
|
2826
|
+
const stroke = resolveChartColor(color, tone);
|
|
2827
|
+
const min = Math.min(...data);
|
|
2828
|
+
const max = Math.max(...data);
|
|
2829
|
+
const range = max - min || 1;
|
|
2830
|
+
const pad = strokeWidth;
|
|
2831
|
+
const innerH = h - pad * 2;
|
|
2832
|
+
const innerW = w - pad * 2;
|
|
2833
|
+
const coords = data.map((v, i) => ({
|
|
2834
|
+
x: pad + i / (data.length - 1) * innerW,
|
|
2835
|
+
y: pad + innerH - (v - min) / range * innerH
|
|
2836
|
+
}));
|
|
2837
|
+
const points = coords.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
|
|
2838
|
+
const areaPath = `M ${points.split(" ").join(" L ")} L ${coords[coords.length - 1].x.toFixed(2)},${h} L ${coords[0].x.toFixed(2)},${h} Z`;
|
|
2839
|
+
const last = coords[coords.length - 1];
|
|
2840
|
+
return /* @__PURE__ */ jsxs38(
|
|
2841
|
+
"svg",
|
|
2842
|
+
{
|
|
2843
|
+
width: w,
|
|
2844
|
+
height: h,
|
|
2845
|
+
viewBox: `0 0 ${w} ${h}`,
|
|
2846
|
+
fill: "none",
|
|
2847
|
+
role: label ? "img" : void 0,
|
|
2848
|
+
"aria-label": label,
|
|
2849
|
+
"aria-hidden": label ? void 0 : true,
|
|
2850
|
+
className: clsx47("block shrink-0", className),
|
|
2851
|
+
children: [
|
|
2852
|
+
variant === "area" && /* @__PURE__ */ jsxs38(Fragment3, { children: [
|
|
2853
|
+
/* @__PURE__ */ jsx51("defs", { children: /* @__PURE__ */ jsxs38("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
2854
|
+
/* @__PURE__ */ jsx51("stop", { offset: "0%", stopColor: stroke, stopOpacity: 0.24 }),
|
|
2855
|
+
/* @__PURE__ */ jsx51("stop", { offset: "100%", stopColor: stroke, stopOpacity: 0 })
|
|
2856
|
+
] }) }),
|
|
2857
|
+
/* @__PURE__ */ jsx51("path", { d: areaPath, fill: `url(#${gradientId})` })
|
|
2858
|
+
] }),
|
|
2859
|
+
/* @__PURE__ */ jsx51(
|
|
2860
|
+
"polyline",
|
|
2861
|
+
{
|
|
2862
|
+
points,
|
|
2863
|
+
stroke,
|
|
2864
|
+
strokeWidth,
|
|
2865
|
+
strokeLinecap: "round",
|
|
2866
|
+
strokeLinejoin: "round",
|
|
2867
|
+
fill: "none"
|
|
2868
|
+
}
|
|
2869
|
+
),
|
|
2870
|
+
showEndDot && /* @__PURE__ */ jsx51("circle", { cx: last.x, cy: last.y, r: strokeWidth * 1.6, fill: stroke, stroke: CHART_TONE.neutral, strokeWidth: 0 })
|
|
2871
|
+
]
|
|
2872
|
+
}
|
|
2873
|
+
);
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
// src/components/charts/mini-bar-chart.tsx
|
|
2877
|
+
import clsx48 from "clsx";
|
|
2878
|
+
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
2879
|
+
var SIZE11 = {
|
|
2880
|
+
sm: { width: 80, height: 32, gap: 2 },
|
|
2881
|
+
md: { width: 120, height: 48, gap: 3 },
|
|
2882
|
+
lg: { width: 200, height: 72, gap: 4 }
|
|
2883
|
+
};
|
|
2884
|
+
function MiniBarChart({
|
|
2885
|
+
bars,
|
|
2886
|
+
tone = "brand",
|
|
2887
|
+
color,
|
|
2888
|
+
restColor = CHART_TRACK,
|
|
2889
|
+
highlight = -1,
|
|
2890
|
+
size = "md",
|
|
2891
|
+
width,
|
|
2892
|
+
height,
|
|
2893
|
+
gap,
|
|
2894
|
+
orientation = "vertical",
|
|
2895
|
+
radius = 2,
|
|
2896
|
+
label,
|
|
2897
|
+
className
|
|
2898
|
+
}) {
|
|
2899
|
+
if (bars.length === 0) return null;
|
|
2900
|
+
const preset = SIZE11[size];
|
|
2901
|
+
const w = width ?? preset.width;
|
|
2902
|
+
const h = height ?? preset.height;
|
|
2903
|
+
const g = gap ?? preset.gap;
|
|
2904
|
+
const fill = resolveChartColor(color, tone);
|
|
2905
|
+
const highlighted = new Set(
|
|
2906
|
+
(Array.isArray(highlight) ? highlight : [highlight]).map((i) => i < 0 ? bars.length + i : i)
|
|
2907
|
+
);
|
|
2908
|
+
const max = Math.max(...bars) || 1;
|
|
2909
|
+
const vertical = orientation === "vertical";
|
|
2910
|
+
const span = vertical ? w : h;
|
|
2911
|
+
const extent = vertical ? h : w;
|
|
2912
|
+
const barThickness = (span - g * (bars.length - 1)) / bars.length;
|
|
2913
|
+
return /* @__PURE__ */ jsx52(
|
|
2914
|
+
"svg",
|
|
2915
|
+
{
|
|
2916
|
+
width: w,
|
|
2917
|
+
height: h,
|
|
2918
|
+
viewBox: `0 0 ${w} ${h}`,
|
|
2919
|
+
fill: "none",
|
|
2920
|
+
role: label ? "img" : void 0,
|
|
2921
|
+
"aria-label": label,
|
|
2922
|
+
"aria-hidden": label ? void 0 : true,
|
|
2923
|
+
className: clsx48("block shrink-0", className),
|
|
2924
|
+
children: bars.map((v, i) => {
|
|
2925
|
+
const magnitude = Math.max(2, v / max * extent);
|
|
2926
|
+
const offset = i * (barThickness + g);
|
|
2927
|
+
return /* @__PURE__ */ jsx52(
|
|
2928
|
+
"rect",
|
|
2929
|
+
{
|
|
2930
|
+
x: (vertical ? offset : 0).toFixed(2),
|
|
2931
|
+
y: (vertical ? extent - magnitude : offset).toFixed(2),
|
|
2932
|
+
width: (vertical ? barThickness : magnitude).toFixed(2),
|
|
2933
|
+
height: (vertical ? magnitude : barThickness).toFixed(2),
|
|
2934
|
+
fill: highlighted.has(i) ? fill : restColor,
|
|
2935
|
+
rx: radius
|
|
2936
|
+
},
|
|
2937
|
+
i
|
|
2938
|
+
);
|
|
2939
|
+
})
|
|
2940
|
+
}
|
|
2941
|
+
);
|
|
2942
|
+
}
|
|
2943
|
+
|
|
2944
|
+
// src/components/charts/chart-legend.tsx
|
|
2945
|
+
import clsx50 from "clsx";
|
|
2946
|
+
|
|
2947
|
+
// src/components/charts/legend-dot.tsx
|
|
2948
|
+
import clsx49 from "clsx";
|
|
2949
|
+
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
2950
|
+
var SHAPE = {
|
|
2951
|
+
dot: { sm: "size-1.5 rounded-full", md: "size-2 rounded-full" },
|
|
2952
|
+
square: { sm: "size-1.5 rounded-[2px]", md: "size-2 rounded-[3px]" },
|
|
2953
|
+
line: { sm: "h-0.5 w-3 rounded-full", md: "h-0.5 w-4 rounded-full" }
|
|
2954
|
+
};
|
|
2955
|
+
function LegendDot({ tone, color, size = "md", shape = "dot", className }) {
|
|
2956
|
+
return /* @__PURE__ */ jsx53(
|
|
2957
|
+
"span",
|
|
2958
|
+
{
|
|
2959
|
+
className: clsx49("inline-block shrink-0", SHAPE[shape][size], className),
|
|
2960
|
+
style: { backgroundColor: resolveChartColor(color, tone) },
|
|
2961
|
+
"aria-hidden": true
|
|
2962
|
+
}
|
|
2963
|
+
);
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
// src/components/charts/chart-legend.tsx
|
|
2967
|
+
import { jsx as jsx54, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
2968
|
+
function ChartLegend({
|
|
2969
|
+
items,
|
|
2970
|
+
orientation = "vertical",
|
|
2971
|
+
size = "md",
|
|
2972
|
+
shape = "dot",
|
|
2973
|
+
className
|
|
2974
|
+
}) {
|
|
2975
|
+
const horizontal = orientation === "horizontal";
|
|
2976
|
+
return /* @__PURE__ */ jsx54(
|
|
2977
|
+
"div",
|
|
2978
|
+
{
|
|
2979
|
+
className: clsx50(
|
|
2980
|
+
horizontal ? "flex flex-wrap items-center gap-x-4 gap-y-2" : "flex flex-col gap-3",
|
|
2981
|
+
className
|
|
2982
|
+
),
|
|
2983
|
+
children: items.map((item, i) => /* @__PURE__ */ jsxs39(
|
|
2984
|
+
"div",
|
|
2985
|
+
{
|
|
2986
|
+
className: clsx50("flex items-center gap-2", horizontal ? "min-w-0" : "justify-between"),
|
|
2987
|
+
children: [
|
|
2988
|
+
/* @__PURE__ */ jsxs39("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2989
|
+
/* @__PURE__ */ jsx54(LegendDot, { color: resolveChartColor(item.color, item.tone, i), size, shape }),
|
|
2990
|
+
/* @__PURE__ */ jsx54("span", { className: "truncate text-body-xs text-default-secondary", children: item.label })
|
|
2991
|
+
] }),
|
|
2992
|
+
item.count != null && /* @__PURE__ */ jsx54("span", { className: "shrink-0 text-body-xs font-semibold tabular-nums text-default", children: item.count })
|
|
2993
|
+
]
|
|
2994
|
+
},
|
|
2995
|
+
item.label
|
|
2996
|
+
))
|
|
2997
|
+
}
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
// src/components/charts/trend-label.tsx
|
|
3002
|
+
import clsx51 from "clsx";
|
|
3003
|
+
import { LuTrendingDown, LuTrendingUp } from "react-icons/lu";
|
|
3004
|
+
import { jsx as jsx55, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3005
|
+
var SIZE12 = {
|
|
3006
|
+
sm: "text-body-xs",
|
|
3007
|
+
md: "text-body-sm",
|
|
3008
|
+
lg: "text-subheading-sm"
|
|
3009
|
+
};
|
|
3010
|
+
var ICON_SIZE = {
|
|
3011
|
+
sm: "size-3",
|
|
3012
|
+
md: "size-3.5",
|
|
3013
|
+
lg: "size-4"
|
|
3014
|
+
};
|
|
3015
|
+
var weightBySize = {
|
|
3016
|
+
sm: "semibold",
|
|
3017
|
+
md: "semibold",
|
|
3018
|
+
lg: "bold"
|
|
3019
|
+
};
|
|
3020
|
+
var WEIGHT2 = {
|
|
3021
|
+
semibold: "font-semibold",
|
|
3022
|
+
bold: "font-bold"
|
|
3023
|
+
};
|
|
3024
|
+
function TrendLabel({
|
|
3025
|
+
value,
|
|
3026
|
+
suffix = "%",
|
|
3027
|
+
size = "md",
|
|
3028
|
+
weight,
|
|
3029
|
+
direction = "up-is-good",
|
|
3030
|
+
showArrow = true,
|
|
3031
|
+
color,
|
|
3032
|
+
className
|
|
3033
|
+
}) {
|
|
3034
|
+
const rising = value > 0;
|
|
3035
|
+
const flat = value === 0;
|
|
3036
|
+
const good = direction === "up-is-good" ? rising : !rising;
|
|
3037
|
+
const Arrow = rising ? LuTrendingUp : LuTrendingDown;
|
|
3038
|
+
return /* @__PURE__ */ jsxs40(
|
|
3039
|
+
"span",
|
|
3040
|
+
{
|
|
3041
|
+
className: clsx51(
|
|
3042
|
+
"inline-flex items-center gap-1 whitespace-nowrap",
|
|
3043
|
+
SIZE12[size],
|
|
3044
|
+
WEIGHT2[weight ?? weightBySize[size]],
|
|
3045
|
+
!color && (flat ? "text-default-secondary" : good ? "text-positive" : "text-danger"),
|
|
3046
|
+
className
|
|
3047
|
+
),
|
|
3048
|
+
style: color ? { color } : void 0,
|
|
3049
|
+
children: [
|
|
3050
|
+
showArrow && !flat && /* @__PURE__ */ jsx55(Arrow, { className: clsx51("shrink-0", ICON_SIZE[size]), "aria-hidden": true }),
|
|
3051
|
+
rising ? "+" : "",
|
|
3052
|
+
value,
|
|
3053
|
+
suffix
|
|
3054
|
+
]
|
|
3055
|
+
}
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3059
|
+
// src/components/lists/list-row.tsx
|
|
3060
|
+
import clsx52 from "clsx";
|
|
3061
|
+
import { jsx as jsx56, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3062
|
+
var DENSITY = {
|
|
3063
|
+
default: {
|
|
3064
|
+
pad: "py-4",
|
|
3065
|
+
gap: "gap-3",
|
|
3066
|
+
title: "text-body-sm font-semibold text-default",
|
|
3067
|
+
description: "text-body-xs text-default-secondary"
|
|
3068
|
+
},
|
|
3069
|
+
compact: {
|
|
3070
|
+
pad: "py-2.5",
|
|
3071
|
+
gap: "gap-2",
|
|
3072
|
+
title: "text-body-xs font-semibold text-default",
|
|
3073
|
+
description: "text-body-tiny text-default-secondary"
|
|
3074
|
+
}
|
|
3075
|
+
};
|
|
3076
|
+
var DIVIDER = {
|
|
3077
|
+
none: "",
|
|
3078
|
+
top: "border-t border-default",
|
|
3079
|
+
bottom: "border-b border-default"
|
|
3080
|
+
};
|
|
3081
|
+
function ListRow({
|
|
3082
|
+
leading,
|
|
3083
|
+
title,
|
|
3084
|
+
titleMeta,
|
|
3085
|
+
description,
|
|
3086
|
+
meta,
|
|
3087
|
+
trailing,
|
|
3088
|
+
footer,
|
|
3089
|
+
density = "default",
|
|
3090
|
+
divider = "none",
|
|
3091
|
+
as: Tag = "div",
|
|
3092
|
+
onClick,
|
|
3093
|
+
className
|
|
3094
|
+
}) {
|
|
3095
|
+
const d = DENSITY[density];
|
|
3096
|
+
const hasTitleLine = Boolean(leading || title != null || titleMeta || meta);
|
|
3097
|
+
return /* @__PURE__ */ jsxs41(
|
|
3098
|
+
Tag,
|
|
3099
|
+
{
|
|
3100
|
+
className: clsx52(
|
|
3101
|
+
"flex w-full items-start",
|
|
3102
|
+
d.pad,
|
|
3103
|
+
DIVIDER[divider],
|
|
3104
|
+
onClick && "cursor-pointer rounded-lg transition-colors hover:bg-default-secondary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand",
|
|
3105
|
+
className
|
|
3106
|
+
),
|
|
3107
|
+
onClick,
|
|
3108
|
+
role: onClick ? "button" : void 0,
|
|
3109
|
+
tabIndex: onClick ? 0 : void 0,
|
|
3110
|
+
onKeyDown: onClick ? (e) => {
|
|
3111
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3112
|
+
e.preventDefault();
|
|
3113
|
+
onClick();
|
|
3114
|
+
}
|
|
3115
|
+
} : void 0,
|
|
3116
|
+
children: [
|
|
3117
|
+
/* @__PURE__ */ jsxs41("div", { className: clsx52("flex min-w-0 flex-1 flex-col", d.gap), children: [
|
|
3118
|
+
hasTitleLine && /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3119
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
3120
|
+
leading,
|
|
3121
|
+
title != null && /* @__PURE__ */ jsx56("span", { className: clsx52("truncate", d.title), children: title }),
|
|
3122
|
+
titleMeta && /* @__PURE__ */ jsx56("span", { className: "shrink-0", children: titleMeta })
|
|
3123
|
+
] }),
|
|
3124
|
+
meta && /* @__PURE__ */ jsx56("span", { className: "shrink-0", children: meta })
|
|
3125
|
+
] }),
|
|
3126
|
+
description && /* @__PURE__ */ jsx56("p", { className: d.description, children: description }),
|
|
3127
|
+
footer
|
|
3128
|
+
] }),
|
|
3129
|
+
trailing && /* @__PURE__ */ jsx56("div", { className: "ml-3 flex shrink-0 items-center self-center", children: trailing })
|
|
3130
|
+
]
|
|
3131
|
+
}
|
|
3132
|
+
);
|
|
3133
|
+
}
|
|
3134
|
+
|
|
3135
|
+
// src/components/lists/file-row.tsx
|
|
3136
|
+
import clsx53 from "clsx";
|
|
3137
|
+
import { jsx as jsx57, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3138
|
+
function FileTypeBadge({ type }) {
|
|
3139
|
+
return /* @__PURE__ */ jsx57("span", { className: "flex size-[34px] shrink-0 items-center justify-center rounded-md bg-brand-tertiary text-body-tiny font-semibold text-brand", children: type });
|
|
3140
|
+
}
|
|
3141
|
+
function FileRow({
|
|
3142
|
+
name,
|
|
3143
|
+
detail,
|
|
3144
|
+
fileType,
|
|
3145
|
+
leading,
|
|
3146
|
+
onDownload,
|
|
3147
|
+
downloadLabel = "Download",
|
|
3148
|
+
actions,
|
|
3149
|
+
className
|
|
3150
|
+
}) {
|
|
3151
|
+
const lead = leading ?? (fileType ? /* @__PURE__ */ jsx57(FileTypeBadge, { type: fileType }) : null);
|
|
3152
|
+
return /* @__PURE__ */ jsxs42(
|
|
3153
|
+
"div",
|
|
3154
|
+
{
|
|
3155
|
+
className: clsx53(
|
|
3156
|
+
"flex items-center gap-3 rounded-lg border border-default bg-default px-3 py-2.5",
|
|
3157
|
+
className
|
|
3158
|
+
),
|
|
3159
|
+
children: [
|
|
3160
|
+
lead,
|
|
3161
|
+
/* @__PURE__ */ jsxs42("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
3162
|
+
/* @__PURE__ */ jsx57("span", { className: "truncate text-body-sm font-medium text-default", children: name }),
|
|
3163
|
+
detail && /* @__PURE__ */ jsx57("span", { className: "text-body-xs text-default-secondary", children: detail })
|
|
3164
|
+
] }),
|
|
3165
|
+
(onDownload || actions) && /* @__PURE__ */ jsxs42("div", { className: "flex shrink-0 items-center gap-3", children: [
|
|
3166
|
+
onDownload && /* @__PURE__ */ jsx57(
|
|
3167
|
+
"button",
|
|
3168
|
+
{
|
|
3169
|
+
type: "button",
|
|
3170
|
+
onClick: onDownload,
|
|
3171
|
+
className: "text-body-xs font-medium text-brand hover:underline",
|
|
3172
|
+
children: downloadLabel
|
|
3173
|
+
}
|
|
3174
|
+
),
|
|
3175
|
+
actions
|
|
3176
|
+
] })
|
|
3177
|
+
]
|
|
3178
|
+
}
|
|
3179
|
+
);
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
// src/components/lists/scored-row.tsx
|
|
3183
|
+
import clsx54 from "clsx";
|
|
3184
|
+
import { jsx as jsx58, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
3185
|
+
var GAP2 = {
|
|
3186
|
+
sm: "gap-2",
|
|
3187
|
+
md: "gap-3",
|
|
3188
|
+
lg: "gap-5",
|
|
3189
|
+
xl: "gap-12"
|
|
3190
|
+
};
|
|
3191
|
+
var ALIGN = {
|
|
3192
|
+
center: "items-center",
|
|
3193
|
+
end: "items-end"
|
|
3194
|
+
};
|
|
3195
|
+
function ScoredRow({
|
|
3196
|
+
leading,
|
|
3197
|
+
title,
|
|
3198
|
+
subtitle,
|
|
3199
|
+
aside,
|
|
3200
|
+
meter,
|
|
3201
|
+
trailing,
|
|
3202
|
+
titleWidth,
|
|
3203
|
+
asideWidth,
|
|
3204
|
+
meterWidth,
|
|
3205
|
+
trailingWidth,
|
|
3206
|
+
gap = "md",
|
|
3207
|
+
leadingGap,
|
|
3208
|
+
align = "center",
|
|
3209
|
+
className
|
|
3210
|
+
}) {
|
|
3211
|
+
return /* @__PURE__ */ jsxs43("div", { className: clsx54("flex w-full", ALIGN[align], GAP2[gap], className), children: [
|
|
3212
|
+
/* @__PURE__ */ jsxs43(
|
|
3213
|
+
"div",
|
|
3214
|
+
{
|
|
3215
|
+
className: clsx54(
|
|
3216
|
+
"flex min-w-0",
|
|
3217
|
+
ALIGN[align],
|
|
3218
|
+
GAP2[leadingGap ?? gap],
|
|
3219
|
+
titleWidth ? "shrink-0" : "flex-1"
|
|
3220
|
+
),
|
|
3221
|
+
style: titleWidth ? { width: titleWidth } : void 0,
|
|
3222
|
+
children: [
|
|
3223
|
+
leading,
|
|
3224
|
+
/* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
|
|
3225
|
+
/* @__PURE__ */ jsx58("p", { className: "truncate text-body-sm font-medium leading-none text-default", children: title }),
|
|
3226
|
+
subtitle && /* @__PURE__ */ jsx58("p", { className: "mt-0.5 truncate text-body-xs text-default-secondary", children: subtitle })
|
|
3227
|
+
] })
|
|
3228
|
+
]
|
|
3229
|
+
}
|
|
3230
|
+
),
|
|
3231
|
+
aside && /* @__PURE__ */ jsx58(
|
|
3232
|
+
"div",
|
|
3233
|
+
{
|
|
3234
|
+
className: clsx54("min-w-0", asideWidth ? "shrink-0" : "flex-1"),
|
|
3235
|
+
style: asideWidth ? { width: asideWidth } : void 0,
|
|
3236
|
+
children: aside
|
|
3237
|
+
}
|
|
3238
|
+
),
|
|
3239
|
+
meter && /* @__PURE__ */ jsx58(
|
|
3240
|
+
"div",
|
|
3241
|
+
{
|
|
3242
|
+
className: clsx54("min-w-0", meterWidth ? "shrink-0" : "flex-1"),
|
|
3243
|
+
style: meterWidth ? { width: meterWidth } : void 0,
|
|
3244
|
+
children: meter
|
|
3245
|
+
}
|
|
3246
|
+
),
|
|
3247
|
+
trailing && /* @__PURE__ */ jsx58("div", { className: "shrink-0 text-right", style: trailingWidth ? { width: trailingWidth } : void 0, children: trailing })
|
|
3248
|
+
] });
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
// src/components/lists/ranked-row.tsx
|
|
3252
|
+
import clsx55 from "clsx";
|
|
3253
|
+
|
|
3254
|
+
// src/components/feedback/progress-bar.tsx
|
|
3255
|
+
import { jsx as jsx59, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
3256
|
+
var SIZE13 = {
|
|
3257
|
+
xs: "h-1",
|
|
3258
|
+
sm: "h-1.5",
|
|
3259
|
+
md: "h-2",
|
|
3260
|
+
lg: "h-3"
|
|
3261
|
+
};
|
|
3262
|
+
var FILL = {
|
|
3263
|
+
brand: "bg-brand",
|
|
3264
|
+
positive: "bg-positive",
|
|
3265
|
+
warning: "bg-warning",
|
|
3266
|
+
danger: "bg-danger",
|
|
3267
|
+
neutral: "bg-neutral"
|
|
3268
|
+
};
|
|
3269
|
+
function ProgressBar({
|
|
3270
|
+
value,
|
|
3271
|
+
tone = "brand",
|
|
3272
|
+
size = "sm",
|
|
3273
|
+
label,
|
|
3274
|
+
showValue = false,
|
|
3275
|
+
radius,
|
|
3276
|
+
"aria-label": ariaLabel,
|
|
3277
|
+
className
|
|
3278
|
+
}) {
|
|
3279
|
+
const clamped = Math.min(100, Math.max(0, value));
|
|
3280
|
+
const rounded = radius ? void 0 : "rounded-full";
|
|
3281
|
+
const track = /* @__PURE__ */ jsx59(
|
|
3282
|
+
"div",
|
|
3283
|
+
{
|
|
3284
|
+
role: "progressbar",
|
|
3285
|
+
"aria-valuenow": clamped,
|
|
3286
|
+
"aria-valuemin": 0,
|
|
3287
|
+
"aria-valuemax": 100,
|
|
3288
|
+
"aria-label": label ? void 0 : ariaLabel,
|
|
3289
|
+
className: cn("w-full overflow-hidden bg-default-tertiary", SIZE13[size], rounded, className),
|
|
3290
|
+
style: radius ? { borderRadius: radius } : void 0,
|
|
3291
|
+
children: /* @__PURE__ */ jsx59(
|
|
3292
|
+
"div",
|
|
3293
|
+
{
|
|
3294
|
+
className: cn("h-full transition-all", rounded, FILL[tone]),
|
|
3295
|
+
style: { width: `${clamped}%`, ...radius ? { borderRadius: radius } : void 0 }
|
|
3296
|
+
}
|
|
3297
|
+
)
|
|
3298
|
+
}
|
|
3299
|
+
);
|
|
3300
|
+
if (!label && !showValue) return track;
|
|
3301
|
+
return /* @__PURE__ */ jsxs44("div", { children: [
|
|
3302
|
+
/* @__PURE__ */ jsxs44("div", { className: "mb-1.5 flex items-center justify-between gap-2", children: [
|
|
3303
|
+
label && /* @__PURE__ */ jsx59("span", { className: "text-body-xs text-default-secondary", children: label }),
|
|
3304
|
+
showValue && /* @__PURE__ */ jsxs44("span", { className: "ml-auto text-body-xs font-medium tabular-nums text-default", children: [
|
|
3305
|
+
Math.round(clamped),
|
|
3306
|
+
"%"
|
|
3307
|
+
] })
|
|
3308
|
+
] }),
|
|
3309
|
+
track
|
|
3310
|
+
] });
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
// src/components/lists/ranked-row.tsx
|
|
3314
|
+
import { jsx as jsx60, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3315
|
+
function RankedRow({
|
|
3316
|
+
rank,
|
|
3317
|
+
name,
|
|
3318
|
+
sublabel,
|
|
3319
|
+
score,
|
|
3320
|
+
tone = "auto",
|
|
3321
|
+
direction = "higher-is-worse",
|
|
3322
|
+
scoreSize = "md",
|
|
3323
|
+
scoreWeight = "bold",
|
|
3324
|
+
className
|
|
1201
3325
|
}) {
|
|
1202
|
-
|
|
3326
|
+
const resolved = tone === "auto" ? getScoreTone(score, { direction }) : tone;
|
|
3327
|
+
return /* @__PURE__ */ jsxs45("div", { className: clsx55("flex w-full shrink-0 flex-col gap-1.5", className), children: [
|
|
3328
|
+
/* @__PURE__ */ jsxs45("div", { className: "flex w-full items-center justify-between", children: [
|
|
3329
|
+
/* @__PURE__ */ jsxs45("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
3330
|
+
rank !== void 0 && /* @__PURE__ */ jsx60("p", { className: "w-[14px] shrink-0 text-body-xs font-bold text-default-secondary", children: rank }),
|
|
3331
|
+
/* @__PURE__ */ jsxs45("div", { className: "flex min-w-0 flex-col gap-px", children: [
|
|
3332
|
+
/* @__PURE__ */ jsx60("p", { className: "truncate text-body-sm font-medium leading-none text-default", children: name }),
|
|
3333
|
+
sublabel && /* @__PURE__ */ jsx60("p", { className: "text-body-tiny text-default-tertiary", children: sublabel })
|
|
3334
|
+
] })
|
|
3335
|
+
] }),
|
|
3336
|
+
/* @__PURE__ */ jsx60(
|
|
3337
|
+
ScoreValue,
|
|
3338
|
+
{
|
|
3339
|
+
value: score,
|
|
3340
|
+
size: scoreSize,
|
|
3341
|
+
weight: scoreWeight,
|
|
3342
|
+
tone: resolved,
|
|
3343
|
+
className: "ml-2 shrink-0"
|
|
3344
|
+
}
|
|
3345
|
+
)
|
|
3346
|
+
] }),
|
|
3347
|
+
/* @__PURE__ */ jsx60(ProgressBar, { value: score, tone: resolved, "aria-label": `${name} score` })
|
|
3348
|
+
] });
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
// src/components/lists/icon-text-row.tsx
|
|
3352
|
+
import clsx56 from "clsx";
|
|
3353
|
+
import { jsx as jsx61, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
3354
|
+
function IconTextRow({ icon, title, detail, className }) {
|
|
3355
|
+
return /* @__PURE__ */ jsxs46("div", { className: clsx56("flex items-start gap-3", className), children: [
|
|
3356
|
+
/* @__PURE__ */ jsx61("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-brand", children: icon }),
|
|
3357
|
+
/* @__PURE__ */ jsxs46("div", { className: "min-w-0", children: [
|
|
3358
|
+
/* @__PURE__ */ jsx61("p", { className: "text-body-sm font-semibold text-default", children: title }),
|
|
3359
|
+
/* @__PURE__ */ jsx61("p", { className: "mt-0.5 text-body-xs text-default-secondary", children: detail })
|
|
3360
|
+
] })
|
|
3361
|
+
] });
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
// src/components/lists/checklist-row.tsx
|
|
3365
|
+
import clsx57 from "clsx";
|
|
3366
|
+
import { LuCheck as LuCheck5 } from "react-icons/lu";
|
|
3367
|
+
import { jsx as jsx62, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
3368
|
+
function ChecklistRow({ label, state, className }) {
|
|
3369
|
+
return /* @__PURE__ */ jsxs47("li", { className: clsx57("flex items-center gap-3", className), children: [
|
|
3370
|
+
/* @__PURE__ */ jsx62("span", { className: "flex size-5 shrink-0 items-center justify-center", children: state === "done" ? /* @__PURE__ */ jsx62(LuCheck5, { className: "size-4 text-positive", strokeWidth: 2.5, "aria-hidden": true }) : /* @__PURE__ */ jsx62(
|
|
3371
|
+
"span",
|
|
3372
|
+
{
|
|
3373
|
+
className: clsx57(
|
|
3374
|
+
"size-3.5 rounded-full border-2",
|
|
3375
|
+
state === "active" ? "animate-pulse border-brand-emphasis border-t-transparent" : "border-disabled"
|
|
3376
|
+
)
|
|
3377
|
+
}
|
|
3378
|
+
) }),
|
|
3379
|
+
/* @__PURE__ */ jsx62(
|
|
3380
|
+
"span",
|
|
3381
|
+
{
|
|
3382
|
+
className: clsx57(
|
|
3383
|
+
"text-body-sm",
|
|
3384
|
+
state === "pending" ? "text-default-tertiary" : "font-semibold text-default"
|
|
3385
|
+
),
|
|
3386
|
+
children: label
|
|
3387
|
+
}
|
|
3388
|
+
)
|
|
3389
|
+
] });
|
|
3390
|
+
}
|
|
3391
|
+
|
|
3392
|
+
// src/components/lists/numbered-steps-list.tsx
|
|
3393
|
+
import clsx58 from "clsx";
|
|
3394
|
+
import { jsx as jsx63, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
3395
|
+
function NumberedStepsList({ steps, className }) {
|
|
3396
|
+
return /* @__PURE__ */ jsx63("ol", { className: clsx58("flex flex-col gap-1.5", className), children: steps.map((step, i) => /* @__PURE__ */ jsxs48("li", { className: "flex items-start gap-2 text-[12px] text-default", children: [
|
|
3397
|
+
/* @__PURE__ */ jsx63("span", { className: "mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-brand-tertiary text-[9px] font-bold text-brand", children: i + 1 }),
|
|
3398
|
+
step
|
|
3399
|
+
] }, i)) });
|
|
1203
3400
|
}
|
|
1204
|
-
|
|
3401
|
+
|
|
3402
|
+
// src/components/lists/meta-field.tsx
|
|
3403
|
+
import clsx59 from "clsx";
|
|
3404
|
+
import { jsx as jsx64, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
3405
|
+
function MetaField({
|
|
1205
3406
|
label,
|
|
1206
3407
|
value,
|
|
1207
|
-
|
|
3408
|
+
detail,
|
|
3409
|
+
layout = "stacked",
|
|
3410
|
+
className
|
|
1208
3411
|
}) {
|
|
1209
|
-
const
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
/* @__PURE__ */
|
|
3412
|
+
const shown = value === null || value === void 0 || value === "" ? "\u2014" : value;
|
|
3413
|
+
if (layout === "inline") {
|
|
3414
|
+
return /* @__PURE__ */ jsxs49("div", { className: clsx59("flex gap-3 text-body-xs", className), children: [
|
|
3415
|
+
/* @__PURE__ */ jsx64("span", { className: "w-[120px] shrink-0 text-default-secondary", children: label }),
|
|
3416
|
+
/* @__PURE__ */ jsx64("span", { className: "min-w-0 flex-1 text-default", children: shown })
|
|
3417
|
+
] });
|
|
3418
|
+
}
|
|
3419
|
+
return /* @__PURE__ */ jsxs49("div", { className: clsx59("flex flex-col gap-0.5", className), children: [
|
|
3420
|
+
/* @__PURE__ */ jsx64("p", { className: "text-body-tiny font-medium text-default-secondary", children: label }),
|
|
3421
|
+
/* @__PURE__ */ jsx64("p", { className: "text-body-sm font-medium text-default", children: shown }),
|
|
3422
|
+
detail && /* @__PURE__ */ jsx64("p", { className: "text-body-xs text-default-secondary", children: detail })
|
|
1218
3423
|
] });
|
|
1219
3424
|
}
|
|
1220
|
-
function
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
3425
|
+
function MetaFieldGrid({ children, className }) {
|
|
3426
|
+
return /* @__PURE__ */ jsx64("div", { className: clsx59("flex flex-wrap gap-x-4 gap-y-3.5", className), children });
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
// src/components/lists/checked-group-list.tsx
|
|
3430
|
+
import clsx60 from "clsx";
|
|
3431
|
+
import { LuCheck as LuCheck6 } from "react-icons/lu";
|
|
3432
|
+
import { jsx as jsx65, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
3433
|
+
var COLUMNS2 = {
|
|
3434
|
+
1: "columns-1",
|
|
3435
|
+
2: "columns-2",
|
|
3436
|
+
3: "columns-3"
|
|
3437
|
+
};
|
|
3438
|
+
function CheckedGroupList({
|
|
3439
|
+
groups,
|
|
3440
|
+
columns = 2,
|
|
3441
|
+
icon,
|
|
3442
|
+
emptyLabel = "None.",
|
|
3443
|
+
className
|
|
3444
|
+
}) {
|
|
3445
|
+
if (groups.length === 0) {
|
|
3446
|
+
return /* @__PURE__ */ jsx65("p", { className: clsx60("text-body-xs text-default-secondary", className), children: emptyLabel });
|
|
3447
|
+
}
|
|
3448
|
+
const glyph = icon === void 0 ? /* @__PURE__ */ jsx65(LuCheck6, { className: "size-3.5", strokeWidth: 2.5, "aria-hidden": true }) : icon;
|
|
3449
|
+
return /* @__PURE__ */ jsx65("div", { className: clsx60(COLUMNS2[columns], "gap-x-6", className), children: groups.map((group) => /* @__PURE__ */ jsxs50("div", { className: "mb-5 break-inside-avoid last:mb-0", children: [
|
|
3450
|
+
/* @__PURE__ */ jsx65("p", { className: "mb-2 text-body-tiny font-semibold uppercase tracking-wide text-default-secondary", children: group.label }),
|
|
3451
|
+
/* @__PURE__ */ jsx65("ul", { className: "space-y-1.5", children: group.items.map((item) => /* @__PURE__ */ jsxs50("li", { className: "flex items-center gap-2 text-body-xs text-default", children: [
|
|
3452
|
+
glyph && /* @__PURE__ */ jsx65("span", { className: "shrink-0", children: glyph }),
|
|
3453
|
+
item
|
|
3454
|
+
] }, item)) })
|
|
3455
|
+
] }, group.label)) });
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3458
|
+
// src/components/lists/data-table.tsx
|
|
3459
|
+
import clsx61 from "clsx";
|
|
3460
|
+
import { jsx as jsx66, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
3461
|
+
var DENSITY2 = {
|
|
3462
|
+
default: {
|
|
3463
|
+
headerCell: "px-4 py-3",
|
|
3464
|
+
headerText: "text-body-xs font-medium text-default-secondary whitespace-nowrap",
|
|
3465
|
+
bodyCell: "px-4 py-[14px]"
|
|
3466
|
+
},
|
|
3467
|
+
compact: {
|
|
3468
|
+
headerCell: "px-3 py-2",
|
|
3469
|
+
headerText: "text-body-tiny font-semibold uppercase tracking-[0.4px] text-default-secondary whitespace-nowrap",
|
|
3470
|
+
bodyCell: "px-3 py-2 text-body-xs text-default"
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
var ALIGN2 = {
|
|
3474
|
+
center: "align-middle",
|
|
3475
|
+
top: "align-top"
|
|
3476
|
+
};
|
|
3477
|
+
function DataTable({
|
|
3478
|
+
columns,
|
|
3479
|
+
rows,
|
|
3480
|
+
getRowKey,
|
|
3481
|
+
density = "default",
|
|
3482
|
+
align = "center",
|
|
3483
|
+
onRowClick,
|
|
3484
|
+
emptyLabel,
|
|
3485
|
+
className
|
|
3486
|
+
}) {
|
|
3487
|
+
const d = DENSITY2[density];
|
|
3488
|
+
const minWidth = columns.length ? `calc(${columns.map((c) => c.width).join(" + ")})` : void 0;
|
|
3489
|
+
return /* @__PURE__ */ jsx66("div", { className: clsx61("overflow-x-auto rounded-xl border border-default bg-default", className), children: /* @__PURE__ */ jsxs51("table", { className: "w-full table-fixed border-collapse text-left", style: { minWidth }, children: [
|
|
3490
|
+
/* @__PURE__ */ jsx66("colgroup", { children: columns.map((col) => (
|
|
3491
|
+
// A grow column gets no width, so table-fixed hands it the leftover space.
|
|
3492
|
+
// Its floor is already counted in the table's min-width.
|
|
3493
|
+
/* @__PURE__ */ jsx66("col", { style: col.grow ? void 0 : { width: col.width } }, col.key)
|
|
3494
|
+
)) }),
|
|
3495
|
+
/* @__PURE__ */ jsx66("thead", { children: /* @__PURE__ */ jsx66("tr", { className: "bg-default-secondary", children: columns.map((col) => /* @__PURE__ */ jsx66("th", { scope: "col", className: clsx61("overflow-hidden", d.headerCell, d.headerText), children: col.header }, col.key)) }) }),
|
|
3496
|
+
/* @__PURE__ */ jsx66("tbody", { children: rows.length === 0 ? emptyLabel && /* @__PURE__ */ jsx66("tr", { children: /* @__PURE__ */ jsx66(
|
|
3497
|
+
"td",
|
|
3498
|
+
{
|
|
3499
|
+
colSpan: columns.length,
|
|
3500
|
+
className: clsx61(d.bodyCell, "text-center text-body-sm text-default-secondary"),
|
|
3501
|
+
children: emptyLabel
|
|
3502
|
+
}
|
|
3503
|
+
) }) : rows.map((row, i) => /* @__PURE__ */ jsx66(
|
|
3504
|
+
"tr",
|
|
3505
|
+
{
|
|
3506
|
+
className: clsx61(
|
|
3507
|
+
"transition-colors hover:bg-default-secondary/50",
|
|
3508
|
+
i > 0 && "border-t border-default",
|
|
3509
|
+
// outline, not ring: `ring-*` compiles to box-shadow, which browsers
|
|
3510
|
+
// do not paint on a <tr> under border-collapse: collapse.
|
|
3511
|
+
onRowClick && "cursor-pointer outline-none focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-brand"
|
|
3512
|
+
),
|
|
3513
|
+
tabIndex: onRowClick ? 0 : void 0,
|
|
3514
|
+
onClick: onRowClick ? () => onRowClick(row) : void 0,
|
|
3515
|
+
onKeyDown: onRowClick ? (e) => {
|
|
3516
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3517
|
+
e.preventDefault();
|
|
3518
|
+
onRowClick(row);
|
|
3519
|
+
}
|
|
3520
|
+
} : void 0,
|
|
3521
|
+
children: columns.map((col) => /* @__PURE__ */ jsx66("td", { className: clsx61("overflow-hidden", d.bodyCell, ALIGN2[align]), children: col.render(row) }, col.key))
|
|
3522
|
+
},
|
|
3523
|
+
getRowKey(row, i)
|
|
3524
|
+
)) })
|
|
3525
|
+
] }) });
|
|
3526
|
+
}
|
|
3527
|
+
function TableCellLeadText({ primary, secondary, size = "md", className }) {
|
|
3528
|
+
return /* @__PURE__ */ jsxs51("div", { className: clsx61("flex flex-col gap-0.5", className), children: [
|
|
3529
|
+
/* @__PURE__ */ jsx66(
|
|
3530
|
+
"span",
|
|
3531
|
+
{
|
|
3532
|
+
className: clsx61(
|
|
3533
|
+
"font-medium leading-snug text-default",
|
|
3534
|
+
size === "sm" ? "text-body-xs" : "text-body-sm"
|
|
3535
|
+
),
|
|
3536
|
+
children: primary
|
|
3537
|
+
}
|
|
3538
|
+
),
|
|
3539
|
+
secondary && /* @__PURE__ */ jsx66(
|
|
3540
|
+
"span",
|
|
3541
|
+
{
|
|
3542
|
+
className: clsx61(
|
|
3543
|
+
"font-normal leading-tight text-default-secondary",
|
|
3544
|
+
size === "sm" ? "text-body-tiny" : "text-body-xs"
|
|
3545
|
+
),
|
|
3546
|
+
children: secondary
|
|
3547
|
+
}
|
|
3548
|
+
)
|
|
3549
|
+
] });
|
|
3550
|
+
}
|
|
3551
|
+
function TableCellText({
|
|
3552
|
+
children,
|
|
3553
|
+
muted = true,
|
|
3554
|
+
size = "md",
|
|
3555
|
+
truncate = false,
|
|
3556
|
+
className
|
|
3557
|
+
}) {
|
|
3558
|
+
return /* @__PURE__ */ jsx66(
|
|
3559
|
+
"span",
|
|
3560
|
+
{
|
|
3561
|
+
className: clsx61(
|
|
3562
|
+
"font-normal leading-snug",
|
|
3563
|
+
size === "sm" ? "text-body-tiny" : "text-body-xs",
|
|
3564
|
+
truncate ? "block truncate" : "whitespace-nowrap",
|
|
3565
|
+
muted ? "text-default-secondary" : "text-default",
|
|
3566
|
+
className
|
|
3567
|
+
),
|
|
3568
|
+
children
|
|
3569
|
+
}
|
|
3570
|
+
);
|
|
3571
|
+
}
|
|
3572
|
+
function TableCellBadge({ label, className }) {
|
|
3573
|
+
return /* @__PURE__ */ jsx66(
|
|
3574
|
+
"span",
|
|
3575
|
+
{
|
|
3576
|
+
className: clsx61(
|
|
3577
|
+
"inline-flex items-center rounded-md border border-default bg-default-secondary px-2 py-0.5 text-body-tiny font-medium text-default-secondary whitespace-nowrap",
|
|
3578
|
+
className
|
|
3579
|
+
),
|
|
3580
|
+
children: label
|
|
3581
|
+
}
|
|
3582
|
+
);
|
|
3583
|
+
}
|
|
3584
|
+
function TableCellProgress({
|
|
3585
|
+
percent,
|
|
3586
|
+
tone = "brand",
|
|
3587
|
+
size = "md",
|
|
3588
|
+
className
|
|
3589
|
+
}) {
|
|
3590
|
+
const clamped = Math.min(100, Math.max(0, percent));
|
|
3591
|
+
return /* @__PURE__ */ jsxs51("div", { className: clsx61("flex flex-col gap-1", className), children: [
|
|
3592
|
+
/* @__PURE__ */ jsx66(ProgressBar, { value: clamped, tone, size: "sm", className: "w-16", "aria-label": `${clamped}%` }),
|
|
3593
|
+
/* @__PURE__ */ jsxs51(
|
|
3594
|
+
"span",
|
|
3595
|
+
{
|
|
3596
|
+
className: clsx61(
|
|
3597
|
+
"leading-none text-default-secondary",
|
|
3598
|
+
size === "sm" ? "text-[10px]" : "text-body-tiny"
|
|
3599
|
+
),
|
|
3600
|
+
children: [
|
|
3601
|
+
percent,
|
|
3602
|
+
"%"
|
|
3603
|
+
]
|
|
3604
|
+
}
|
|
3605
|
+
)
|
|
3606
|
+
] });
|
|
3607
|
+
}
|
|
3608
|
+
|
|
3609
|
+
// src/components/feedback/inline-alert.tsx
|
|
3610
|
+
import clsx62 from "clsx";
|
|
3611
|
+
import { LuCircleCheckBig as LuCircleCheckBig2, LuInfo as LuInfo2, LuTriangleAlert as LuTriangleAlert2 } from "react-icons/lu";
|
|
3612
|
+
import { jsx as jsx67, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
3613
|
+
var toneStyles3 = {
|
|
3614
|
+
info: "border-brand-tertiary bg-brand-tertiary text-brand",
|
|
3615
|
+
warning: "border-warning-tertiary bg-warning-tertiary text-warning",
|
|
3616
|
+
danger: "border-danger-tertiary bg-danger-tertiary text-danger",
|
|
3617
|
+
positive: "border-positive-tertiary bg-positive-tertiary text-positive"
|
|
3618
|
+
};
|
|
3619
|
+
var toneIcons = {
|
|
3620
|
+
info: /* @__PURE__ */ jsx67(LuInfo2, { className: "size-4" }),
|
|
3621
|
+
warning: /* @__PURE__ */ jsx67(LuTriangleAlert2, { className: "size-4" }),
|
|
3622
|
+
danger: /* @__PURE__ */ jsx67(LuTriangleAlert2, { className: "size-4" }),
|
|
3623
|
+
positive: /* @__PURE__ */ jsx67(LuCircleCheckBig2, { className: "size-4" })
|
|
3624
|
+
};
|
|
3625
|
+
function InlineAlert({ tone, children, icon, className }) {
|
|
3626
|
+
const glyph = icon === void 0 ? toneIcons[tone] : icon;
|
|
3627
|
+
return /* @__PURE__ */ jsxs52(
|
|
3628
|
+
"div",
|
|
3629
|
+
{
|
|
3630
|
+
role: tone === "danger" ? "alert" : "status",
|
|
3631
|
+
className: clsx62(
|
|
3632
|
+
"flex items-start gap-2.5 rounded-xl border p-3.5 text-body-xs",
|
|
3633
|
+
toneStyles3[tone],
|
|
3634
|
+
className
|
|
3635
|
+
),
|
|
3636
|
+
children: [
|
|
3637
|
+
glyph && /* @__PURE__ */ jsx67("span", { className: "mt-px shrink-0", children: glyph }),
|
|
3638
|
+
/* @__PURE__ */ jsx67("div", { className: "min-w-0", children })
|
|
3639
|
+
]
|
|
3640
|
+
}
|
|
3641
|
+
);
|
|
3642
|
+
}
|
|
3643
|
+
|
|
3644
|
+
// src/components/feedback/empty-state.tsx
|
|
3645
|
+
import clsx63 from "clsx";
|
|
3646
|
+
import { jsx as jsx68, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
3647
|
+
var SIZES = {
|
|
3648
|
+
sm: "py-8",
|
|
3649
|
+
md: "py-12",
|
|
3650
|
+
lg: "py-16"
|
|
3651
|
+
};
|
|
3652
|
+
var TONES = {
|
|
3653
|
+
empty: "text-default-secondary",
|
|
3654
|
+
loading: "text-default-secondary",
|
|
3655
|
+
error: "text-danger"
|
|
3656
|
+
};
|
|
3657
|
+
function EmptyState({
|
|
3658
|
+
message,
|
|
3659
|
+
variant = "empty",
|
|
3660
|
+
size = "sm",
|
|
3661
|
+
icon,
|
|
3662
|
+
action,
|
|
3663
|
+
className
|
|
3664
|
+
}) {
|
|
3665
|
+
return /* @__PURE__ */ jsxs53(
|
|
3666
|
+
"div",
|
|
3667
|
+
{
|
|
3668
|
+
className: clsx63(
|
|
3669
|
+
"flex flex-col items-center justify-center gap-2 px-4 text-center text-body-sm",
|
|
3670
|
+
SIZES[size],
|
|
3671
|
+
TONES[variant],
|
|
3672
|
+
className
|
|
3673
|
+
),
|
|
3674
|
+
"aria-live": variant === "empty" ? void 0 : "polite",
|
|
3675
|
+
children: [
|
|
3676
|
+
icon && /* @__PURE__ */ jsx68("span", { className: "text-default-tertiary", children: icon }),
|
|
3677
|
+
/* @__PURE__ */ jsx68("p", { children: message }),
|
|
3678
|
+
action
|
|
3679
|
+
]
|
|
3680
|
+
}
|
|
3681
|
+
);
|
|
3682
|
+
}
|
|
3683
|
+
|
|
3684
|
+
// src/components/forms/password-input.tsx
|
|
3685
|
+
import { forwardRef as forwardRef5, useState as useState5 } from "react";
|
|
3686
|
+
import { LuEye, LuEyeOff } from "react-icons/lu";
|
|
3687
|
+
import { jsx as jsx69 } from "react/jsx-runtime";
|
|
3688
|
+
var PasswordInput = forwardRef5(function PasswordInput2(props, ref) {
|
|
3689
|
+
const [visible, setVisible] = useState5(false);
|
|
3690
|
+
return /* @__PURE__ */ jsx69(
|
|
3691
|
+
Input,
|
|
3692
|
+
{
|
|
3693
|
+
ref,
|
|
3694
|
+
...props,
|
|
3695
|
+
type: visible ? "text" : "password",
|
|
3696
|
+
trailingAction: /* @__PURE__ */ jsx69(
|
|
3697
|
+
"button",
|
|
3698
|
+
{
|
|
3699
|
+
type: "button",
|
|
3700
|
+
"aria-label": visible ? "Hide password" : "Show password",
|
|
3701
|
+
onClick: () => setVisible((v) => !v),
|
|
3702
|
+
className: "flex items-center justify-center rounded transition-colors hover:text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand",
|
|
3703
|
+
children: visible ? /* @__PURE__ */ jsx69(LuEyeOff, { className: "size-4" }) : /* @__PURE__ */ jsx69(LuEye, { className: "size-4" })
|
|
3704
|
+
}
|
|
3705
|
+
)
|
|
3706
|
+
}
|
|
3707
|
+
);
|
|
3708
|
+
});
|
|
3709
|
+
|
|
3710
|
+
// src/components/ai/ai-chat-bar.tsx
|
|
3711
|
+
import clsx64 from "clsx";
|
|
3712
|
+
import { LuArrowRight as LuArrowRight2, LuSearch } from "react-icons/lu";
|
|
3713
|
+
import { jsx as jsx70, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
3714
|
+
function AIChatBar({
|
|
3715
|
+
placeholder = "Ask Intelligence about any entity, supplier, or risk\u2026",
|
|
3716
|
+
className
|
|
1242
3717
|
}) {
|
|
1243
|
-
return /* @__PURE__ */
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
3718
|
+
return /* @__PURE__ */ jsxs54(
|
|
3719
|
+
"div",
|
|
3720
|
+
{
|
|
3721
|
+
className: clsx64(
|
|
3722
|
+
"flex h-16 items-center gap-3 rounded-2xl border border-default bg-default px-6 shadow-panel",
|
|
3723
|
+
className
|
|
3724
|
+
),
|
|
3725
|
+
children: [
|
|
3726
|
+
/* @__PURE__ */ jsx70("span", { className: "shrink-0 text-icon-default-secondary", children: /* @__PURE__ */ jsx70(LuSearch, { className: "size-4" }) }),
|
|
3727
|
+
/* @__PURE__ */ jsx70("p", { className: "flex-1 text-body-sm text-default-tertiary truncate", children: placeholder }),
|
|
3728
|
+
/* @__PURE__ */ jsxs54(
|
|
3729
|
+
"button",
|
|
3730
|
+
{
|
|
3731
|
+
type: "button",
|
|
3732
|
+
className: "inline-flex shrink-0 items-center gap-2 rounded-xl bg-brand px-4 py-3 text-body-sm font-semibold text-brand-on-brand hover:bg-brand-hover transition-colors",
|
|
3733
|
+
children: [
|
|
3734
|
+
"Ask",
|
|
3735
|
+
/* @__PURE__ */ jsx70(LuArrowRight2, { className: "size-4" })
|
|
3736
|
+
]
|
|
3737
|
+
}
|
|
3738
|
+
)
|
|
3739
|
+
]
|
|
3740
|
+
}
|
|
3741
|
+
);
|
|
3742
|
+
}
|
|
3743
|
+
|
|
3744
|
+
// src/components/ai/ai-suggestion-chip.tsx
|
|
3745
|
+
import clsx65 from "clsx";
|
|
3746
|
+
import { LuArrowRight as LuArrowRight3, LuCpu } from "react-icons/lu";
|
|
3747
|
+
import { jsx as jsx71, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
3748
|
+
function AISuggestionChip({ prompt, onClick, className }) {
|
|
3749
|
+
return /* @__PURE__ */ jsxs55(
|
|
3750
|
+
"button",
|
|
3751
|
+
{
|
|
3752
|
+
type: "button",
|
|
3753
|
+
onClick,
|
|
3754
|
+
className: clsx65(
|
|
3755
|
+
"flex h-12 w-full items-center gap-3 rounded-xl border border-default bg-default px-3 text-left hover:bg-default-hover transition-colors",
|
|
3756
|
+
className
|
|
3757
|
+
),
|
|
3758
|
+
children: [
|
|
3759
|
+
/* @__PURE__ */ jsx71("span", { className: "shrink-0 text-icon-brand", children: /* @__PURE__ */ jsx71(LuCpu, { className: "size-4" }) }),
|
|
3760
|
+
/* @__PURE__ */ jsx71("span", { className: "flex-1 text-body-sm text-default truncate", children: prompt }),
|
|
3761
|
+
/* @__PURE__ */ jsx71("span", { className: "shrink-0 text-icon-default-secondary", children: /* @__PURE__ */ jsx71(LuArrowRight3, { className: "size-3.5", strokeWidth: 2.5 }) })
|
|
3762
|
+
]
|
|
3763
|
+
}
|
|
3764
|
+
);
|
|
3765
|
+
}
|
|
3766
|
+
|
|
3767
|
+
// src/components/ai/quick-actions-bar.tsx
|
|
3768
|
+
import clsx66 from "clsx";
|
|
3769
|
+
import { jsx as jsx72 } from "react/jsx-runtime";
|
|
3770
|
+
function QuickActionsBar({ actions, active, onSelect, className }) {
|
|
3771
|
+
return /* @__PURE__ */ jsx72("div", { className: clsx66("flex items-center gap-3 flex-wrap", className), children: actions.map((action) => /* @__PURE__ */ jsx72(
|
|
3772
|
+
"button",
|
|
3773
|
+
{
|
|
3774
|
+
type: "button",
|
|
3775
|
+
onClick: () => onSelect?.(action.value),
|
|
3776
|
+
className: "focus:outline-none",
|
|
3777
|
+
children: /* @__PURE__ */ jsx72(
|
|
3778
|
+
TagPill,
|
|
3779
|
+
{
|
|
3780
|
+
label: action.label,
|
|
3781
|
+
tone: active === action.value ? "brand" : "default"
|
|
3782
|
+
}
|
|
3783
|
+
)
|
|
3784
|
+
},
|
|
3785
|
+
action.value
|
|
3786
|
+
)) });
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
// src/components/decorative/aurora-backdrop.tsx
|
|
3790
|
+
import { jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
3791
|
+
function AuroraBackdrop() {
|
|
3792
|
+
return /* @__PURE__ */ jsxs56("div", { className: "pointer-events-none absolute inset-0", "aria-hidden": true, children: [
|
|
3793
|
+
/* @__PURE__ */ jsx73("div", { className: "absolute -left-24 -top-28", style: { width: 380, height: 380, background: "radial-gradient(ellipse, rgba(249,133,133,0.45) 0%, transparent 70%)" } }),
|
|
3794
|
+
/* @__PURE__ */ jsx73("div", { className: "absolute -top-24 right-[-4%]", style: { width: 320, height: 320, background: "radial-gradient(ellipse, rgba(254,160,160,0.4) 0%, transparent 70%)" } }),
|
|
3795
|
+
/* @__PURE__ */ jsx73("div", { className: "absolute bottom-[-10%] right-[14%]", style: { width: 420, height: 420, background: "radial-gradient(ellipse, rgba(196,181,253,0.3) 0%, transparent 70%)" } }),
|
|
3796
|
+
/* @__PURE__ */ jsx73("div", { className: "absolute bottom-[-6%] left-[4%]", style: { width: 280, height: 280, background: "radial-gradient(ellipse, rgba(147,197,253,0.25) 0%, transparent 70%)" } }),
|
|
3797
|
+
/* @__PURE__ */ jsx73("div", { className: "absolute left-[20%] top-[30%]", style: { width: 240, height: 240, background: "radial-gradient(ellipse, rgba(173,216,255,0.18) 0%, transparent 70%)" } })
|
|
1247
3798
|
] });
|
|
1248
3799
|
}
|
|
3800
|
+
|
|
3801
|
+
// src/components/icons/solid.tsx
|
|
3802
|
+
import { jsx as jsx74 } from "react/jsx-runtime";
|
|
3803
|
+
function solid(path, displayName) {
|
|
3804
|
+
const Component = ({ className }) => /* @__PURE__ */ jsx74("svg", { viewBox: "0 0 20 20", fill: "currentColor", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx74("path", { fillRule: "evenodd", d: path, clipRule: "evenodd" }) });
|
|
3805
|
+
Component.displayName = displayName;
|
|
3806
|
+
return Component;
|
|
3807
|
+
}
|
|
3808
|
+
var SolidAlertTriangle = solid(
|
|
3809
|
+
"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
|
|
3810
|
+
"SolidAlertTriangle"
|
|
3811
|
+
);
|
|
3812
|
+
var SolidShieldCheck = solid(
|
|
3813
|
+
"M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zm1.414 7.349a1 1 0 00-1.414-1.414L8.5 9.379l-.793-.793a1 1 0 00-1.414 1.414l1.5 1.5a1 1 0 001.414 0l2.207-2.207z",
|
|
3814
|
+
"SolidShieldCheck"
|
|
3815
|
+
);
|
|
3816
|
+
var SolidGlobe = solid(
|
|
3817
|
+
"M10 18a8 8 0 100-16 8 8 0 000 16zM4.332 8.027a6.012 6.012 0 011.912-2.706C6.512 5.73 6.974 6 7.5 6A1.5 1.5 0 019 7.5V8a2 2 0 004 0 2 2 0 011.523-1.943A5.977 5.977 0 0116 10c0 .34-.028.675-.083 1H15a2 2 0 00-2 2v2.197A5.973 5.973 0 0110 16v-2a2 2 0 00-2-2 2 2 0 01-2-2 2 2 0 00-1.668-1.973z",
|
|
3818
|
+
"SolidGlobe"
|
|
3819
|
+
);
|
|
3820
|
+
var SolidMapPin = solid(
|
|
3821
|
+
"M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z",
|
|
3822
|
+
"SolidMapPin"
|
|
3823
|
+
);
|
|
3824
|
+
var SolidClock = solid(
|
|
3825
|
+
"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z",
|
|
3826
|
+
"SolidClock"
|
|
3827
|
+
);
|
|
3828
|
+
var SolidArrowRight = solid(
|
|
3829
|
+
"M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z",
|
|
3830
|
+
"SolidArrowRight"
|
|
3831
|
+
);
|
|
3832
|
+
var SolidInfoCircle = solid(
|
|
3833
|
+
"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",
|
|
3834
|
+
"SolidInfoCircle"
|
|
3835
|
+
);
|
|
3836
|
+
var SolidCheck = solid(
|
|
3837
|
+
"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
3838
|
+
"SolidCheck"
|
|
3839
|
+
);
|
|
3840
|
+
function SolidChartBar({ className }) {
|
|
3841
|
+
return /* @__PURE__ */ jsx74("svg", { viewBox: "0 0 20 20", fill: "currentColor", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx74("path", { d: "M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z" }) });
|
|
3842
|
+
}
|
|
1249
3843
|
export {
|
|
3844
|
+
AIChatBar,
|
|
3845
|
+
AISuggestionChip,
|
|
3846
|
+
AuroraBackdrop,
|
|
1250
3847
|
Avatar,
|
|
3848
|
+
AvatarBlock,
|
|
1251
3849
|
AvatarGroup,
|
|
3850
|
+
Badge,
|
|
3851
|
+
BarChart,
|
|
1252
3852
|
Button,
|
|
1253
3853
|
ButtonGroup,
|
|
3854
|
+
CHART_SEQUENCE,
|
|
3855
|
+
CHART_TONE,
|
|
3856
|
+
CHART_TRACK,
|
|
3857
|
+
Card,
|
|
3858
|
+
CardAction,
|
|
3859
|
+
CardBody,
|
|
3860
|
+
CardDescription,
|
|
3861
|
+
CardFooter,
|
|
3862
|
+
CardHeader,
|
|
3863
|
+
CardTitle,
|
|
3864
|
+
ChartLegend,
|
|
3865
|
+
CheckIndicator,
|
|
3866
|
+
Checkbox,
|
|
3867
|
+
CheckedGroupList,
|
|
3868
|
+
ChecklistRow,
|
|
3869
|
+
ConfirmDialog,
|
|
3870
|
+
CountBadge,
|
|
3871
|
+
DEFAULT_SCORE_THRESHOLDS,
|
|
1254
3872
|
DataTable,
|
|
1255
|
-
|
|
3873
|
+
DatePicker,
|
|
3874
|
+
DonutChart,
|
|
3875
|
+
Drawer,
|
|
3876
|
+
DropdownMenu,
|
|
3877
|
+
EmptyState,
|
|
3878
|
+
EntityIconBadge,
|
|
3879
|
+
EyebrowLabel,
|
|
1256
3880
|
FileDropZone,
|
|
3881
|
+
FileRow,
|
|
3882
|
+
FilterBar,
|
|
1257
3883
|
FormCard,
|
|
1258
3884
|
FormCardFooter,
|
|
1259
3885
|
FormCardHeader,
|
|
1260
3886
|
IconButton,
|
|
3887
|
+
IconTextRow,
|
|
3888
|
+
InlineAlert,
|
|
1261
3889
|
Input,
|
|
1262
|
-
|
|
3890
|
+
LegendDot,
|
|
3891
|
+
ListRow,
|
|
3892
|
+
MetaField,
|
|
3893
|
+
MetaFieldGrid,
|
|
3894
|
+
MiniBarChart,
|
|
1263
3895
|
Modal,
|
|
3896
|
+
ModalBody,
|
|
3897
|
+
ModalDescription,
|
|
3898
|
+
ModalFooter,
|
|
3899
|
+
ModalHeader,
|
|
3900
|
+
ModalTitle,
|
|
1264
3901
|
MultiSelectCard,
|
|
1265
3902
|
NavItem,
|
|
1266
|
-
|
|
3903
|
+
NoteConfirmModal,
|
|
3904
|
+
NumberedStepsList,
|
|
3905
|
+
OVERLAY_SCRIM,
|
|
3906
|
+
PageHeading,
|
|
3907
|
+
PageToolbar,
|
|
3908
|
+
PasswordInput,
|
|
3909
|
+
ProgressBar,
|
|
3910
|
+
QuickActionsBar,
|
|
1267
3911
|
ROLE_COMBO_OPTIONS,
|
|
3912
|
+
RadialGauge,
|
|
3913
|
+
RankedRow,
|
|
1268
3914
|
RoleBadge,
|
|
1269
3915
|
RoleComboBox,
|
|
1270
|
-
|
|
3916
|
+
ScoreValue,
|
|
3917
|
+
ScoredRow,
|
|
3918
|
+
SegmentedControl,
|
|
1271
3919
|
Select,
|
|
1272
|
-
|
|
1273
|
-
|
|
3920
|
+
SolidAlertTriangle,
|
|
3921
|
+
SolidArrowRight,
|
|
3922
|
+
SolidChartBar,
|
|
3923
|
+
SolidCheck,
|
|
3924
|
+
SolidClock,
|
|
3925
|
+
SolidGlobe,
|
|
3926
|
+
SolidInfoCircle,
|
|
3927
|
+
SolidMapPin,
|
|
3928
|
+
SolidShieldCheck,
|
|
3929
|
+
Sparkline,
|
|
3930
|
+
StatNumber,
|
|
1274
3931
|
StatTile,
|
|
3932
|
+
StatusBadge,
|
|
3933
|
+
StatusChip,
|
|
3934
|
+
StatusDot,
|
|
1275
3935
|
Stepper,
|
|
1276
3936
|
TableCellBadge,
|
|
1277
3937
|
TableCellLeadText,
|
|
1278
3938
|
TableCellProgress,
|
|
1279
|
-
TableCellStatusPill,
|
|
1280
3939
|
TableCellText,
|
|
3940
|
+
Tabs,
|
|
3941
|
+
TagPill,
|
|
1281
3942
|
Textarea,
|
|
1282
|
-
|
|
3943
|
+
TileGrid,
|
|
3944
|
+
Toggle,
|
|
3945
|
+
TrailChip,
|
|
3946
|
+
TrendLabel,
|
|
3947
|
+
UserStatusPill,
|
|
3948
|
+
WidgetFooter,
|
|
3949
|
+
WidgetHeader,
|
|
3950
|
+
WidgetTitle,
|
|
3951
|
+
cn,
|
|
3952
|
+
getScoreTone,
|
|
3953
|
+
resolveChartColor,
|
|
3954
|
+
useOverlayDismiss
|
|
1283
3955
|
};
|
|
1284
3956
|
//# sourceMappingURL=index.js.map
|