@kjaniec-dev/ui 0.5.0 → 0.7.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/dist/index.cjs +996 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +193 -3
- package/dist/index.d.ts +193 -3
- package/dist/index.js +982 -123
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var clsx = require('clsx');
|
|
4
4
|
var tailwindMerge = require('tailwind-merge');
|
|
5
|
-
var
|
|
5
|
+
var React18 = require('react');
|
|
6
6
|
var classVarianceAuthority = require('class-variance-authority');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
|
|
@@ -24,7 +24,7 @@ function _interopNamespace(e) {
|
|
|
24
24
|
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
|
|
28
28
|
|
|
29
29
|
// src/lib/cn.ts
|
|
30
30
|
function cn(...inputs) {
|
|
@@ -60,7 +60,7 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
60
60
|
defaultVariants: { variant: "primary", size: "md" }
|
|
61
61
|
}
|
|
62
62
|
);
|
|
63
|
-
var Button =
|
|
63
|
+
var Button = React18__namespace.forwardRef(
|
|
64
64
|
({ className, variant, size, loading, leadingIcon, trailingIcon, children, disabled, ...props }, ref) => {
|
|
65
65
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
66
66
|
"button",
|
|
@@ -107,7 +107,7 @@ var badgeVariants = classVarianceAuthority.cva(
|
|
|
107
107
|
defaultVariants: { variant: "neutral" }
|
|
108
108
|
}
|
|
109
109
|
);
|
|
110
|
-
var Badge =
|
|
110
|
+
var Badge = React18__namespace.forwardRef(
|
|
111
111
|
({ className, variant, dot, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("span", { ref, className: cn(badgeVariants({ variant }), className), ...props, children: [
|
|
112
112
|
dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-current", "aria-hidden": true }),
|
|
113
113
|
children
|
|
@@ -134,7 +134,7 @@ var iconColor = {
|
|
|
134
134
|
warning: "text-warning",
|
|
135
135
|
danger: "text-danger"
|
|
136
136
|
};
|
|
137
|
-
var Alert =
|
|
137
|
+
var Alert = React18__namespace.forwardRef(
|
|
138
138
|
({ className, variant = "info", icon, title, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props, children: [
|
|
139
139
|
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("shrink-0 mt-0.5 [&_svg]:h-[1.15rem] [&_svg]:w-[1.15rem]", iconColor[variant ?? "info"]), children: icon }),
|
|
140
140
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-foreground", children: [
|
|
@@ -144,7 +144,7 @@ var Alert = React17__namespace.forwardRef(
|
|
|
144
144
|
] })
|
|
145
145
|
);
|
|
146
146
|
Alert.displayName = "Alert";
|
|
147
|
-
var Spinner =
|
|
147
|
+
var Spinner = React18__namespace.forwardRef(
|
|
148
148
|
({ className, size = 24, style, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
149
149
|
"span",
|
|
150
150
|
{
|
|
@@ -161,7 +161,7 @@ var Spinner = React17__namespace.forwardRef(
|
|
|
161
161
|
)
|
|
162
162
|
);
|
|
163
163
|
Spinner.displayName = "Spinner";
|
|
164
|
-
var Progress =
|
|
164
|
+
var Progress = React18__namespace.forwardRef(
|
|
165
165
|
({ className, value = 0, tone = "primary", barClassName, ...props }, ref) => {
|
|
166
166
|
const pct = Math.max(0, Math.min(100, value));
|
|
167
167
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -191,8 +191,55 @@ var Progress = React17__namespace.forwardRef(
|
|
|
191
191
|
}
|
|
192
192
|
);
|
|
193
193
|
Progress.displayName = "Progress";
|
|
194
|
+
var Label = React18__namespace.forwardRef(
|
|
195
|
+
({ className, required, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("label", { ref, className: cn("text-[0.8rem] font-semibold text-foreground", className), ...props, children: [
|
|
196
|
+
children,
|
|
197
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-danger", children: " *" })
|
|
198
|
+
] })
|
|
199
|
+
);
|
|
200
|
+
Label.displayName = "Label";
|
|
201
|
+
var Hint = React18__namespace.forwardRef(
|
|
202
|
+
({ className, error, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
203
|
+
"span",
|
|
204
|
+
{
|
|
205
|
+
ref,
|
|
206
|
+
className: cn("text-[0.76rem]", error ? "text-danger" : "text-muted-foreground", className),
|
|
207
|
+
...props
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
);
|
|
211
|
+
Hint.displayName = "Hint";
|
|
212
|
+
var Field = React18__namespace.forwardRef(
|
|
213
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1.5", className), ...props })
|
|
214
|
+
);
|
|
215
|
+
Field.displayName = "Field";
|
|
216
|
+
var FormField = React18__namespace.forwardRef(
|
|
217
|
+
({ className, label, hint, error, required, children, ...props }, ref) => {
|
|
218
|
+
const id = React18__namespace.useId();
|
|
219
|
+
const hintId = `${id}-hint`;
|
|
220
|
+
const errorId = `${id}-error`;
|
|
221
|
+
const child = React18__namespace.Children.only(children);
|
|
222
|
+
const clonedChild = React18__namespace.cloneElement(child, {
|
|
223
|
+
id: child.props.id ?? id,
|
|
224
|
+
"aria-describedby": cn(
|
|
225
|
+
hint && hintId,
|
|
226
|
+
error && errorId,
|
|
227
|
+
child.props["aria-describedby"]
|
|
228
|
+
) || void 0,
|
|
229
|
+
"aria-invalid": error ? "true" : void 0,
|
|
230
|
+
required: child.props.required ?? required
|
|
231
|
+
});
|
|
232
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col gap-1.5 w-full", className), ...props, children: [
|
|
233
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: id, required, children: label }),
|
|
234
|
+
clonedChild,
|
|
235
|
+
hint && !error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: hintId, children: hint }),
|
|
236
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: errorId, error: true, children: error })
|
|
237
|
+
] });
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
FormField.displayName = "FormField";
|
|
194
241
|
var baseField = "w-full font-sans text-sm text-foreground bg-surface border rounded-kj-md px-[0.85rem] transition-[border-color,box-shadow] duration-150 placeholder:text-muted-foreground focus:outline-none focus:border-ring focus:ring-[3px] focus:ring-ring/30 disabled:bg-muted disabled:text-muted-foreground disabled:cursor-not-allowed";
|
|
195
|
-
var Input =
|
|
242
|
+
var Input = React18__namespace.forwardRef(
|
|
196
243
|
({ className, error, leadingIcon, style, ...props }, ref) => {
|
|
197
244
|
const field = /* @__PURE__ */ jsxRuntime.jsx(
|
|
198
245
|
"input",
|
|
@@ -217,7 +264,7 @@ var Input = React17__namespace.forwardRef(
|
|
|
217
264
|
}
|
|
218
265
|
);
|
|
219
266
|
Input.displayName = "Input";
|
|
220
|
-
var Textarea =
|
|
267
|
+
var Textarea = React18__namespace.forwardRef(
|
|
221
268
|
({ className, error, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
222
269
|
"textarea",
|
|
223
270
|
{
|
|
@@ -234,30 +281,14 @@ var Textarea = React17__namespace.forwardRef(
|
|
|
234
281
|
)
|
|
235
282
|
);
|
|
236
283
|
Textarea.displayName = "Textarea";
|
|
237
|
-
var
|
|
238
|
-
({
|
|
239
|
-
children,
|
|
240
|
-
|
|
241
|
-
] })
|
|
242
|
-
);
|
|
243
|
-
Label.displayName = "Label";
|
|
244
|
-
var Hint = React17__namespace.forwardRef(
|
|
245
|
-
({ className, error, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
246
|
-
"span",
|
|
247
|
-
{
|
|
248
|
-
ref,
|
|
249
|
-
className: cn("text-[0.76rem]", error ? "text-danger" : "text-muted-foreground", className),
|
|
250
|
-
...props
|
|
251
|
-
}
|
|
252
|
-
)
|
|
253
|
-
);
|
|
254
|
-
Hint.displayName = "Hint";
|
|
255
|
-
var Field = React17__namespace.forwardRef(
|
|
256
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1.5", className), ...props })
|
|
284
|
+
var TextField = React18__namespace.forwardRef(
|
|
285
|
+
({ label, hint, error, required, className, ...props }, ref) => {
|
|
286
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormField, { label, hint, error, required, className, children: /* @__PURE__ */ jsxRuntime.jsx(Input, { ref, error: !!error, ...props }) });
|
|
287
|
+
}
|
|
257
288
|
);
|
|
258
|
-
|
|
289
|
+
TextField.displayName = "TextField";
|
|
259
290
|
var chevron = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E";
|
|
260
|
-
var Select =
|
|
291
|
+
var Select = React18__namespace.forwardRef(
|
|
261
292
|
({ className, error, style, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
262
293
|
"select",
|
|
263
294
|
{
|
|
@@ -285,9 +316,15 @@ var Select = React17__namespace.forwardRef(
|
|
|
285
316
|
)
|
|
286
317
|
);
|
|
287
318
|
Select.displayName = "Select";
|
|
288
|
-
var
|
|
319
|
+
var SelectField = React18__namespace.forwardRef(
|
|
320
|
+
({ label, hint, error, required, className, children, ...props }, ref) => {
|
|
321
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormField, { label, hint, error, required, className, children: /* @__PURE__ */ jsxRuntime.jsx(Select, { ref, error: !!error, ...props, children }) });
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
SelectField.displayName = "SelectField";
|
|
325
|
+
var Checkbox = React18__namespace.forwardRef(
|
|
289
326
|
({ className, label, id, ...props }, ref) => {
|
|
290
|
-
const autoId =
|
|
327
|
+
const autoId = React18__namespace.useId();
|
|
291
328
|
const inputId = id ?? autoId;
|
|
292
329
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: inputId, className: cn("inline-flex items-center gap-2.5 cursor-pointer text-sm select-none", className), children: [
|
|
293
330
|
/* @__PURE__ */ jsxRuntime.jsx("input", { ref, id: inputId, type: "checkbox", className: "peer sr-only", ...props }),
|
|
@@ -297,9 +334,9 @@ var Checkbox = React17__namespace.forwardRef(
|
|
|
297
334
|
}
|
|
298
335
|
);
|
|
299
336
|
Checkbox.displayName = "Checkbox";
|
|
300
|
-
var Radio =
|
|
337
|
+
var Radio = React18__namespace.forwardRef(
|
|
301
338
|
({ className, label, id, ...props }, ref) => {
|
|
302
|
-
const autoId =
|
|
339
|
+
const autoId = React18__namespace.useId();
|
|
303
340
|
const inputId = id ?? autoId;
|
|
304
341
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: inputId, className: cn("inline-flex items-center gap-2.5 cursor-pointer text-sm select-none", className), children: [
|
|
305
342
|
/* @__PURE__ */ jsxRuntime.jsx("input", { ref, id: inputId, type: "radio", className: "peer sr-only", ...props }),
|
|
@@ -309,9 +346,32 @@ var Radio = React17__namespace.forwardRef(
|
|
|
309
346
|
}
|
|
310
347
|
);
|
|
311
348
|
Radio.displayName = "Radio";
|
|
312
|
-
var
|
|
349
|
+
var CheckboxField = React18__namespace.forwardRef(
|
|
350
|
+
({ label, hint, error, className, ...props }, ref) => {
|
|
351
|
+
const id = React18__namespace.useId();
|
|
352
|
+
const hintId = `${id}-hint`;
|
|
353
|
+
const errorId = `${id}-error`;
|
|
354
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1 w-full", className), children: [
|
|
355
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
356
|
+
Checkbox,
|
|
357
|
+
{
|
|
358
|
+
ref,
|
|
359
|
+
id,
|
|
360
|
+
label,
|
|
361
|
+
"aria-describedby": cn(hint && hintId, error && errorId) || void 0,
|
|
362
|
+
"aria-invalid": error ? "true" : void 0,
|
|
363
|
+
...props
|
|
364
|
+
}
|
|
365
|
+
),
|
|
366
|
+
hint && !error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: hintId, className: "pl-[1.8rem]", children: hint }),
|
|
367
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: errorId, error: true, className: "pl-[1.8rem]", children: error })
|
|
368
|
+
] });
|
|
369
|
+
}
|
|
370
|
+
);
|
|
371
|
+
CheckboxField.displayName = "CheckboxField";
|
|
372
|
+
var Switch = React18__namespace.forwardRef(
|
|
313
373
|
({ className, label, id, ...props }, ref) => {
|
|
314
|
-
const autoId =
|
|
374
|
+
const autoId = React18__namespace.useId();
|
|
315
375
|
const inputId = id ?? autoId;
|
|
316
376
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: inputId, className: cn("inline-flex items-center gap-2.5 cursor-pointer text-sm select-none", className), children: [
|
|
317
377
|
/* @__PURE__ */ jsxRuntime.jsx("input", { ref, id: inputId, type: "checkbox", role: "switch", className: "peer sr-only", ...props }),
|
|
@@ -321,7 +381,7 @@ var Switch = React17__namespace.forwardRef(
|
|
|
321
381
|
}
|
|
322
382
|
);
|
|
323
383
|
Switch.displayName = "Switch";
|
|
324
|
-
var Slider =
|
|
384
|
+
var Slider = React18__namespace.forwardRef(
|
|
325
385
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
326
386
|
"input",
|
|
327
387
|
{
|
|
@@ -374,7 +434,7 @@ function Segmented({
|
|
|
374
434
|
}
|
|
375
435
|
);
|
|
376
436
|
}
|
|
377
|
-
var Card =
|
|
437
|
+
var Card = React18__namespace.forwardRef(
|
|
378
438
|
({ as: Tag = "div", className, elevated, interactive, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
379
439
|
Tag,
|
|
380
440
|
{
|
|
@@ -390,23 +450,23 @@ var Card = React17__namespace.forwardRef(
|
|
|
390
450
|
)
|
|
391
451
|
);
|
|
392
452
|
Card.displayName = "Card";
|
|
393
|
-
var CardHeader =
|
|
453
|
+
var CardHeader = React18__namespace.forwardRef(
|
|
394
454
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("p-[1.35rem] flex flex-col gap-1", className), ...props })
|
|
395
455
|
);
|
|
396
456
|
CardHeader.displayName = "CardHeader";
|
|
397
|
-
var CardTitle =
|
|
457
|
+
var CardTitle = React18__namespace.forwardRef(
|
|
398
458
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, className: cn("m-0 text-base font-bold tracking-[-0.01em]", className), ...props })
|
|
399
459
|
);
|
|
400
460
|
CardTitle.displayName = "CardTitle";
|
|
401
|
-
var CardDescription =
|
|
461
|
+
var CardDescription = React18__namespace.forwardRef(
|
|
402
462
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("p", { ref, className: cn("m-0 text-[0.85rem] text-muted-foreground", className), ...props })
|
|
403
463
|
);
|
|
404
464
|
CardDescription.displayName = "CardDescription";
|
|
405
|
-
var CardContent =
|
|
465
|
+
var CardContent = React18__namespace.forwardRef(
|
|
406
466
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("px-[1.35rem] pb-[1.35rem]", className), ...props })
|
|
407
467
|
);
|
|
408
468
|
CardContent.displayName = "CardContent";
|
|
409
|
-
var CardFooter =
|
|
469
|
+
var CardFooter = React18__namespace.forwardRef(
|
|
410
470
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
411
471
|
"div",
|
|
412
472
|
{
|
|
@@ -417,7 +477,7 @@ var CardFooter = React17__namespace.forwardRef(
|
|
|
417
477
|
)
|
|
418
478
|
);
|
|
419
479
|
CardFooter.displayName = "CardFooter";
|
|
420
|
-
var Stat =
|
|
480
|
+
var Stat = React18__namespace.forwardRef(
|
|
421
481
|
({ className, label, value, delta, trend, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(Card, { ref, className: cn("p-[1.35rem] flex flex-col gap-2", className), ...props, children: [
|
|
422
482
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.78rem] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: label }),
|
|
423
483
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[2rem] font-bold tracking-[-0.03em] tabular-nums leading-none", children: value }),
|
|
@@ -457,7 +517,7 @@ var avatarVariants = classVarianceAuthority.cva(
|
|
|
457
517
|
defaultVariants: { size: "md", tone: "secondary" }
|
|
458
518
|
}
|
|
459
519
|
);
|
|
460
|
-
var Avatar =
|
|
520
|
+
var Avatar = React18__namespace.forwardRef(
|
|
461
521
|
({ className, size, tone, src, alt, status, children, ...props }, ref) => {
|
|
462
522
|
const node = /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn(avatarVariants({ size, tone }), "overflow-hidden", className), ...props, children: src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt, className: "h-full w-full object-cover" }) : children });
|
|
463
523
|
if (!status) return node;
|
|
@@ -468,20 +528,20 @@ var Avatar = React17__namespace.forwardRef(
|
|
|
468
528
|
}
|
|
469
529
|
);
|
|
470
530
|
Avatar.displayName = "Avatar";
|
|
471
|
-
var AvatarGroup =
|
|
531
|
+
var AvatarGroup = React18__namespace.forwardRef(
|
|
472
532
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex [&>*:not(:first-child)]:-ml-2.5", className), ...props })
|
|
473
533
|
);
|
|
474
534
|
AvatarGroup.displayName = "AvatarGroup";
|
|
475
|
-
var TabsContext =
|
|
535
|
+
var TabsContext = React18__namespace.createContext(null);
|
|
476
536
|
function useTabs() {
|
|
477
|
-
const ctx =
|
|
537
|
+
const ctx = React18__namespace.useContext(TabsContext);
|
|
478
538
|
if (!ctx) throw new Error("Tabs.* must be used within <Tabs>");
|
|
479
539
|
return ctx;
|
|
480
540
|
}
|
|
481
541
|
function Tabs({ value, defaultValue, onValueChange, className, children, ...props }) {
|
|
482
|
-
const [internal, setInternal] =
|
|
542
|
+
const [internal, setInternal] = React18__namespace.useState(defaultValue ?? "");
|
|
483
543
|
const current = value ?? internal;
|
|
484
|
-
const setValue =
|
|
544
|
+
const setValue = React18__namespace.useCallback(
|
|
485
545
|
(v) => {
|
|
486
546
|
if (value === void 0) setInternal(v);
|
|
487
547
|
onValueChange?.(v);
|
|
@@ -490,7 +550,7 @@ function Tabs({ value, defaultValue, onValueChange, className, children, ...prop
|
|
|
490
550
|
);
|
|
491
551
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, setValue }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, ...props, children }) });
|
|
492
552
|
}
|
|
493
|
-
var TabsList =
|
|
553
|
+
var TabsList = React18__namespace.forwardRef(
|
|
494
554
|
({ className, onKeyDown, ...props }, ref) => {
|
|
495
555
|
const handleKeyDown = (e) => {
|
|
496
556
|
const container = e.currentTarget;
|
|
@@ -534,7 +594,7 @@ var TabsList = React17__namespace.forwardRef(
|
|
|
534
594
|
}
|
|
535
595
|
);
|
|
536
596
|
TabsList.displayName = "TabsList";
|
|
537
|
-
var TabsTrigger =
|
|
597
|
+
var TabsTrigger = React18__namespace.forwardRef(
|
|
538
598
|
({ className, value, children, ...props }, ref) => {
|
|
539
599
|
const { value: current, setValue } = useTabs();
|
|
540
600
|
const active = current === value;
|
|
@@ -563,7 +623,7 @@ var TabsTrigger = React17__namespace.forwardRef(
|
|
|
563
623
|
}
|
|
564
624
|
);
|
|
565
625
|
TabsTrigger.displayName = "TabsTrigger";
|
|
566
|
-
var TabsContent =
|
|
626
|
+
var TabsContent = React18__namespace.forwardRef(
|
|
567
627
|
({ className, value, ...props }, ref) => {
|
|
568
628
|
const { value: current } = useTabs();
|
|
569
629
|
const active = current === value;
|
|
@@ -583,10 +643,10 @@ var TabsContent = React17__namespace.forwardRef(
|
|
|
583
643
|
}
|
|
584
644
|
);
|
|
585
645
|
TabsContent.displayName = "TabsContent";
|
|
586
|
-
var AccordionContext =
|
|
646
|
+
var AccordionContext = React18__namespace.createContext(null);
|
|
587
647
|
function Accordion({ type = "single", defaultValue = [], className, children, ...props }) {
|
|
588
|
-
const [open, setOpen] =
|
|
589
|
-
const toggle =
|
|
648
|
+
const [open, setOpen] = React18__namespace.useState(defaultValue);
|
|
649
|
+
const toggle = React18__namespace.useCallback(
|
|
590
650
|
(v) => {
|
|
591
651
|
setOpen((prev) => {
|
|
592
652
|
const isOpen = prev.includes(v);
|
|
@@ -598,15 +658,15 @@ function Accordion({ type = "single", defaultValue = [], className, children, ..
|
|
|
598
658
|
);
|
|
599
659
|
return /* @__PURE__ */ jsxRuntime.jsx(AccordionContext.Provider, { value: { open, toggle }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("border border-border rounded-kj-lg overflow-hidden", className), ...props, children }) });
|
|
600
660
|
}
|
|
601
|
-
var ItemContext =
|
|
602
|
-
var AccordionItem =
|
|
661
|
+
var ItemContext = React18__namespace.createContext("");
|
|
662
|
+
var AccordionItem = React18__namespace.forwardRef(
|
|
603
663
|
({ className, value, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(ItemContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("border-t border-border first:border-t-0", className), ...props }) })
|
|
604
664
|
);
|
|
605
665
|
AccordionItem.displayName = "AccordionItem";
|
|
606
|
-
var AccordionTrigger =
|
|
666
|
+
var AccordionTrigger = React18__namespace.forwardRef(
|
|
607
667
|
({ className, children, ...props }, ref) => {
|
|
608
|
-
const ctx =
|
|
609
|
-
const value =
|
|
668
|
+
const ctx = React18__namespace.useContext(AccordionContext);
|
|
669
|
+
const value = React18__namespace.useContext(ItemContext);
|
|
610
670
|
const isOpen = ctx.open.includes(value);
|
|
611
671
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
612
672
|
"button",
|
|
@@ -643,10 +703,10 @@ var AccordionTrigger = React17__namespace.forwardRef(
|
|
|
643
703
|
}
|
|
644
704
|
);
|
|
645
705
|
AccordionTrigger.displayName = "AccordionTrigger";
|
|
646
|
-
var AccordionContent =
|
|
706
|
+
var AccordionContent = React18__namespace.forwardRef(
|
|
647
707
|
({ className, children, ...props }, ref) => {
|
|
648
|
-
const ctx =
|
|
649
|
-
const value =
|
|
708
|
+
const ctx = React18__namespace.useContext(AccordionContext);
|
|
709
|
+
const value = React18__namespace.useContext(ItemContext);
|
|
650
710
|
const isOpen = ctx.open.includes(value);
|
|
651
711
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
652
712
|
"div",
|
|
@@ -654,17 +714,17 @@ var AccordionContent = React17__namespace.forwardRef(
|
|
|
654
714
|
ref,
|
|
655
715
|
className: cn("grid transition-[grid-template-rows] duration-200 ease-out", isOpen ? "[grid-template-rows:1fr]" : "[grid-template-rows:0fr]"),
|
|
656
716
|
...props,
|
|
657
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-[1.2rem] pb-
|
|
717
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("px-[1.2rem] pt-3 pb-4 text-[0.85rem] text-muted-foreground", className), children }) })
|
|
658
718
|
}
|
|
659
719
|
);
|
|
660
720
|
}
|
|
661
721
|
);
|
|
662
722
|
AccordionContent.displayName = "AccordionContent";
|
|
663
|
-
var MenuContext =
|
|
723
|
+
var MenuContext = React18__namespace.createContext(null);
|
|
664
724
|
function DropdownMenu({ children, className }) {
|
|
665
|
-
const [open, setOpen] =
|
|
666
|
-
const ref =
|
|
667
|
-
|
|
725
|
+
const [open, setOpen] = React18__namespace.useState(false);
|
|
726
|
+
const ref = React18__namespace.useRef(null);
|
|
727
|
+
React18__namespace.useEffect(() => {
|
|
668
728
|
if (!open) return;
|
|
669
729
|
const onDoc = (e) => {
|
|
670
730
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -679,11 +739,11 @@ function DropdownMenu({ children, className }) {
|
|
|
679
739
|
}, [open]);
|
|
680
740
|
return /* @__PURE__ */ jsxRuntime.jsx(MenuContext.Provider, { value: { open, setOpen }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative inline-block", className), children }) });
|
|
681
741
|
}
|
|
682
|
-
var DropdownMenuTrigger =
|
|
683
|
-
const ctx =
|
|
742
|
+
var DropdownMenuTrigger = React18__namespace.forwardRef(({ onClick, asChild, ...props }, ref) => {
|
|
743
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
684
744
|
if (asChild) {
|
|
685
|
-
const child =
|
|
686
|
-
return
|
|
745
|
+
const child = React18__namespace.Children.only(props.children);
|
|
746
|
+
return React18__namespace.cloneElement(child, {
|
|
687
747
|
ref,
|
|
688
748
|
...props,
|
|
689
749
|
...child.props,
|
|
@@ -713,9 +773,9 @@ var DropdownMenuTrigger = React17__namespace.forwardRef(({ onClick, asChild, ...
|
|
|
713
773
|
});
|
|
714
774
|
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
|
|
715
775
|
function DropdownMenuContent({ className, align = "start", children, ...props }) {
|
|
716
|
-
const ctx =
|
|
717
|
-
const ref =
|
|
718
|
-
|
|
776
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
777
|
+
const ref = React18__namespace.useRef(null);
|
|
778
|
+
React18__namespace.useEffect(() => {
|
|
719
779
|
if (!ctx.open) return;
|
|
720
780
|
const container = ref.current;
|
|
721
781
|
if (container) {
|
|
@@ -762,9 +822,9 @@ function DropdownMenuContent({ className, align = "start", children, ...props })
|
|
|
762
822
|
}
|
|
763
823
|
);
|
|
764
824
|
}
|
|
765
|
-
var DropdownMenuItem =
|
|
825
|
+
var DropdownMenuItem = React18__namespace.forwardRef(
|
|
766
826
|
({ className, danger, icon, children, onClick, ...props }, ref) => {
|
|
767
|
-
const ctx =
|
|
827
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
768
828
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
769
829
|
"button",
|
|
770
830
|
{
|
|
@@ -794,11 +854,11 @@ DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
|
794
854
|
function DropdownMenuSeparator({ className }) {
|
|
795
855
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("h-px bg-border my-1.5", className), role: "separator" });
|
|
796
856
|
}
|
|
797
|
-
var Breadcrumb =
|
|
857
|
+
var Breadcrumb = React18__namespace.forwardRef(
|
|
798
858
|
({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("nav", { ref, "aria-label": "Breadcrumb", className: cn("flex items-center gap-1.5 text-[0.85rem] text-muted-foreground", className), ...props, children })
|
|
799
859
|
);
|
|
800
860
|
Breadcrumb.displayName = "Breadcrumb";
|
|
801
|
-
var BreadcrumbItem =
|
|
861
|
+
var BreadcrumbItem = React18__namespace.forwardRef(
|
|
802
862
|
({ className, current, children, ...props }, ref) => {
|
|
803
863
|
if (current) {
|
|
804
864
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-current": "page", className: cn("text-foreground font-semibold", className), children });
|
|
@@ -845,27 +905,99 @@ function Pagination({ page, pageCount, onPageChange, className }) {
|
|
|
845
905
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Next", disabled: page >= pageCount, onClick: () => onPageChange(page + 1), children: /* @__PURE__ */ jsxRuntime.jsx(Chevron, { dir: "right" }) })
|
|
846
906
|
] });
|
|
847
907
|
}
|
|
848
|
-
var
|
|
849
|
-
({ className,
|
|
908
|
+
var BottomNavigation = React18__namespace.forwardRef(
|
|
909
|
+
({ className, items, showLabels = "always", fixed = true, ...props }, ref) => {
|
|
910
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
911
|
+
"nav",
|
|
912
|
+
{
|
|
913
|
+
ref,
|
|
914
|
+
className: cn(
|
|
915
|
+
"bg-surface/90 border-t border-border flex items-center justify-around px-4 pt-2 pb-[calc(0.75rem+env(safe-area-inset-bottom,0))] shadow-kj-lg",
|
|
916
|
+
fixed ? "fixed bottom-0 left-0 right-0 z-40 backdrop-blur-md" : "relative w-full",
|
|
917
|
+
className
|
|
918
|
+
),
|
|
919
|
+
...props,
|
|
920
|
+
children: items.map((item) => {
|
|
921
|
+
const isActive = item.active;
|
|
922
|
+
const showLabel = showLabels !== "never" && (showLabels === "always" || isActive);
|
|
923
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-center justify-center gap-1 w-full relative", children: [
|
|
924
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
925
|
+
"span",
|
|
926
|
+
{
|
|
927
|
+
className: cn(
|
|
928
|
+
"relative flex items-center justify-center p-1 rounded-full transition-all duration-200",
|
|
929
|
+
isActive ? "text-primary scale-110" : "text-muted-foreground group-hover:text-foreground group-active:scale-95"
|
|
930
|
+
),
|
|
931
|
+
children: [
|
|
932
|
+
item.icon,
|
|
933
|
+
item.badge !== void 0 && item.badge !== null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 -right-1.5 min-w-[16px] h-[16px] px-1 rounded-full bg-primary text-primary-foreground text-[9px] font-bold flex items-center justify-center ring-2 ring-surface", children: item.badge })
|
|
934
|
+
]
|
|
935
|
+
}
|
|
936
|
+
),
|
|
937
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
938
|
+
"span",
|
|
939
|
+
{
|
|
940
|
+
className: cn(
|
|
941
|
+
"text-[10px] font-semibold tracking-wide transition-all duration-200 select-none",
|
|
942
|
+
showLabel ? "opacity-100 scale-100 h-auto" : "opacity-0 scale-75 h-0 overflow-hidden",
|
|
943
|
+
isActive ? "text-primary font-bold" : "text-muted-foreground group-hover:text-foreground"
|
|
944
|
+
),
|
|
945
|
+
children: item.label
|
|
946
|
+
}
|
|
947
|
+
),
|
|
948
|
+
isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-1.5 w-1 h-1 rounded-full bg-primary animate-fade-in" })
|
|
949
|
+
] });
|
|
950
|
+
const itemClass = "group flex-1 flex flex-col items-center justify-center py-1 cursor-pointer transition-all duration-150 relative focus:outline-none";
|
|
951
|
+
if (item.href) {
|
|
952
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
953
|
+
"a",
|
|
954
|
+
{
|
|
955
|
+
href: item.href,
|
|
956
|
+
className: itemClass,
|
|
957
|
+
"aria-current": isActive ? "page" : void 0,
|
|
958
|
+
children: content
|
|
959
|
+
},
|
|
960
|
+
item.id
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
964
|
+
"button",
|
|
965
|
+
{
|
|
966
|
+
type: "button",
|
|
967
|
+
onClick: item.onClick,
|
|
968
|
+
className: itemClass,
|
|
969
|
+
"aria-pressed": isActive,
|
|
970
|
+
children: content
|
|
971
|
+
},
|
|
972
|
+
item.id
|
|
973
|
+
);
|
|
974
|
+
})
|
|
975
|
+
}
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
);
|
|
979
|
+
BottomNavigation.displayName = "BottomNavigation";
|
|
980
|
+
var TableWrap = React18__namespace.forwardRef(
|
|
981
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("border border-border rounded-kj-lg overflow-x-auto w-full", className), ...props })
|
|
850
982
|
);
|
|
851
983
|
TableWrap.displayName = "TableWrap";
|
|
852
|
-
var Table =
|
|
984
|
+
var Table = React18__namespace.forwardRef(
|
|
853
985
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("table", { ref, className: cn("w-full border-collapse text-[0.85rem]", className), ...props })
|
|
854
986
|
);
|
|
855
987
|
Table.displayName = "Table";
|
|
856
|
-
var TableHeader =
|
|
988
|
+
var TableHeader = React18__namespace.forwardRef(
|
|
857
989
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className, ...props })
|
|
858
990
|
);
|
|
859
991
|
TableHeader.displayName = "TableHeader";
|
|
860
|
-
var TableBody =
|
|
992
|
+
var TableBody = React18__namespace.forwardRef(
|
|
861
993
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className, ...props })
|
|
862
994
|
);
|
|
863
995
|
TableBody.displayName = "TableBody";
|
|
864
|
-
var TableRow =
|
|
996
|
+
var TableRow = React18__namespace.forwardRef(
|
|
865
997
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tr", { ref, className: cn("transition-colors hover:bg-muted/50", className), ...props })
|
|
866
998
|
);
|
|
867
999
|
TableRow.displayName = "TableRow";
|
|
868
|
-
var TableHead =
|
|
1000
|
+
var TableHead = React18__namespace.forwardRef(
|
|
869
1001
|
({ className, numeric, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
870
1002
|
"th",
|
|
871
1003
|
{
|
|
@@ -880,7 +1012,7 @@ var TableHead = React17__namespace.forwardRef(
|
|
|
880
1012
|
)
|
|
881
1013
|
);
|
|
882
1014
|
TableHead.displayName = "TableHead";
|
|
883
|
-
var TableCell =
|
|
1015
|
+
var TableCell = React18__namespace.forwardRef(
|
|
884
1016
|
({ className, numeric, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
885
1017
|
"td",
|
|
886
1018
|
{
|
|
@@ -913,13 +1045,13 @@ function Tooltip({ content, children, className }) {
|
|
|
913
1045
|
)
|
|
914
1046
|
] });
|
|
915
1047
|
}
|
|
916
|
-
var ModalContext =
|
|
1048
|
+
var ModalContext = React18__namespace.createContext(null);
|
|
917
1049
|
function Modal({ open, onClose, children, width = 440, className, showClose = true }) {
|
|
918
|
-
const titleId =
|
|
919
|
-
const descId =
|
|
920
|
-
const containerRef =
|
|
921
|
-
const lastActiveElement =
|
|
922
|
-
|
|
1050
|
+
const titleId = React18__namespace.useId();
|
|
1051
|
+
const descId = React18__namespace.useId();
|
|
1052
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1053
|
+
const lastActiveElement = React18__namespace.useRef(null);
|
|
1054
|
+
React18__namespace.useEffect(() => {
|
|
923
1055
|
if (!open) {
|
|
924
1056
|
if (lastActiveElement.current) {
|
|
925
1057
|
lastActiveElement.current.focus();
|
|
@@ -1021,19 +1153,19 @@ function Modal({ open, onClose, children, width = 440, className, showClose = tr
|
|
|
1021
1153
|
);
|
|
1022
1154
|
}
|
|
1023
1155
|
function ModalTitle({ className, id, ...props }) {
|
|
1024
|
-
const ctx =
|
|
1156
|
+
const ctx = React18__namespace.useContext(ModalContext);
|
|
1025
1157
|
return /* @__PURE__ */ jsxRuntime.jsx("h3", { id: id ?? ctx?.titleId, className: cn("m-0 mb-2 text-[1.15rem] font-bold tracking-[-0.01em]", className), ...props });
|
|
1026
1158
|
}
|
|
1027
1159
|
function ModalDescription({ className, id, ...props }) {
|
|
1028
|
-
const ctx =
|
|
1160
|
+
const ctx = React18__namespace.useContext(ModalContext);
|
|
1029
1161
|
return /* @__PURE__ */ jsxRuntime.jsx("p", { id: id ?? ctx?.descId, className: cn("m-0 text-[0.9rem] text-muted-foreground", className), ...props });
|
|
1030
1162
|
}
|
|
1031
1163
|
function ModalActions({ className, ...props }) {
|
|
1032
1164
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex gap-2.5 justify-end mt-6", className), ...props });
|
|
1033
1165
|
}
|
|
1034
|
-
var ToastContext =
|
|
1166
|
+
var ToastContext = React18__namespace.createContext(null);
|
|
1035
1167
|
function useToast() {
|
|
1036
|
-
const ctx =
|
|
1168
|
+
const ctx = React18__namespace.useContext(ToastContext);
|
|
1037
1169
|
if (!ctx) throw new Error("useToast must be used within <ToastProvider>");
|
|
1038
1170
|
return ctx;
|
|
1039
1171
|
}
|
|
@@ -1054,13 +1186,13 @@ var toneBorder = {
|
|
|
1054
1186
|
danger: "border-l-danger"
|
|
1055
1187
|
};
|
|
1056
1188
|
function ToastProvider({ children }) {
|
|
1057
|
-
const [items, setItems] =
|
|
1058
|
-
const idRef =
|
|
1059
|
-
const remove =
|
|
1189
|
+
const [items, setItems] = React18__namespace.useState([]);
|
|
1190
|
+
const idRef = React18__namespace.useRef(0);
|
|
1191
|
+
const remove = React18__namespace.useCallback((id) => {
|
|
1060
1192
|
setItems((prev) => prev.map((t) => t.id === id ? { ...t, leaving: true } : t));
|
|
1061
1193
|
setTimeout(() => setItems((prev) => prev.filter((t) => t.id !== id)), 250);
|
|
1062
1194
|
}, []);
|
|
1063
|
-
const toast =
|
|
1195
|
+
const toast = React18__namespace.useCallback(
|
|
1064
1196
|
({ message, tone = "default", duration = 3200 }) => {
|
|
1065
1197
|
const id = ++idRef.current;
|
|
1066
1198
|
setItems((prev) => [...prev, { id, message, tone, duration }]);
|
|
@@ -1090,7 +1222,7 @@ function ToastProvider({ children }) {
|
|
|
1090
1222
|
)) })
|
|
1091
1223
|
] });
|
|
1092
1224
|
}
|
|
1093
|
-
var PageHeader =
|
|
1225
|
+
var PageHeader = React18__namespace.forwardRef(
|
|
1094
1226
|
({ eyebrow, title, description, actions }, ref) => /* @__PURE__ */ jsxRuntime.jsx("header", { ref, className: "py-12 md:py-16", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6 md:flex-row md:items-end md:justify-between", children: [
|
|
1095
1227
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 max-w-2xl", children: [
|
|
1096
1228
|
eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-xs font-bold uppercase tracking-[0.2em] text-primary", children: eyebrow }),
|
|
@@ -1101,7 +1233,7 @@ var PageHeader = React17__namespace.forwardRef(
|
|
|
1101
1233
|
] }) })
|
|
1102
1234
|
);
|
|
1103
1235
|
PageHeader.displayName = "PageHeader";
|
|
1104
|
-
var EmptyState =
|
|
1236
|
+
var EmptyState = React18__namespace.forwardRef(
|
|
1105
1237
|
({ className, icon, title, description, action, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1106
1238
|
"div",
|
|
1107
1239
|
{
|
|
@@ -1121,7 +1253,7 @@ var EmptyState = React17__namespace.forwardRef(
|
|
|
1121
1253
|
)
|
|
1122
1254
|
);
|
|
1123
1255
|
EmptyState.displayName = "EmptyState";
|
|
1124
|
-
var MetricCard =
|
|
1256
|
+
var MetricCard = React18__namespace.forwardRef(
|
|
1125
1257
|
({ className, title, value, trend, trendDirection = "neutral", description, icon, ...props }, ref) => {
|
|
1126
1258
|
const trendColor = {
|
|
1127
1259
|
up: "text-success bg-success-surface border-success/20",
|
|
@@ -1151,28 +1283,755 @@ function DataTable({
|
|
|
1151
1283
|
emptyTitle = "No data available",
|
|
1152
1284
|
emptyDescription = "There are no records to display at this time.",
|
|
1153
1285
|
emptyAction,
|
|
1286
|
+
getRowKey,
|
|
1287
|
+
onRowClick,
|
|
1288
|
+
toolbar,
|
|
1289
|
+
pagination,
|
|
1290
|
+
selectedRows,
|
|
1291
|
+
onSelectionChange,
|
|
1292
|
+
sortBy,
|
|
1293
|
+
sortDirection,
|
|
1294
|
+
onSort,
|
|
1154
1295
|
...props
|
|
1155
1296
|
}) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1297
|
+
const getRowId = React18__namespace.useCallback(
|
|
1298
|
+
(row, index) => getRowKey ? getRowKey(row, index) : index,
|
|
1299
|
+
[getRowKey]
|
|
1300
|
+
);
|
|
1301
|
+
const isSelectionActive = selectedRows !== void 0 && onSelectionChange !== void 0;
|
|
1302
|
+
const allSelected = React18__namespace.useMemo(() => {
|
|
1303
|
+
if (!isSelectionActive || data.length === 0) return false;
|
|
1304
|
+
return data.every((row, idx) => selectedRows.has(getRowId(row, idx)));
|
|
1305
|
+
}, [isSelectionActive, data, selectedRows, getRowId]);
|
|
1306
|
+
const someSelected = React18__namespace.useMemo(() => {
|
|
1307
|
+
if (!isSelectionActive || data.length === 0) return false;
|
|
1308
|
+
const selectedCount = data.filter((row, idx) => selectedRows.has(getRowId(row, idx))).length;
|
|
1309
|
+
return selectedCount > 0 && selectedCount < data.length;
|
|
1310
|
+
}, [isSelectionActive, data, selectedRows, getRowId]);
|
|
1311
|
+
const headerCheckboxRef = React18__namespace.useRef(null);
|
|
1312
|
+
React18__namespace.useEffect(() => {
|
|
1313
|
+
if (headerCheckboxRef.current) {
|
|
1314
|
+
headerCheckboxRef.current.indeterminate = someSelected;
|
|
1315
|
+
}
|
|
1316
|
+
}, [someSelected]);
|
|
1317
|
+
const handleSelectAll = (e) => {
|
|
1318
|
+
if (!onSelectionChange) return;
|
|
1319
|
+
const checked = e.target.checked;
|
|
1320
|
+
const next = new Set(selectedRows);
|
|
1321
|
+
data.forEach((row, idx) => {
|
|
1322
|
+
const id = getRowId(row, idx);
|
|
1323
|
+
if (checked) {
|
|
1324
|
+
next.add(id);
|
|
1325
|
+
} else {
|
|
1326
|
+
next.delete(id);
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
onSelectionChange(next);
|
|
1330
|
+
};
|
|
1331
|
+
const handleSelectRow = (row, idx, checked) => {
|
|
1332
|
+
if (!onSelectionChange || !selectedRows) return;
|
|
1333
|
+
const id = getRowId(row, idx);
|
|
1334
|
+
const next = new Set(selectedRows);
|
|
1335
|
+
if (checked) {
|
|
1336
|
+
next.add(id);
|
|
1337
|
+
} else {
|
|
1338
|
+
next.delete(id);
|
|
1339
|
+
}
|
|
1340
|
+
onSelectionChange(next);
|
|
1341
|
+
};
|
|
1342
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-4 w-full", className), children: [
|
|
1343
|
+
toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3", children: toolbar }),
|
|
1344
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TableWrap, { className: "relative overflow-hidden", ...props, children: [
|
|
1345
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
|
|
1346
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
|
|
1347
|
+
isSelectionActive && /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "w-12 px-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1348
|
+
"input",
|
|
1349
|
+
{
|
|
1350
|
+
type: "checkbox",
|
|
1351
|
+
ref: headerCheckboxRef,
|
|
1352
|
+
checked: allSelected,
|
|
1353
|
+
onChange: handleSelectAll,
|
|
1354
|
+
"aria-label": "Select all rows",
|
|
1355
|
+
className: "h-4 w-4 rounded border-input text-primary focus:ring-ring"
|
|
1356
|
+
}
|
|
1357
|
+
) }) }),
|
|
1358
|
+
columns.map((col, idx) => {
|
|
1359
|
+
const alignClass = {
|
|
1360
|
+
left: "text-left",
|
|
1361
|
+
center: "text-center",
|
|
1362
|
+
right: "text-right"
|
|
1363
|
+
}[col.align || "left"];
|
|
1364
|
+
const isSortable = col.sortable && onSort && col.sortKey;
|
|
1365
|
+
const isSortedActive = sortBy && col.sortKey === sortBy;
|
|
1366
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1367
|
+
TableHead,
|
|
1368
|
+
{
|
|
1369
|
+
className: cn(
|
|
1370
|
+
alignClass,
|
|
1371
|
+
isSortable && "cursor-pointer select-none hover:bg-muted/30 transition-colors",
|
|
1372
|
+
col.className
|
|
1373
|
+
),
|
|
1374
|
+
onClick: () => {
|
|
1375
|
+
if (!isSortable || !col.sortKey) return;
|
|
1376
|
+
const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
|
|
1377
|
+
onSort(col.sortKey, nextDirection);
|
|
1378
|
+
},
|
|
1379
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: [
|
|
1380
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: col.header }),
|
|
1381
|
+
isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
|
|
1382
|
+
] })
|
|
1383
|
+
},
|
|
1384
|
+
idx
|
|
1385
|
+
);
|
|
1386
|
+
})
|
|
1387
|
+
] }) }),
|
|
1388
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: loading && data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: columns.length + (isSelectionActive ? 1 : 0), className: "h-64 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center gap-3", children: [
|
|
1389
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }),
|
|
1390
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Loading dataset..." })
|
|
1391
|
+
] }) }) }) : error ? /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: columns.length + (isSelectionActive ? 1 : 0), className: "p-8", children: /* @__PURE__ */ jsxRuntime.jsx(Alert, { variant: "danger", title: "Error loading data", children: error }) }) }) : data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: columns.length + (isSelectionActive ? 1 : 0), className: "p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1392
|
+
EmptyState,
|
|
1393
|
+
{
|
|
1394
|
+
title: emptyTitle,
|
|
1395
|
+
description: emptyDescription,
|
|
1396
|
+
action: emptyAction,
|
|
1397
|
+
className: "border-none bg-transparent rounded-none py-16"
|
|
1398
|
+
}
|
|
1399
|
+
) }) }) : data.map((row, rowIdx) => {
|
|
1400
|
+
const rowKey = getRowId(row, rowIdx);
|
|
1401
|
+
const isSelected = isSelectionActive && selectedRows.has(rowKey);
|
|
1402
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1403
|
+
TableRow,
|
|
1404
|
+
{
|
|
1405
|
+
onClick: () => onRowClick && onRowClick(row),
|
|
1406
|
+
className: cn(
|
|
1407
|
+
onRowClick && "cursor-pointer hover:bg-muted/40 transition-colors",
|
|
1408
|
+
isSelected && "bg-primary/5 hover:bg-primary/10"
|
|
1409
|
+
),
|
|
1410
|
+
children: [
|
|
1411
|
+
isSelectionActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1412
|
+
TableCell,
|
|
1413
|
+
{
|
|
1414
|
+
className: "w-12 px-4 text-center",
|
|
1415
|
+
onClick: (e) => {
|
|
1416
|
+
e.stopPropagation();
|
|
1417
|
+
},
|
|
1418
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1419
|
+
"input",
|
|
1420
|
+
{
|
|
1421
|
+
type: "checkbox",
|
|
1422
|
+
checked: isSelected,
|
|
1423
|
+
onChange: (e) => handleSelectRow(row, rowIdx, e.target.checked),
|
|
1424
|
+
"aria-label": `Select row ${rowIdx + 1}`,
|
|
1425
|
+
className: "h-4 w-4 rounded border-input text-primary focus:ring-ring"
|
|
1426
|
+
}
|
|
1427
|
+
) })
|
|
1428
|
+
}
|
|
1429
|
+
),
|
|
1430
|
+
columns.map((col, colIdx) => {
|
|
1431
|
+
const alignClass = {
|
|
1432
|
+
left: "text-left",
|
|
1433
|
+
center: "text-center",
|
|
1434
|
+
right: "text-right"
|
|
1435
|
+
}[col.align || "left"];
|
|
1436
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: cn(alignClass, col.className), children: col.accessor(row) }, colIdx);
|
|
1437
|
+
})
|
|
1438
|
+
]
|
|
1439
|
+
},
|
|
1440
|
+
rowKey
|
|
1441
|
+
);
|
|
1442
|
+
}) })
|
|
1443
|
+
] }),
|
|
1444
|
+
loading && data.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-background/50 backdrop-blur-[1px] grid place-items-center z-10 transition-opacity duration-150", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 36 }) })
|
|
1171
1445
|
] }),
|
|
1172
|
-
|
|
1446
|
+
pagination && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end w-full", children: pagination })
|
|
1173
1447
|
] });
|
|
1174
1448
|
}
|
|
1175
1449
|
DataTable.displayName = "DataTable";
|
|
1450
|
+
var ErrorState = React18__namespace.forwardRef(
|
|
1451
|
+
({ className, title = "Wyst\u0105pi\u0142 b\u0142\u0105d", message, onRetry, retryLabel = "Spr\xF3buj ponownie", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1452
|
+
"div",
|
|
1453
|
+
{
|
|
1454
|
+
ref,
|
|
1455
|
+
className: cn(
|
|
1456
|
+
"flex flex-col items-center justify-center text-center p-8 border border-danger/25 rounded-kj-lg bg-danger-surface/20 min-h-[300px]",
|
|
1457
|
+
className
|
|
1458
|
+
),
|
|
1459
|
+
...props,
|
|
1460
|
+
children: [
|
|
1461
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-danger-surface border border-danger/30 text-danger mb-4", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "none", stroke: "currentColor", strokeWidth: 2.5, viewBox: "0 0 24 24", className: "h-6 w-6", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" }) }) }),
|
|
1462
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground mb-1", children: title }),
|
|
1463
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm mb-6 leading-relaxed", children: message }),
|
|
1464
|
+
onRetry && /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "danger", onClick: onRetry, children: retryLabel })
|
|
1465
|
+
]
|
|
1466
|
+
}
|
|
1467
|
+
)
|
|
1468
|
+
);
|
|
1469
|
+
ErrorState.displayName = "ErrorState";
|
|
1470
|
+
var Skeleton = React18__namespace.forwardRef(
|
|
1471
|
+
({ className, variant = "rectangular", width, height, style, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1472
|
+
"div",
|
|
1473
|
+
{
|
|
1474
|
+
ref,
|
|
1475
|
+
className: cn(
|
|
1476
|
+
"animate-pulse bg-muted/40",
|
|
1477
|
+
variant === "text" && "h-3 w-4/5 rounded-sm my-1.5",
|
|
1478
|
+
variant === "circular" && "rounded-full",
|
|
1479
|
+
variant === "rectangular" && "rounded-kj-md",
|
|
1480
|
+
className
|
|
1481
|
+
),
|
|
1482
|
+
style: {
|
|
1483
|
+
width,
|
|
1484
|
+
height,
|
|
1485
|
+
...style
|
|
1486
|
+
},
|
|
1487
|
+
...props
|
|
1488
|
+
}
|
|
1489
|
+
)
|
|
1490
|
+
);
|
|
1491
|
+
Skeleton.displayName = "Skeleton";
|
|
1492
|
+
var DashboardShell = React18__namespace.forwardRef(
|
|
1493
|
+
({
|
|
1494
|
+
className,
|
|
1495
|
+
sidebar,
|
|
1496
|
+
topbar,
|
|
1497
|
+
children,
|
|
1498
|
+
sidebarWidth = "md:w-64",
|
|
1499
|
+
contentWidth = "default",
|
|
1500
|
+
stickyTopbar = true,
|
|
1501
|
+
mobileSidebar,
|
|
1502
|
+
...props
|
|
1503
|
+
}, ref) => {
|
|
1504
|
+
const [mobileOpen, setMobileOpen] = React18__namespace.useState(false);
|
|
1505
|
+
const contentWidthClass = {
|
|
1506
|
+
default: "max-w-7xl w-full mx-auto",
|
|
1507
|
+
wide: "max-w-screen-2xl w-full mx-auto",
|
|
1508
|
+
full: "max-w-none w-full"
|
|
1509
|
+
}[contentWidth];
|
|
1510
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1511
|
+
"div",
|
|
1512
|
+
{
|
|
1513
|
+
ref,
|
|
1514
|
+
className: cn(
|
|
1515
|
+
"min-h-screen bg-canvas text-foreground flex flex-col md:flex-row",
|
|
1516
|
+
className
|
|
1517
|
+
),
|
|
1518
|
+
...props,
|
|
1519
|
+
children: [
|
|
1520
|
+
sidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1521
|
+
"aside",
|
|
1522
|
+
{
|
|
1523
|
+
className: cn(
|
|
1524
|
+
"border-r border-border bg-surface shrink-0 z-20",
|
|
1525
|
+
mobileSidebar ? "hidden md:flex" : "w-full md:flex",
|
|
1526
|
+
sidebarWidth
|
|
1527
|
+
),
|
|
1528
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("sticky top-0 w-full flex flex-col", mobileSidebar ? "h-screen" : "h-auto md:h-screen"), children: sidebar })
|
|
1529
|
+
}
|
|
1530
|
+
),
|
|
1531
|
+
mobileSidebar && mobileOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1532
|
+
"div",
|
|
1533
|
+
{
|
|
1534
|
+
onClick: () => setMobileOpen(false),
|
|
1535
|
+
className: "fixed inset-0 z-50 md:hidden bg-[color-mix(in_oklch,#09090b_45%,transparent)] backdrop-blur-[2px] transition-opacity duration-300",
|
|
1536
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1537
|
+
"aside",
|
|
1538
|
+
{
|
|
1539
|
+
onClick: (e) => e.stopPropagation(),
|
|
1540
|
+
className: "w-72 h-full bg-surface border-r border-border flex flex-col shadow-kj-lg",
|
|
1541
|
+
children: [
|
|
1542
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-border", children: [
|
|
1543
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-bold uppercase tracking-wider text-muted-foreground", children: "Navigation" }),
|
|
1544
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1545
|
+
"button",
|
|
1546
|
+
{
|
|
1547
|
+
type: "button",
|
|
1548
|
+
onClick: () => setMobileOpen(false),
|
|
1549
|
+
className: "p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer",
|
|
1550
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
1551
|
+
}
|
|
1552
|
+
)
|
|
1553
|
+
] }),
|
|
1554
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: mobileSidebar })
|
|
1555
|
+
]
|
|
1556
|
+
}
|
|
1557
|
+
)
|
|
1558
|
+
}
|
|
1559
|
+
),
|
|
1560
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [
|
|
1561
|
+
topbar && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1562
|
+
"header",
|
|
1563
|
+
{
|
|
1564
|
+
className: cn(
|
|
1565
|
+
"h-14 border-b border-border bg-surface flex items-center px-6 z-10 shrink-0 gap-4",
|
|
1566
|
+
stickyTopbar && "sticky top-0"
|
|
1567
|
+
),
|
|
1568
|
+
children: [
|
|
1569
|
+
mobileSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1570
|
+
"button",
|
|
1571
|
+
{
|
|
1572
|
+
type: "button",
|
|
1573
|
+
onClick: () => setMobileOpen(true),
|
|
1574
|
+
className: "md:hidden p-1.5 -ml-1.5 rounded-kj-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer",
|
|
1575
|
+
"aria-label": "Open navigation",
|
|
1576
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1577
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
|
|
1578
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
1579
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
|
|
1580
|
+
] })
|
|
1581
|
+
}
|
|
1582
|
+
),
|
|
1583
|
+
topbar
|
|
1584
|
+
]
|
|
1585
|
+
}
|
|
1586
|
+
),
|
|
1587
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: cn("flex-1 p-6 md:p-8", contentWidthClass), children })
|
|
1588
|
+
] })
|
|
1589
|
+
]
|
|
1590
|
+
}
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1593
|
+
);
|
|
1594
|
+
DashboardShell.displayName = "DashboardShell";
|
|
1595
|
+
var SettingsLayout = React18__namespace.forwardRef(
|
|
1596
|
+
({ className, sidebar, children, title, description, ...props }, ref) => {
|
|
1597
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-6 w-full", className), ...props, children: [
|
|
1598
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border pb-4", children: [
|
|
1599
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight text-foreground", children: title }),
|
|
1600
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: description })
|
|
1601
|
+
] }),
|
|
1602
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col lg:flex-row gap-8", children: [
|
|
1603
|
+
/* @__PURE__ */ jsxRuntime.jsx("aside", { className: "lg:w-1/4 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex flex-row lg:flex-col gap-1 overflow-x-auto lg:overflow-x-visible pb-2 lg:pb-0", children: sidebar }) }),
|
|
1604
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 max-w-3xl", children })
|
|
1605
|
+
] })
|
|
1606
|
+
] });
|
|
1607
|
+
}
|
|
1608
|
+
);
|
|
1609
|
+
SettingsLayout.displayName = "SettingsLayout";
|
|
1610
|
+
var DetailPageLayout = React18__namespace.forwardRef(
|
|
1611
|
+
({ className, title, description, backHref, backLabel = "Back", onBackClick, actions, aside, children, ...props }, ref) => {
|
|
1612
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-6 w-full", className), ...props, children: [
|
|
1613
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1614
|
+
(backHref || onBackClick) && /* @__PURE__ */ jsxRuntime.jsx("div", { children: backHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1615
|
+
"a",
|
|
1616
|
+
{
|
|
1617
|
+
href: backHref,
|
|
1618
|
+
className: cn(
|
|
1619
|
+
buttonVariants({ variant: "ghost", size: "sm" }),
|
|
1620
|
+
"-ml-3 h-8 text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5"
|
|
1621
|
+
),
|
|
1622
|
+
children: [
|
|
1623
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 19.5 8.25 12l7.5-7.5" }) }),
|
|
1624
|
+
backLabel
|
|
1625
|
+
]
|
|
1626
|
+
}
|
|
1627
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1628
|
+
Button,
|
|
1629
|
+
{
|
|
1630
|
+
variant: "ghost",
|
|
1631
|
+
size: "sm",
|
|
1632
|
+
className: "-ml-3 h-8 text-muted-foreground hover:text-foreground",
|
|
1633
|
+
onClick: onBackClick,
|
|
1634
|
+
children: [
|
|
1635
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "h-4 w-4 mr-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 19.5 8.25 12l7.5-7.5" }) }),
|
|
1636
|
+
backLabel
|
|
1637
|
+
]
|
|
1638
|
+
}
|
|
1639
|
+
) }),
|
|
1640
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col md:flex-row md:items-center md:justify-between gap-4", children: [
|
|
1641
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1642
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight text-foreground", children: title }),
|
|
1643
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
1644
|
+
] }),
|
|
1645
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions })
|
|
1646
|
+
] })
|
|
1647
|
+
] }),
|
|
1648
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8 items-start", children: [
|
|
1649
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-6", aside ? "lg:col-span-2" : "lg:col-span-3"), children }),
|
|
1650
|
+
aside && /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "space-y-6 lg:col-span-1 bg-surface border border-border rounded-kj-xl p-6 shadow-kj-xs", children: aside })
|
|
1651
|
+
] })
|
|
1652
|
+
] });
|
|
1653
|
+
}
|
|
1654
|
+
);
|
|
1655
|
+
DetailPageLayout.displayName = "DetailPageLayout";
|
|
1656
|
+
var TableToolbar = React18__namespace.forwardRef(
|
|
1657
|
+
({ className, searchQuery, onSearchChange, searchPlaceholder = "Search...", actions, filters, ...props }, ref) => {
|
|
1658
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1659
|
+
"div",
|
|
1660
|
+
{
|
|
1661
|
+
ref,
|
|
1662
|
+
className: cn(
|
|
1663
|
+
"flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3 w-full pb-1",
|
|
1664
|
+
className
|
|
1665
|
+
),
|
|
1666
|
+
...props,
|
|
1667
|
+
children: [
|
|
1668
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col sm:flex-row items-stretch sm:items-center gap-2 max-w-xl", children: [
|
|
1669
|
+
onSearchChange && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1670
|
+
Input,
|
|
1671
|
+
{
|
|
1672
|
+
type: "search",
|
|
1673
|
+
placeholder: searchPlaceholder,
|
|
1674
|
+
value: searchQuery,
|
|
1675
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
1676
|
+
className: "sm:w-64",
|
|
1677
|
+
leadingIcon: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" }) })
|
|
1678
|
+
}
|
|
1679
|
+
),
|
|
1680
|
+
filters && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: filters })
|
|
1681
|
+
] }),
|
|
1682
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0 justify-end", children: actions })
|
|
1683
|
+
]
|
|
1684
|
+
}
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
);
|
|
1688
|
+
TableToolbar.displayName = "TableToolbar";
|
|
1689
|
+
function ConfirmDialog({
|
|
1690
|
+
open,
|
|
1691
|
+
onClose,
|
|
1692
|
+
onConfirm,
|
|
1693
|
+
title,
|
|
1694
|
+
description,
|
|
1695
|
+
confirmLabel = "Confirm",
|
|
1696
|
+
cancelLabel = "Cancel",
|
|
1697
|
+
tone = "primary",
|
|
1698
|
+
loading = false
|
|
1699
|
+
}) {
|
|
1700
|
+
const toneButtonVariant = {
|
|
1701
|
+
danger: "danger",
|
|
1702
|
+
primary: "primary",
|
|
1703
|
+
success: "secondary"
|
|
1704
|
+
// standard secondary in our system is teal (success-aligned)
|
|
1705
|
+
}[tone];
|
|
1706
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { open, onClose, width: 400, showClose: !loading, children: [
|
|
1707
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalTitle, { children: title }),
|
|
1708
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalDescription, { children: description }),
|
|
1709
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ModalActions, { children: [
|
|
1710
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: onClose, disabled: loading, children: cancelLabel }),
|
|
1711
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: toneButtonVariant, onClick: onConfirm, loading, children: confirmLabel })
|
|
1712
|
+
] })
|
|
1713
|
+
] });
|
|
1714
|
+
}
|
|
1715
|
+
ConfirmDialog.displayName = "ConfirmDialog";
|
|
1716
|
+
function Drawer({
|
|
1717
|
+
open,
|
|
1718
|
+
onClose,
|
|
1719
|
+
children,
|
|
1720
|
+
title,
|
|
1721
|
+
description,
|
|
1722
|
+
width = "max-w-md",
|
|
1723
|
+
side = "right"
|
|
1724
|
+
}) {
|
|
1725
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1726
|
+
const lastActiveElement = React18__namespace.useRef(null);
|
|
1727
|
+
React18__namespace.useEffect(() => {
|
|
1728
|
+
if (!open) {
|
|
1729
|
+
if (lastActiveElement.current) {
|
|
1730
|
+
lastActiveElement.current.focus();
|
|
1731
|
+
lastActiveElement.current = null;
|
|
1732
|
+
}
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
lastActiveElement.current = document.activeElement;
|
|
1736
|
+
const container = containerRef.current;
|
|
1737
|
+
if (container) {
|
|
1738
|
+
const focusables = container.querySelectorAll(
|
|
1739
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
1740
|
+
);
|
|
1741
|
+
if (focusables.length > 0) {
|
|
1742
|
+
setTimeout(() => focusables[0].focus(), 50);
|
|
1743
|
+
} else {
|
|
1744
|
+
container.focus();
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
const handleKeyDown = (e) => {
|
|
1748
|
+
if (e.key === "Escape") {
|
|
1749
|
+
onClose();
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
if (e.key === "Tab") {
|
|
1753
|
+
const container2 = containerRef.current;
|
|
1754
|
+
if (!container2) return;
|
|
1755
|
+
const focusables = Array.from(
|
|
1756
|
+
container2.querySelectorAll(
|
|
1757
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
1758
|
+
)
|
|
1759
|
+
);
|
|
1760
|
+
if (focusables.length === 0) {
|
|
1761
|
+
e.preventDefault();
|
|
1762
|
+
return;
|
|
1763
|
+
}
|
|
1764
|
+
const first = focusables[0];
|
|
1765
|
+
const last = focusables[focusables.length - 1];
|
|
1766
|
+
if (e.shiftKey) {
|
|
1767
|
+
if (document.activeElement === first || document.activeElement === container2) {
|
|
1768
|
+
last.focus();
|
|
1769
|
+
e.preventDefault();
|
|
1770
|
+
}
|
|
1771
|
+
} else {
|
|
1772
|
+
if (document.activeElement === last) {
|
|
1773
|
+
first.focus();
|
|
1774
|
+
e.preventDefault();
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1780
|
+
document.body.style.overflow = "hidden";
|
|
1781
|
+
return () => {
|
|
1782
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1783
|
+
document.body.style.overflow = "";
|
|
1784
|
+
};
|
|
1785
|
+
}, [open, onClose]);
|
|
1786
|
+
const sideClasses = {
|
|
1787
|
+
right: cn(
|
|
1788
|
+
"right-0 h-full border-l",
|
|
1789
|
+
open ? "translate-x-0" : "translate-x-full"
|
|
1790
|
+
),
|
|
1791
|
+
left: cn(
|
|
1792
|
+
"left-0 h-full border-r",
|
|
1793
|
+
open ? "translate-x-0" : "-translate-x-full"
|
|
1794
|
+
)
|
|
1795
|
+
}[side];
|
|
1796
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1797
|
+
"div",
|
|
1798
|
+
{
|
|
1799
|
+
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
1800
|
+
className: cn(
|
|
1801
|
+
"fixed inset-0 z-[100] transition-opacity duration-300 backdrop-blur-[2px]",
|
|
1802
|
+
"bg-[color-mix(in_oklch,#09090b_45%,transparent)]",
|
|
1803
|
+
open ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
|
1804
|
+
),
|
|
1805
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1806
|
+
"div",
|
|
1807
|
+
{
|
|
1808
|
+
ref: containerRef,
|
|
1809
|
+
role: "dialog",
|
|
1810
|
+
"aria-modal": "true",
|
|
1811
|
+
"aria-label": !title ? "Drawer" : void 0,
|
|
1812
|
+
"aria-labelledby": title ? "drawer-title" : void 0,
|
|
1813
|
+
"aria-describedby": description ? "drawer-description" : void 0,
|
|
1814
|
+
tabIndex: -1,
|
|
1815
|
+
className: cn(
|
|
1816
|
+
"fixed top-0 bottom-0 bg-surface border-border flex flex-col w-full shadow-kj-lg transition-transform duration-300 ease-spring outline-none",
|
|
1817
|
+
width,
|
|
1818
|
+
sideClasses
|
|
1819
|
+
),
|
|
1820
|
+
children: [
|
|
1821
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-6 border-b border-border", children: [
|
|
1822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1823
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: "drawer-title", className: "text-lg font-bold tracking-tight text-foreground", children: title }),
|
|
1824
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "drawer-description", className: "text-xs text-muted-foreground", children: description })
|
|
1825
|
+
] }),
|
|
1826
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1827
|
+
"button",
|
|
1828
|
+
{
|
|
1829
|
+
type: "button",
|
|
1830
|
+
onClick: onClose,
|
|
1831
|
+
"aria-label": "Close",
|
|
1832
|
+
className: "p-1.5 rounded-kj-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer",
|
|
1833
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
1834
|
+
}
|
|
1835
|
+
)
|
|
1836
|
+
] }),
|
|
1837
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto p-6", children })
|
|
1838
|
+
]
|
|
1839
|
+
}
|
|
1840
|
+
)
|
|
1841
|
+
}
|
|
1842
|
+
);
|
|
1843
|
+
}
|
|
1844
|
+
Drawer.displayName = "Drawer";
|
|
1845
|
+
function CommandPalette({ open, onClose, items, placeholder = "Type a command or search..." }) {
|
|
1846
|
+
const [search, setSearch] = React18__namespace.useState("");
|
|
1847
|
+
const [activeIndex, setActiveIndex] = React18__namespace.useState(0);
|
|
1848
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1849
|
+
const listRef = React18__namespace.useRef(null);
|
|
1850
|
+
React18__namespace.useEffect(() => {
|
|
1851
|
+
if (open) {
|
|
1852
|
+
setSearch("");
|
|
1853
|
+
setActiveIndex(0);
|
|
1854
|
+
document.body.style.overflow = "hidden";
|
|
1855
|
+
} else {
|
|
1856
|
+
document.body.style.overflow = "";
|
|
1857
|
+
}
|
|
1858
|
+
}, [open]);
|
|
1859
|
+
const filteredItems = React18__namespace.useMemo(() => {
|
|
1860
|
+
if (!search) return items;
|
|
1861
|
+
const cleanSearch = search.toLowerCase();
|
|
1862
|
+
return items.filter(
|
|
1863
|
+
(item) => item.title.toLowerCase().includes(cleanSearch) || item.subtitle?.toLowerCase().includes(cleanSearch) || item.category?.toLowerCase().includes(cleanSearch)
|
|
1864
|
+
);
|
|
1865
|
+
}, [search, items]);
|
|
1866
|
+
React18__namespace.useEffect(() => {
|
|
1867
|
+
setActiveIndex(0);
|
|
1868
|
+
}, [filteredItems]);
|
|
1869
|
+
React18__namespace.useEffect(() => {
|
|
1870
|
+
if (!open) return;
|
|
1871
|
+
const handleKeyDown = (e) => {
|
|
1872
|
+
if (e.key === "Escape") {
|
|
1873
|
+
onClose();
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
if (e.key === "ArrowDown") {
|
|
1877
|
+
e.preventDefault();
|
|
1878
|
+
setActiveIndex((prev) => filteredItems.length === 0 ? 0 : (prev + 1) % filteredItems.length);
|
|
1879
|
+
} else if (e.key === "ArrowUp") {
|
|
1880
|
+
e.preventDefault();
|
|
1881
|
+
setActiveIndex((prev) => filteredItems.length === 0 ? 0 : (prev - 1 + filteredItems.length) % filteredItems.length);
|
|
1882
|
+
} else if (e.key === "Enter") {
|
|
1883
|
+
e.preventDefault();
|
|
1884
|
+
if (filteredItems[activeIndex]) {
|
|
1885
|
+
filteredItems[activeIndex].action();
|
|
1886
|
+
onClose();
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
};
|
|
1890
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1891
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1892
|
+
}, [open, filteredItems, activeIndex, onClose]);
|
|
1893
|
+
React18__namespace.useEffect(() => {
|
|
1894
|
+
if (listRef.current) {
|
|
1895
|
+
const activeEl = listRef.current.children[activeIndex];
|
|
1896
|
+
if (activeEl) {
|
|
1897
|
+
activeEl.scrollIntoView({ block: "nearest" });
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}, [activeIndex]);
|
|
1901
|
+
if (!open) return null;
|
|
1902
|
+
const groups = {};
|
|
1903
|
+
filteredItems.forEach((item) => {
|
|
1904
|
+
const cat = item.category || "General";
|
|
1905
|
+
if (!groups[cat]) groups[cat] = [];
|
|
1906
|
+
groups[cat].push(item);
|
|
1907
|
+
});
|
|
1908
|
+
let absoluteItemIndex = 0;
|
|
1909
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1910
|
+
"div",
|
|
1911
|
+
{
|
|
1912
|
+
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
1913
|
+
className: "fixed inset-0 z-[100] grid place-items-start justify-center p-6 md:p-24 backdrop-blur-[3px] bg-[color-mix(in_oklch,#09090b_60%,transparent)]",
|
|
1914
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1915
|
+
"div",
|
|
1916
|
+
{
|
|
1917
|
+
ref: containerRef,
|
|
1918
|
+
className: "w-[95vw] max-w-lg bg-surface border border-border rounded-kj-xl shadow-kj-lg flex flex-col overflow-hidden max-h-[500px]",
|
|
1919
|
+
children: [
|
|
1920
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
|
|
1921
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", className: "h-5 w-5 text-muted-foreground shrink-0 ml-1", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" }) }),
|
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1923
|
+
"input",
|
|
1924
|
+
{
|
|
1925
|
+
type: "text",
|
|
1926
|
+
placeholder,
|
|
1927
|
+
value: search,
|
|
1928
|
+
onChange: (e) => setSearch(e.target.value),
|
|
1929
|
+
className: "flex-1 font-sans text-[0.95rem] bg-transparent text-foreground placeholder:text-muted-foreground outline-none border-none focus:ring-0",
|
|
1930
|
+
autoFocus: true
|
|
1931
|
+
}
|
|
1932
|
+
)
|
|
1933
|
+
] }),
|
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto p-2 min-h-[150px]", children: filteredItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-12 text-center text-sm text-muted-foreground", children: [
|
|
1935
|
+
'No results found for "',
|
|
1936
|
+
search,
|
|
1937
|
+
'"'
|
|
1938
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: listRef, className: "space-y-4", children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground", children: cat }),
|
|
1940
|
+
itemsInCat.map((item) => {
|
|
1941
|
+
const currentIdx = absoluteItemIndex++;
|
|
1942
|
+
const isActive = currentIdx === activeIndex;
|
|
1943
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1944
|
+
"div",
|
|
1945
|
+
{
|
|
1946
|
+
onClick: () => {
|
|
1947
|
+
item.action();
|
|
1948
|
+
onClose();
|
|
1949
|
+
},
|
|
1950
|
+
className: cn(
|
|
1951
|
+
"flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
|
|
1952
|
+
isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1953
|
+
),
|
|
1954
|
+
children: [
|
|
1955
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
1956
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
|
|
1957
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex flex-col", children: [
|
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
|
|
1959
|
+
item.subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
|
|
1960
|
+
] })
|
|
1961
|
+
] }),
|
|
1962
|
+
item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1963
|
+
"kbd",
|
|
1964
|
+
{
|
|
1965
|
+
className: "px-1.5 py-0.5 rounded border border-border bg-subtle text-[10px] font-mono leading-none shadow-kj-xs text-muted-foreground",
|
|
1966
|
+
children: sc
|
|
1967
|
+
},
|
|
1968
|
+
scIdx
|
|
1969
|
+
)) })
|
|
1970
|
+
]
|
|
1971
|
+
},
|
|
1972
|
+
item.id
|
|
1973
|
+
);
|
|
1974
|
+
})
|
|
1975
|
+
] }, cat)) }) }),
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2.5 border-t border-border bg-subtle flex items-center justify-between text-[11px] text-muted-foreground font-medium", children: [
|
|
1977
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1978
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
1979
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "\u2191\u2193" }),
|
|
1980
|
+
" Navigate"
|
|
1981
|
+
] }),
|
|
1982
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
1983
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "Enter" }),
|
|
1984
|
+
" Select"
|
|
1985
|
+
] })
|
|
1986
|
+
] }),
|
|
1987
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1988
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "Esc" }),
|
|
1989
|
+
" Close"
|
|
1990
|
+
] })
|
|
1991
|
+
] })
|
|
1992
|
+
]
|
|
1993
|
+
}
|
|
1994
|
+
)
|
|
1995
|
+
}
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
CommandPalette.displayName = "CommandPalette";
|
|
1999
|
+
function SidebarNav({ className, groups, currentHref, ...props }) {
|
|
2000
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-6 py-4 px-3 w-full", className), ...props, children: groups.map((group, groupIdx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
2001
|
+
group.title && /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "px-3 text-[10px] font-bold uppercase tracking-widest text-muted-foreground/85", children: group.title }),
|
|
2002
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: group.items.map((item) => {
|
|
2003
|
+
const isActive = item.active || item.href && currentHref && currentHref === item.href;
|
|
2004
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2005
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2.5 min-w-0", children: [
|
|
2006
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
2007
|
+
"[&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem] shrink-0",
|
|
2008
|
+
isActive ? "text-primary" : "text-muted-foreground group-hover:text-foreground"
|
|
2009
|
+
), children: item.icon }),
|
|
2010
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: item.label })
|
|
2011
|
+
] }),
|
|
2012
|
+
item.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 flex items-center justify-center", children: item.badge })
|
|
2013
|
+
] });
|
|
2014
|
+
const itemClass = cn(
|
|
2015
|
+
"group flex items-center justify-between gap-3 px-3 py-2 rounded-kj-md text-[0.85rem] font-semibold select-none cursor-pointer transition-all duration-150",
|
|
2016
|
+
isActive ? "bg-primary/10 text-primary border-l-2 border-primary rounded-l-none pl-2.5" : "text-muted-foreground hover:bg-muted hover:text-foreground border-l-2 border-transparent"
|
|
2017
|
+
);
|
|
2018
|
+
if (item.href) {
|
|
2019
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: itemClass, children: content }, item.id);
|
|
2020
|
+
}
|
|
2021
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2022
|
+
"button",
|
|
2023
|
+
{
|
|
2024
|
+
type: "button",
|
|
2025
|
+
onClick: item.onClick,
|
|
2026
|
+
className: itemClass,
|
|
2027
|
+
children: content
|
|
2028
|
+
},
|
|
2029
|
+
item.id
|
|
2030
|
+
);
|
|
2031
|
+
}) })
|
|
2032
|
+
] }, groupIdx)) });
|
|
2033
|
+
}
|
|
2034
|
+
SidebarNav.displayName = "SidebarNav";
|
|
1176
2035
|
|
|
1177
2036
|
exports.Accordion = Accordion;
|
|
1178
2037
|
exports.AccordionContent = AccordionContent;
|
|
@@ -1182,6 +2041,7 @@ exports.Alert = Alert;
|
|
|
1182
2041
|
exports.Avatar = Avatar;
|
|
1183
2042
|
exports.AvatarGroup = AvatarGroup;
|
|
1184
2043
|
exports.Badge = Badge;
|
|
2044
|
+
exports.BottomNavigation = BottomNavigation;
|
|
1185
2045
|
exports.Breadcrumb = Breadcrumb;
|
|
1186
2046
|
exports.BreadcrumbItem = BreadcrumbItem;
|
|
1187
2047
|
exports.BreadcrumbSeparator = BreadcrumbSeparator;
|
|
@@ -1193,14 +2053,22 @@ exports.CardFooter = CardFooter;
|
|
|
1193
2053
|
exports.CardHeader = CardHeader;
|
|
1194
2054
|
exports.CardTitle = CardTitle;
|
|
1195
2055
|
exports.Checkbox = Checkbox;
|
|
2056
|
+
exports.CheckboxField = CheckboxField;
|
|
2057
|
+
exports.CommandPalette = CommandPalette;
|
|
2058
|
+
exports.ConfirmDialog = ConfirmDialog;
|
|
2059
|
+
exports.DashboardShell = DashboardShell;
|
|
1196
2060
|
exports.DataTable = DataTable;
|
|
2061
|
+
exports.DetailPageLayout = DetailPageLayout;
|
|
2062
|
+
exports.Drawer = Drawer;
|
|
1197
2063
|
exports.DropdownMenu = DropdownMenu;
|
|
1198
2064
|
exports.DropdownMenuContent = DropdownMenuContent;
|
|
1199
2065
|
exports.DropdownMenuItem = DropdownMenuItem;
|
|
1200
2066
|
exports.DropdownMenuSeparator = DropdownMenuSeparator;
|
|
1201
2067
|
exports.DropdownMenuTrigger = DropdownMenuTrigger;
|
|
1202
2068
|
exports.EmptyState = EmptyState;
|
|
2069
|
+
exports.ErrorState = ErrorState;
|
|
1203
2070
|
exports.Field = Field;
|
|
2071
|
+
exports.FormField = FormField;
|
|
1204
2072
|
exports.Hint = Hint;
|
|
1205
2073
|
exports.Input = Input;
|
|
1206
2074
|
exports.Label = Label;
|
|
@@ -1215,6 +2083,10 @@ exports.Progress = Progress;
|
|
|
1215
2083
|
exports.Radio = Radio;
|
|
1216
2084
|
exports.Segmented = Segmented;
|
|
1217
2085
|
exports.Select = Select;
|
|
2086
|
+
exports.SelectField = SelectField;
|
|
2087
|
+
exports.SettingsLayout = SettingsLayout;
|
|
2088
|
+
exports.SidebarNav = SidebarNav;
|
|
2089
|
+
exports.Skeleton = Skeleton;
|
|
1218
2090
|
exports.Slider = Slider;
|
|
1219
2091
|
exports.Spinner = Spinner;
|
|
1220
2092
|
exports.Stat = Stat;
|
|
@@ -1225,11 +2097,13 @@ exports.TableCell = TableCell;
|
|
|
1225
2097
|
exports.TableHead = TableHead;
|
|
1226
2098
|
exports.TableHeader = TableHeader;
|
|
1227
2099
|
exports.TableRow = TableRow;
|
|
2100
|
+
exports.TableToolbar = TableToolbar;
|
|
1228
2101
|
exports.TableWrap = TableWrap;
|
|
1229
2102
|
exports.Tabs = Tabs;
|
|
1230
2103
|
exports.TabsContent = TabsContent;
|
|
1231
2104
|
exports.TabsList = TabsList;
|
|
1232
2105
|
exports.TabsTrigger = TabsTrigger;
|
|
2106
|
+
exports.TextField = TextField;
|
|
1233
2107
|
exports.Textarea = Textarea;
|
|
1234
2108
|
exports.ToastProvider = ToastProvider;
|
|
1235
2109
|
exports.Tooltip = Tooltip;
|