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