@kjaniec-dev/ui 0.6.0 → 0.7.1
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 +951 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +162 -3
- package/dist/index.d.ts +162 -3
- package/dist/index.js +941 -167
- 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;
|
|
@@ -527,14 +587,17 @@ var TabsList = React17__namespace.forwardRef(
|
|
|
527
587
|
ref,
|
|
528
588
|
role: "tablist",
|
|
529
589
|
onKeyDown: handleKeyDown,
|
|
530
|
-
className: cn(
|
|
590
|
+
className: cn(
|
|
591
|
+
"flex gap-1 border-b border-border overflow-x-auto whitespace-nowrap [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
592
|
+
className
|
|
593
|
+
),
|
|
531
594
|
...props
|
|
532
595
|
}
|
|
533
596
|
);
|
|
534
597
|
}
|
|
535
598
|
);
|
|
536
599
|
TabsList.displayName = "TabsList";
|
|
537
|
-
var TabsTrigger =
|
|
600
|
+
var TabsTrigger = React18__namespace.forwardRef(
|
|
538
601
|
({ className, value, children, ...props }, ref) => {
|
|
539
602
|
const { value: current, setValue } = useTabs();
|
|
540
603
|
const active = current === value;
|
|
@@ -550,7 +613,7 @@ var TabsTrigger = React17__namespace.forwardRef(
|
|
|
550
613
|
tabIndex: active ? 0 : -1,
|
|
551
614
|
onClick: () => setValue(value),
|
|
552
615
|
className: cn(
|
|
553
|
-
"relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none",
|
|
616
|
+
"relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none shrink-0 whitespace-nowrap",
|
|
554
617
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:rounded-sm",
|
|
555
618
|
"after:content-[''] after:absolute after:left-[0.9rem] after:right-[0.9rem] after:-bottom-px after:h-0.5 after:rounded-sm after:transition-colors",
|
|
556
619
|
active ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent",
|
|
@@ -563,7 +626,7 @@ var TabsTrigger = React17__namespace.forwardRef(
|
|
|
563
626
|
}
|
|
564
627
|
);
|
|
565
628
|
TabsTrigger.displayName = "TabsTrigger";
|
|
566
|
-
var TabsContent =
|
|
629
|
+
var TabsContent = React18__namespace.forwardRef(
|
|
567
630
|
({ className, value, ...props }, ref) => {
|
|
568
631
|
const { value: current } = useTabs();
|
|
569
632
|
const active = current === value;
|
|
@@ -583,10 +646,10 @@ var TabsContent = React17__namespace.forwardRef(
|
|
|
583
646
|
}
|
|
584
647
|
);
|
|
585
648
|
TabsContent.displayName = "TabsContent";
|
|
586
|
-
var AccordionContext =
|
|
649
|
+
var AccordionContext = React18__namespace.createContext(null);
|
|
587
650
|
function Accordion({ type = "single", defaultValue = [], className, children, ...props }) {
|
|
588
|
-
const [open, setOpen] =
|
|
589
|
-
const toggle =
|
|
651
|
+
const [open, setOpen] = React18__namespace.useState(defaultValue);
|
|
652
|
+
const toggle = React18__namespace.useCallback(
|
|
590
653
|
(v) => {
|
|
591
654
|
setOpen((prev) => {
|
|
592
655
|
const isOpen = prev.includes(v);
|
|
@@ -598,15 +661,15 @@ function Accordion({ type = "single", defaultValue = [], className, children, ..
|
|
|
598
661
|
);
|
|
599
662
|
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
663
|
}
|
|
601
|
-
var ItemContext =
|
|
602
|
-
var AccordionItem =
|
|
664
|
+
var ItemContext = React18__namespace.createContext("");
|
|
665
|
+
var AccordionItem = React18__namespace.forwardRef(
|
|
603
666
|
({ 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
667
|
);
|
|
605
668
|
AccordionItem.displayName = "AccordionItem";
|
|
606
|
-
var AccordionTrigger =
|
|
669
|
+
var AccordionTrigger = React18__namespace.forwardRef(
|
|
607
670
|
({ className, children, ...props }, ref) => {
|
|
608
|
-
const ctx =
|
|
609
|
-
const value =
|
|
671
|
+
const ctx = React18__namespace.useContext(AccordionContext);
|
|
672
|
+
const value = React18__namespace.useContext(ItemContext);
|
|
610
673
|
const isOpen = ctx.open.includes(value);
|
|
611
674
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
612
675
|
"button",
|
|
@@ -643,10 +706,10 @@ var AccordionTrigger = React17__namespace.forwardRef(
|
|
|
643
706
|
}
|
|
644
707
|
);
|
|
645
708
|
AccordionTrigger.displayName = "AccordionTrigger";
|
|
646
|
-
var AccordionContent =
|
|
709
|
+
var AccordionContent = React18__namespace.forwardRef(
|
|
647
710
|
({ className, children, ...props }, ref) => {
|
|
648
|
-
const ctx =
|
|
649
|
-
const value =
|
|
711
|
+
const ctx = React18__namespace.useContext(AccordionContext);
|
|
712
|
+
const value = React18__namespace.useContext(ItemContext);
|
|
650
713
|
const isOpen = ctx.open.includes(value);
|
|
651
714
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
652
715
|
"div",
|
|
@@ -660,11 +723,11 @@ var AccordionContent = React17__namespace.forwardRef(
|
|
|
660
723
|
}
|
|
661
724
|
);
|
|
662
725
|
AccordionContent.displayName = "AccordionContent";
|
|
663
|
-
var MenuContext =
|
|
726
|
+
var MenuContext = React18__namespace.createContext(null);
|
|
664
727
|
function DropdownMenu({ children, className }) {
|
|
665
|
-
const [open, setOpen] =
|
|
666
|
-
const ref =
|
|
667
|
-
|
|
728
|
+
const [open, setOpen] = React18__namespace.useState(false);
|
|
729
|
+
const ref = React18__namespace.useRef(null);
|
|
730
|
+
React18__namespace.useEffect(() => {
|
|
668
731
|
if (!open) return;
|
|
669
732
|
const onDoc = (e) => {
|
|
670
733
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -679,11 +742,11 @@ function DropdownMenu({ children, className }) {
|
|
|
679
742
|
}, [open]);
|
|
680
743
|
return /* @__PURE__ */ jsxRuntime.jsx(MenuContext.Provider, { value: { open, setOpen }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative inline-block", className), children }) });
|
|
681
744
|
}
|
|
682
|
-
var DropdownMenuTrigger =
|
|
683
|
-
const ctx =
|
|
745
|
+
var DropdownMenuTrigger = React18__namespace.forwardRef(({ onClick, asChild, ...props }, ref) => {
|
|
746
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
684
747
|
if (asChild) {
|
|
685
|
-
const child =
|
|
686
|
-
return
|
|
748
|
+
const child = React18__namespace.Children.only(props.children);
|
|
749
|
+
return React18__namespace.cloneElement(child, {
|
|
687
750
|
ref,
|
|
688
751
|
...props,
|
|
689
752
|
...child.props,
|
|
@@ -713,9 +776,9 @@ var DropdownMenuTrigger = React17__namespace.forwardRef(({ onClick, asChild, ...
|
|
|
713
776
|
});
|
|
714
777
|
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
|
|
715
778
|
function DropdownMenuContent({ className, align = "start", children, ...props }) {
|
|
716
|
-
const ctx =
|
|
717
|
-
const ref =
|
|
718
|
-
|
|
779
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
780
|
+
const ref = React18__namespace.useRef(null);
|
|
781
|
+
React18__namespace.useEffect(() => {
|
|
719
782
|
if (!ctx.open) return;
|
|
720
783
|
const container = ref.current;
|
|
721
784
|
if (container) {
|
|
@@ -762,9 +825,9 @@ function DropdownMenuContent({ className, align = "start", children, ...props })
|
|
|
762
825
|
}
|
|
763
826
|
);
|
|
764
827
|
}
|
|
765
|
-
var DropdownMenuItem =
|
|
828
|
+
var DropdownMenuItem = React18__namespace.forwardRef(
|
|
766
829
|
({ className, danger, icon, children, onClick, ...props }, ref) => {
|
|
767
|
-
const ctx =
|
|
830
|
+
const ctx = React18__namespace.useContext(MenuContext);
|
|
768
831
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
769
832
|
"button",
|
|
770
833
|
{
|
|
@@ -794,11 +857,11 @@ DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
|
794
857
|
function DropdownMenuSeparator({ className }) {
|
|
795
858
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("h-px bg-border my-1.5", className), role: "separator" });
|
|
796
859
|
}
|
|
797
|
-
var Breadcrumb =
|
|
860
|
+
var Breadcrumb = React18__namespace.forwardRef(
|
|
798
861
|
({ 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
862
|
);
|
|
800
863
|
Breadcrumb.displayName = "Breadcrumb";
|
|
801
|
-
var BreadcrumbItem =
|
|
864
|
+
var BreadcrumbItem = React18__namespace.forwardRef(
|
|
802
865
|
({ className, current, children, ...props }, ref) => {
|
|
803
866
|
if (current) {
|
|
804
867
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-current": "page", className: cn("text-foreground font-semibold", className), children });
|
|
@@ -845,27 +908,99 @@ function Pagination({ page, pageCount, onPageChange, className }) {
|
|
|
845
908
|
/* @__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
909
|
] });
|
|
847
910
|
}
|
|
848
|
-
var
|
|
849
|
-
({ className,
|
|
911
|
+
var BottomNavigation = React18__namespace.forwardRef(
|
|
912
|
+
({ className, items, showLabels = "always", fixed = true, ...props }, ref) => {
|
|
913
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
914
|
+
"nav",
|
|
915
|
+
{
|
|
916
|
+
ref,
|
|
917
|
+
className: cn(
|
|
918
|
+
"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",
|
|
919
|
+
fixed ? "fixed bottom-0 left-0 right-0 z-40 backdrop-blur-md" : "relative w-full",
|
|
920
|
+
className
|
|
921
|
+
),
|
|
922
|
+
...props,
|
|
923
|
+
children: items.map((item) => {
|
|
924
|
+
const isActive = item.active;
|
|
925
|
+
const showLabel = showLabels !== "never" && (showLabels === "always" || isActive);
|
|
926
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-center justify-center gap-1 w-full relative", children: [
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
928
|
+
"span",
|
|
929
|
+
{
|
|
930
|
+
className: cn(
|
|
931
|
+
"relative flex items-center justify-center p-1 rounded-full transition-all duration-200",
|
|
932
|
+
isActive ? "text-primary scale-110" : "text-muted-foreground group-hover:text-foreground group-active:scale-95"
|
|
933
|
+
),
|
|
934
|
+
children: [
|
|
935
|
+
item.icon,
|
|
936
|
+
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 })
|
|
937
|
+
]
|
|
938
|
+
}
|
|
939
|
+
),
|
|
940
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
941
|
+
"span",
|
|
942
|
+
{
|
|
943
|
+
className: cn(
|
|
944
|
+
"text-[10px] font-semibold tracking-wide transition-all duration-200 select-none",
|
|
945
|
+
showLabel ? "opacity-100 scale-100 h-auto" : "opacity-0 scale-75 h-0 overflow-hidden",
|
|
946
|
+
isActive ? "text-primary font-bold" : "text-muted-foreground group-hover:text-foreground"
|
|
947
|
+
),
|
|
948
|
+
children: item.label
|
|
949
|
+
}
|
|
950
|
+
),
|
|
951
|
+
isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -bottom-1.5 w-1 h-1 rounded-full bg-primary animate-fade-in" })
|
|
952
|
+
] });
|
|
953
|
+
const itemClass = "group flex-1 flex flex-col items-center justify-center py-1 cursor-pointer transition-all duration-150 relative focus:outline-none";
|
|
954
|
+
if (item.href) {
|
|
955
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
956
|
+
"a",
|
|
957
|
+
{
|
|
958
|
+
href: item.href,
|
|
959
|
+
className: itemClass,
|
|
960
|
+
"aria-current": isActive ? "page" : void 0,
|
|
961
|
+
children: content
|
|
962
|
+
},
|
|
963
|
+
item.id
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
967
|
+
"button",
|
|
968
|
+
{
|
|
969
|
+
type: "button",
|
|
970
|
+
onClick: item.onClick,
|
|
971
|
+
className: itemClass,
|
|
972
|
+
"aria-pressed": isActive,
|
|
973
|
+
children: content
|
|
974
|
+
},
|
|
975
|
+
item.id
|
|
976
|
+
);
|
|
977
|
+
})
|
|
978
|
+
}
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
);
|
|
982
|
+
BottomNavigation.displayName = "BottomNavigation";
|
|
983
|
+
var TableWrap = React18__namespace.forwardRef(
|
|
984
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("border border-border rounded-kj-lg overflow-x-auto w-full", className), ...props })
|
|
850
985
|
);
|
|
851
986
|
TableWrap.displayName = "TableWrap";
|
|
852
|
-
var Table =
|
|
987
|
+
var Table = React18__namespace.forwardRef(
|
|
853
988
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("table", { ref, className: cn("w-full border-collapse text-[0.85rem]", className), ...props })
|
|
854
989
|
);
|
|
855
990
|
Table.displayName = "Table";
|
|
856
|
-
var TableHeader =
|
|
991
|
+
var TableHeader = React18__namespace.forwardRef(
|
|
857
992
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className, ...props })
|
|
858
993
|
);
|
|
859
994
|
TableHeader.displayName = "TableHeader";
|
|
860
|
-
var TableBody =
|
|
995
|
+
var TableBody = React18__namespace.forwardRef(
|
|
861
996
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className, ...props })
|
|
862
997
|
);
|
|
863
998
|
TableBody.displayName = "TableBody";
|
|
864
|
-
var TableRow =
|
|
999
|
+
var TableRow = React18__namespace.forwardRef(
|
|
865
1000
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tr", { ref, className: cn("transition-colors hover:bg-muted/50", className), ...props })
|
|
866
1001
|
);
|
|
867
1002
|
TableRow.displayName = "TableRow";
|
|
868
|
-
var TableHead =
|
|
1003
|
+
var TableHead = React18__namespace.forwardRef(
|
|
869
1004
|
({ className, numeric, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
870
1005
|
"th",
|
|
871
1006
|
{
|
|
@@ -880,7 +1015,7 @@ var TableHead = React17__namespace.forwardRef(
|
|
|
880
1015
|
)
|
|
881
1016
|
);
|
|
882
1017
|
TableHead.displayName = "TableHead";
|
|
883
|
-
var TableCell =
|
|
1018
|
+
var TableCell = React18__namespace.forwardRef(
|
|
884
1019
|
({ className, numeric, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
885
1020
|
"td",
|
|
886
1021
|
{
|
|
@@ -913,13 +1048,13 @@ function Tooltip({ content, children, className }) {
|
|
|
913
1048
|
)
|
|
914
1049
|
] });
|
|
915
1050
|
}
|
|
916
|
-
var ModalContext =
|
|
1051
|
+
var ModalContext = React18__namespace.createContext(null);
|
|
917
1052
|
function Modal({ open, onClose, children, width = 440, className, showClose = true }) {
|
|
918
|
-
const titleId =
|
|
919
|
-
const descId =
|
|
920
|
-
const containerRef =
|
|
921
|
-
const lastActiveElement =
|
|
922
|
-
|
|
1053
|
+
const titleId = React18__namespace.useId();
|
|
1054
|
+
const descId = React18__namespace.useId();
|
|
1055
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1056
|
+
const lastActiveElement = React18__namespace.useRef(null);
|
|
1057
|
+
React18__namespace.useEffect(() => {
|
|
923
1058
|
if (!open) {
|
|
924
1059
|
if (lastActiveElement.current) {
|
|
925
1060
|
lastActiveElement.current.focus();
|
|
@@ -1021,19 +1156,19 @@ function Modal({ open, onClose, children, width = 440, className, showClose = tr
|
|
|
1021
1156
|
);
|
|
1022
1157
|
}
|
|
1023
1158
|
function ModalTitle({ className, id, ...props }) {
|
|
1024
|
-
const ctx =
|
|
1159
|
+
const ctx = React18__namespace.useContext(ModalContext);
|
|
1025
1160
|
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
1161
|
}
|
|
1027
1162
|
function ModalDescription({ className, id, ...props }) {
|
|
1028
|
-
const ctx =
|
|
1163
|
+
const ctx = React18__namespace.useContext(ModalContext);
|
|
1029
1164
|
return /* @__PURE__ */ jsxRuntime.jsx("p", { id: id ?? ctx?.descId, className: cn("m-0 text-[0.9rem] text-muted-foreground", className), ...props });
|
|
1030
1165
|
}
|
|
1031
1166
|
function ModalActions({ className, ...props }) {
|
|
1032
1167
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex gap-2.5 justify-end mt-6", className), ...props });
|
|
1033
1168
|
}
|
|
1034
|
-
var ToastContext =
|
|
1169
|
+
var ToastContext = React18__namespace.createContext(null);
|
|
1035
1170
|
function useToast() {
|
|
1036
|
-
const ctx =
|
|
1171
|
+
const ctx = React18__namespace.useContext(ToastContext);
|
|
1037
1172
|
if (!ctx) throw new Error("useToast must be used within <ToastProvider>");
|
|
1038
1173
|
return ctx;
|
|
1039
1174
|
}
|
|
@@ -1054,13 +1189,13 @@ var toneBorder = {
|
|
|
1054
1189
|
danger: "border-l-danger"
|
|
1055
1190
|
};
|
|
1056
1191
|
function ToastProvider({ children }) {
|
|
1057
|
-
const [items, setItems] =
|
|
1058
|
-
const idRef =
|
|
1059
|
-
const remove =
|
|
1192
|
+
const [items, setItems] = React18__namespace.useState([]);
|
|
1193
|
+
const idRef = React18__namespace.useRef(0);
|
|
1194
|
+
const remove = React18__namespace.useCallback((id) => {
|
|
1060
1195
|
setItems((prev) => prev.map((t) => t.id === id ? { ...t, leaving: true } : t));
|
|
1061
1196
|
setTimeout(() => setItems((prev) => prev.filter((t) => t.id !== id)), 250);
|
|
1062
1197
|
}, []);
|
|
1063
|
-
const toast =
|
|
1198
|
+
const toast = React18__namespace.useCallback(
|
|
1064
1199
|
({ message, tone = "default", duration = 3200 }) => {
|
|
1065
1200
|
const id = ++idRef.current;
|
|
1066
1201
|
setItems((prev) => [...prev, { id, message, tone, duration }]);
|
|
@@ -1090,7 +1225,7 @@ function ToastProvider({ children }) {
|
|
|
1090
1225
|
)) })
|
|
1091
1226
|
] });
|
|
1092
1227
|
}
|
|
1093
|
-
var PageHeader =
|
|
1228
|
+
var PageHeader = React18__namespace.forwardRef(
|
|
1094
1229
|
({ 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
1230
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 max-w-2xl", children: [
|
|
1096
1231
|
eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-xs font-bold uppercase tracking-[0.2em] text-primary", children: eyebrow }),
|
|
@@ -1101,7 +1236,7 @@ var PageHeader = React17__namespace.forwardRef(
|
|
|
1101
1236
|
] }) })
|
|
1102
1237
|
);
|
|
1103
1238
|
PageHeader.displayName = "PageHeader";
|
|
1104
|
-
var EmptyState =
|
|
1239
|
+
var EmptyState = React18__namespace.forwardRef(
|
|
1105
1240
|
({ className, icon, title, description, action, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1106
1241
|
"div",
|
|
1107
1242
|
{
|
|
@@ -1121,7 +1256,7 @@ var EmptyState = React17__namespace.forwardRef(
|
|
|
1121
1256
|
)
|
|
1122
1257
|
);
|
|
1123
1258
|
EmptyState.displayName = "EmptyState";
|
|
1124
|
-
var MetricCard =
|
|
1259
|
+
var MetricCard = React18__namespace.forwardRef(
|
|
1125
1260
|
({ className, title, value, trend, trendDirection = "neutral", description, icon, ...props }, ref) => {
|
|
1126
1261
|
const trendColor = {
|
|
1127
1262
|
up: "text-success bg-success-surface border-success/20",
|
|
@@ -1151,54 +1286,171 @@ function DataTable({
|
|
|
1151
1286
|
emptyTitle = "No data available",
|
|
1152
1287
|
emptyDescription = "There are no records to display at this time.",
|
|
1153
1288
|
emptyAction,
|
|
1289
|
+
getRowKey,
|
|
1290
|
+
onRowClick,
|
|
1291
|
+
toolbar,
|
|
1292
|
+
pagination,
|
|
1293
|
+
selectedRows,
|
|
1294
|
+
onSelectionChange,
|
|
1295
|
+
sortBy,
|
|
1296
|
+
sortDirection,
|
|
1297
|
+
onSort,
|
|
1154
1298
|
...props
|
|
1155
1299
|
}) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1300
|
+
const getRowId = React18__namespace.useCallback(
|
|
1301
|
+
(row, index) => getRowKey ? getRowKey(row, index) : index,
|
|
1302
|
+
[getRowKey]
|
|
1303
|
+
);
|
|
1304
|
+
const isSelectionActive = selectedRows !== void 0 && onSelectionChange !== void 0;
|
|
1305
|
+
const allSelected = React18__namespace.useMemo(() => {
|
|
1306
|
+
if (!isSelectionActive || data.length === 0) return false;
|
|
1307
|
+
return data.every((row, idx) => selectedRows.has(getRowId(row, idx)));
|
|
1308
|
+
}, [isSelectionActive, data, selectedRows, getRowId]);
|
|
1309
|
+
const someSelected = React18__namespace.useMemo(() => {
|
|
1310
|
+
if (!isSelectionActive || data.length === 0) return false;
|
|
1311
|
+
const selectedCount = data.filter((row, idx) => selectedRows.has(getRowId(row, idx))).length;
|
|
1312
|
+
return selectedCount > 0 && selectedCount < data.length;
|
|
1313
|
+
}, [isSelectionActive, data, selectedRows, getRowId]);
|
|
1314
|
+
const headerCheckboxRef = React18__namespace.useRef(null);
|
|
1315
|
+
React18__namespace.useEffect(() => {
|
|
1316
|
+
if (headerCheckboxRef.current) {
|
|
1317
|
+
headerCheckboxRef.current.indeterminate = someSelected;
|
|
1318
|
+
}
|
|
1319
|
+
}, [someSelected]);
|
|
1320
|
+
const handleSelectAll = (e) => {
|
|
1321
|
+
if (!onSelectionChange) return;
|
|
1322
|
+
const checked = e.target.checked;
|
|
1323
|
+
const next = new Set(selectedRows);
|
|
1324
|
+
data.forEach((row, idx) => {
|
|
1325
|
+
const id = getRowId(row, idx);
|
|
1326
|
+
if (checked) {
|
|
1327
|
+
next.add(id);
|
|
1328
|
+
} else {
|
|
1329
|
+
next.delete(id);
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
onSelectionChange(next);
|
|
1333
|
+
};
|
|
1334
|
+
const handleSelectRow = (row, idx, checked) => {
|
|
1335
|
+
if (!onSelectionChange || !selectedRows) return;
|
|
1336
|
+
const id = getRowId(row, idx);
|
|
1337
|
+
const next = new Set(selectedRows);
|
|
1338
|
+
if (checked) {
|
|
1339
|
+
next.add(id);
|
|
1340
|
+
} else {
|
|
1341
|
+
next.delete(id);
|
|
1342
|
+
}
|
|
1343
|
+
onSelectionChange(next);
|
|
1344
|
+
};
|
|
1345
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-4 w-full", className), children: [
|
|
1346
|
+
toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3", children: toolbar }),
|
|
1347
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TableWrap, { className: "relative overflow-hidden", ...props, children: [
|
|
1348
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
|
|
1349
|
+
/* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
|
|
1350
|
+
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(
|
|
1351
|
+
"input",
|
|
1352
|
+
{
|
|
1353
|
+
type: "checkbox",
|
|
1354
|
+
ref: headerCheckboxRef,
|
|
1355
|
+
checked: allSelected,
|
|
1356
|
+
onChange: handleSelectAll,
|
|
1357
|
+
"aria-label": "Select all rows",
|
|
1358
|
+
className: "h-4 w-4 rounded border-input text-primary focus:ring-ring"
|
|
1359
|
+
}
|
|
1360
|
+
) }) }),
|
|
1361
|
+
columns.map((col, idx) => {
|
|
1362
|
+
const alignClass = {
|
|
1363
|
+
left: "text-left",
|
|
1364
|
+
center: "text-center",
|
|
1365
|
+
right: "text-right"
|
|
1366
|
+
}[col.align || "left"];
|
|
1367
|
+
const isSortable = col.sortable && onSort && col.sortKey;
|
|
1368
|
+
const isSortedActive = sortBy && col.sortKey === sortBy;
|
|
1369
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1370
|
+
TableHead,
|
|
1371
|
+
{
|
|
1372
|
+
className: cn(
|
|
1373
|
+
alignClass,
|
|
1374
|
+
isSortable && "cursor-pointer select-none hover:bg-muted/30 transition-colors",
|
|
1375
|
+
col.className
|
|
1376
|
+
),
|
|
1377
|
+
onClick: () => {
|
|
1378
|
+
if (!isSortable || !col.sortKey) return;
|
|
1379
|
+
const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
|
|
1380
|
+
onSort(col.sortKey, nextDirection);
|
|
1381
|
+
},
|
|
1382
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: [
|
|
1383
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: col.header }),
|
|
1384
|
+
isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
|
|
1385
|
+
] })
|
|
1386
|
+
},
|
|
1387
|
+
idx
|
|
1388
|
+
);
|
|
1389
|
+
})
|
|
1390
|
+
] }) }),
|
|
1391
|
+
/* @__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: [
|
|
1392
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 32 }),
|
|
1393
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Loading dataset..." })
|
|
1394
|
+
] }) }) }) : 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(
|
|
1395
|
+
EmptyState,
|
|
1396
|
+
{
|
|
1397
|
+
title: emptyTitle,
|
|
1398
|
+
description: emptyDescription,
|
|
1399
|
+
action: emptyAction,
|
|
1400
|
+
className: "border-none bg-transparent rounded-none py-16"
|
|
1401
|
+
}
|
|
1402
|
+
) }) }) : data.map((row, rowIdx) => {
|
|
1403
|
+
const rowKey = getRowId(row, rowIdx);
|
|
1404
|
+
const isSelected = isSelectionActive && selectedRows.has(rowKey);
|
|
1405
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1406
|
+
TableRow,
|
|
1407
|
+
{
|
|
1408
|
+
onClick: () => onRowClick && onRowClick(row),
|
|
1409
|
+
className: cn(
|
|
1410
|
+
onRowClick && "cursor-pointer hover:bg-muted/40 transition-colors",
|
|
1411
|
+
isSelected && "bg-primary/5 hover:bg-primary/10"
|
|
1412
|
+
),
|
|
1413
|
+
children: [
|
|
1414
|
+
isSelectionActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1415
|
+
TableCell,
|
|
1416
|
+
{
|
|
1417
|
+
className: "w-12 px-4 text-center",
|
|
1418
|
+
onClick: (e) => {
|
|
1419
|
+
e.stopPropagation();
|
|
1420
|
+
},
|
|
1421
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1422
|
+
"input",
|
|
1423
|
+
{
|
|
1424
|
+
type: "checkbox",
|
|
1425
|
+
checked: isSelected,
|
|
1426
|
+
onChange: (e) => handleSelectRow(row, rowIdx, e.target.checked),
|
|
1427
|
+
"aria-label": `Select row ${rowIdx + 1}`,
|
|
1428
|
+
className: "h-4 w-4 rounded border-input text-primary focus:ring-ring"
|
|
1429
|
+
}
|
|
1430
|
+
) })
|
|
1431
|
+
}
|
|
1432
|
+
),
|
|
1433
|
+
columns.map((col, colIdx) => {
|
|
1434
|
+
const alignClass = {
|
|
1435
|
+
left: "text-left",
|
|
1436
|
+
center: "text-center",
|
|
1437
|
+
right: "text-right"
|
|
1438
|
+
}[col.align || "left"];
|
|
1439
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: cn(alignClass, col.className), children: col.accessor(row) }, colIdx);
|
|
1440
|
+
})
|
|
1441
|
+
]
|
|
1442
|
+
},
|
|
1443
|
+
rowKey
|
|
1444
|
+
);
|
|
1445
|
+
}) })
|
|
1446
|
+
] }),
|
|
1447
|
+
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
1448
|
] }),
|
|
1172
|
-
|
|
1449
|
+
pagination && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end w-full", children: pagination })
|
|
1173
1450
|
] });
|
|
1174
1451
|
}
|
|
1175
1452
|
DataTable.displayName = "DataTable";
|
|
1176
|
-
var
|
|
1177
|
-
({ className, label, hint, error, required, children, ...props }, ref) => {
|
|
1178
|
-
const id = React17__namespace.useId();
|
|
1179
|
-
const hintId = `${id}-hint`;
|
|
1180
|
-
const errorId = `${id}-error`;
|
|
1181
|
-
const child = React17__namespace.Children.only(children);
|
|
1182
|
-
const clonedChild = React17__namespace.cloneElement(child, {
|
|
1183
|
-
id: child.props.id ?? id,
|
|
1184
|
-
"aria-describedby": cn(
|
|
1185
|
-
hint && hintId,
|
|
1186
|
-
error && errorId,
|
|
1187
|
-
child.props["aria-describedby"]
|
|
1188
|
-
) || void 0,
|
|
1189
|
-
"aria-invalid": error ? "true" : void 0,
|
|
1190
|
-
required: child.props.required ?? required
|
|
1191
|
-
});
|
|
1192
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col gap-1.5 w-full", className), ...props, children: [
|
|
1193
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: id, required, children: label }),
|
|
1194
|
-
clonedChild,
|
|
1195
|
-
hint && !error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: hintId, children: hint }),
|
|
1196
|
-
error && /* @__PURE__ */ jsxRuntime.jsx(Hint, { id: errorId, error: true, children: error })
|
|
1197
|
-
] });
|
|
1198
|
-
}
|
|
1199
|
-
);
|
|
1200
|
-
FormField.displayName = "FormField";
|
|
1201
|
-
var ErrorState = React17__namespace.forwardRef(
|
|
1453
|
+
var ErrorState = React18__namespace.forwardRef(
|
|
1202
1454
|
({ className, title = "Wyst\u0105pi\u0142 b\u0142\u0105d", message, onRetry, retryLabel = "Spr\xF3buj ponownie", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1203
1455
|
"div",
|
|
1204
1456
|
{
|
|
@@ -1218,7 +1470,7 @@ var ErrorState = React17__namespace.forwardRef(
|
|
|
1218
1470
|
)
|
|
1219
1471
|
);
|
|
1220
1472
|
ErrorState.displayName = "ErrorState";
|
|
1221
|
-
var Skeleton =
|
|
1473
|
+
var Skeleton = React18__namespace.forwardRef(
|
|
1222
1474
|
({ className, variant = "rectangular", width, height, style, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1223
1475
|
"div",
|
|
1224
1476
|
{
|
|
@@ -1240,27 +1492,549 @@ var Skeleton = React17__namespace.forwardRef(
|
|
|
1240
1492
|
)
|
|
1241
1493
|
);
|
|
1242
1494
|
Skeleton.displayName = "Skeleton";
|
|
1243
|
-
var DashboardShell =
|
|
1244
|
-
({
|
|
1495
|
+
var DashboardShell = React18__namespace.forwardRef(
|
|
1496
|
+
({
|
|
1497
|
+
className,
|
|
1498
|
+
sidebar,
|
|
1499
|
+
topbar,
|
|
1500
|
+
children,
|
|
1501
|
+
sidebarWidth = "md:w-64",
|
|
1502
|
+
contentWidth = "default",
|
|
1503
|
+
stickyTopbar = true,
|
|
1504
|
+
mobileSidebar,
|
|
1505
|
+
...props
|
|
1506
|
+
}, ref) => {
|
|
1507
|
+
const [mobileOpen, setMobileOpen] = React18__namespace.useState(false);
|
|
1508
|
+
const contentWidthClass = {
|
|
1509
|
+
default: "max-w-7xl w-full mx-auto",
|
|
1510
|
+
wide: "max-w-screen-2xl w-full mx-auto",
|
|
1511
|
+
full: "max-w-none w-full"
|
|
1512
|
+
}[contentWidth];
|
|
1513
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1514
|
+
"div",
|
|
1515
|
+
{
|
|
1516
|
+
ref,
|
|
1517
|
+
className: cn(
|
|
1518
|
+
"min-h-screen bg-canvas text-foreground flex flex-col md:flex-row",
|
|
1519
|
+
className
|
|
1520
|
+
),
|
|
1521
|
+
...props,
|
|
1522
|
+
children: [
|
|
1523
|
+
sidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1524
|
+
"aside",
|
|
1525
|
+
{
|
|
1526
|
+
className: cn(
|
|
1527
|
+
"border-r border-border bg-surface shrink-0 z-20",
|
|
1528
|
+
mobileSidebar ? "hidden md:flex" : "w-full md:flex",
|
|
1529
|
+
sidebarWidth
|
|
1530
|
+
),
|
|
1531
|
+
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 })
|
|
1532
|
+
}
|
|
1533
|
+
),
|
|
1534
|
+
mobileSidebar && mobileOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1535
|
+
"div",
|
|
1536
|
+
{
|
|
1537
|
+
onClick: () => setMobileOpen(false),
|
|
1538
|
+
className: "fixed inset-0 z-50 md:hidden bg-[color-mix(in_oklch,#09090b_45%,transparent)] backdrop-blur-[2px] transition-opacity duration-300",
|
|
1539
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1540
|
+
"aside",
|
|
1541
|
+
{
|
|
1542
|
+
onClick: (e) => e.stopPropagation(),
|
|
1543
|
+
className: "w-72 h-full bg-surface border-r border-border flex flex-col shadow-kj-lg",
|
|
1544
|
+
children: [
|
|
1545
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-border", children: [
|
|
1546
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-bold uppercase tracking-wider text-muted-foreground", children: "Navigation" }),
|
|
1547
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1548
|
+
"button",
|
|
1549
|
+
{
|
|
1550
|
+
type: "button",
|
|
1551
|
+
onClick: () => setMobileOpen(false),
|
|
1552
|
+
className: "p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer",
|
|
1553
|
+
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" }) })
|
|
1554
|
+
}
|
|
1555
|
+
)
|
|
1556
|
+
] }),
|
|
1557
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: mobileSidebar })
|
|
1558
|
+
]
|
|
1559
|
+
}
|
|
1560
|
+
)
|
|
1561
|
+
}
|
|
1562
|
+
),
|
|
1563
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [
|
|
1564
|
+
topbar && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1565
|
+
"header",
|
|
1566
|
+
{
|
|
1567
|
+
className: cn(
|
|
1568
|
+
"h-14 border-b border-border bg-surface flex items-center px-6 z-10 shrink-0 gap-4",
|
|
1569
|
+
stickyTopbar && "sticky top-0"
|
|
1570
|
+
),
|
|
1571
|
+
children: [
|
|
1572
|
+
mobileSidebar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1573
|
+
"button",
|
|
1574
|
+
{
|
|
1575
|
+
type: "button",
|
|
1576
|
+
onClick: () => setMobileOpen(true),
|
|
1577
|
+
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",
|
|
1578
|
+
"aria-label": "Open navigation",
|
|
1579
|
+
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: [
|
|
1580
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
|
|
1581
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
1582
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
|
|
1583
|
+
] })
|
|
1584
|
+
}
|
|
1585
|
+
),
|
|
1586
|
+
topbar
|
|
1587
|
+
]
|
|
1588
|
+
}
|
|
1589
|
+
),
|
|
1590
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: cn("flex-1 p-6 md:p-8", contentWidthClass), children })
|
|
1591
|
+
] })
|
|
1592
|
+
]
|
|
1593
|
+
}
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
);
|
|
1597
|
+
DashboardShell.displayName = "DashboardShell";
|
|
1598
|
+
var SettingsLayout = React18__namespace.forwardRef(
|
|
1599
|
+
({ className, sidebar, children, title, description, ...props }, ref) => {
|
|
1600
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-6 w-full", className), ...props, children: [
|
|
1601
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border pb-4", children: [
|
|
1602
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight text-foreground", children: title }),
|
|
1603
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: description })
|
|
1604
|
+
] }),
|
|
1605
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col lg:flex-row gap-8", children: [
|
|
1606
|
+
/* @__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 }) }),
|
|
1607
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 max-w-3xl", children })
|
|
1608
|
+
] })
|
|
1609
|
+
] });
|
|
1610
|
+
}
|
|
1611
|
+
);
|
|
1612
|
+
SettingsLayout.displayName = "SettingsLayout";
|
|
1613
|
+
var DetailPageLayout = React18__namespace.forwardRef(
|
|
1614
|
+
({ className, title, description, backHref, backLabel = "Back", onBackClick, actions, aside, children, ...props }, ref) => {
|
|
1615
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("space-y-6 w-full", className), ...props, children: [
|
|
1616
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1617
|
+
(backHref || onBackClick) && /* @__PURE__ */ jsxRuntime.jsx("div", { children: backHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1618
|
+
"a",
|
|
1619
|
+
{
|
|
1620
|
+
href: backHref,
|
|
1621
|
+
className: cn(
|
|
1622
|
+
buttonVariants({ variant: "ghost", size: "sm" }),
|
|
1623
|
+
"-ml-3 h-8 text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5"
|
|
1624
|
+
),
|
|
1625
|
+
children: [
|
|
1626
|
+
/* @__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" }) }),
|
|
1627
|
+
backLabel
|
|
1628
|
+
]
|
|
1629
|
+
}
|
|
1630
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1631
|
+
Button,
|
|
1632
|
+
{
|
|
1633
|
+
variant: "ghost",
|
|
1634
|
+
size: "sm",
|
|
1635
|
+
className: "-ml-3 h-8 text-muted-foreground hover:text-foreground",
|
|
1636
|
+
onClick: onBackClick,
|
|
1637
|
+
children: [
|
|
1638
|
+
/* @__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" }) }),
|
|
1639
|
+
backLabel
|
|
1640
|
+
]
|
|
1641
|
+
}
|
|
1642
|
+
) }),
|
|
1643
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col md:flex-row md:items-center md:justify-between gap-4", children: [
|
|
1644
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1645
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold tracking-tight text-foreground", children: title }),
|
|
1646
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
1647
|
+
] }),
|
|
1648
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions })
|
|
1649
|
+
] })
|
|
1650
|
+
] }),
|
|
1651
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8 items-start", children: [
|
|
1652
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-6", aside ? "lg:col-span-2" : "lg:col-span-3"), children }),
|
|
1653
|
+
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 })
|
|
1654
|
+
] })
|
|
1655
|
+
] });
|
|
1656
|
+
}
|
|
1657
|
+
);
|
|
1658
|
+
DetailPageLayout.displayName = "DetailPageLayout";
|
|
1659
|
+
var TableToolbar = React18__namespace.forwardRef(
|
|
1660
|
+
({ className, searchQuery, onSearchChange, searchPlaceholder = "Search...", actions, filters, ...props }, ref) => {
|
|
1661
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
ref,
|
|
1665
|
+
className: cn(
|
|
1666
|
+
"flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3 w-full pb-1",
|
|
1667
|
+
className
|
|
1668
|
+
),
|
|
1669
|
+
...props,
|
|
1670
|
+
children: [
|
|
1671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col sm:flex-row items-stretch sm:items-center gap-2 max-w-xl", children: [
|
|
1672
|
+
onSearchChange && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1673
|
+
Input,
|
|
1674
|
+
{
|
|
1675
|
+
type: "search",
|
|
1676
|
+
placeholder: searchPlaceholder,
|
|
1677
|
+
value: searchQuery,
|
|
1678
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
1679
|
+
className: "sm:w-64",
|
|
1680
|
+
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" }) })
|
|
1681
|
+
}
|
|
1682
|
+
),
|
|
1683
|
+
filters && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: filters })
|
|
1684
|
+
] }),
|
|
1685
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0 justify-end", children: actions })
|
|
1686
|
+
]
|
|
1687
|
+
}
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1690
|
+
);
|
|
1691
|
+
TableToolbar.displayName = "TableToolbar";
|
|
1692
|
+
function ConfirmDialog({
|
|
1693
|
+
open,
|
|
1694
|
+
onClose,
|
|
1695
|
+
onConfirm,
|
|
1696
|
+
title,
|
|
1697
|
+
description,
|
|
1698
|
+
confirmLabel = "Confirm",
|
|
1699
|
+
cancelLabel = "Cancel",
|
|
1700
|
+
tone = "primary",
|
|
1701
|
+
loading = false
|
|
1702
|
+
}) {
|
|
1703
|
+
const toneButtonVariant = {
|
|
1704
|
+
danger: "danger",
|
|
1705
|
+
primary: "primary",
|
|
1706
|
+
success: "secondary"
|
|
1707
|
+
// standard secondary in our system is teal (success-aligned)
|
|
1708
|
+
}[tone];
|
|
1709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { open, onClose, width: 400, showClose: !loading, children: [
|
|
1710
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalTitle, { children: title }),
|
|
1711
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalDescription, { children: description }),
|
|
1712
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ModalActions, { children: [
|
|
1713
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: onClose, disabled: loading, children: cancelLabel }),
|
|
1714
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: toneButtonVariant, onClick: onConfirm, loading, children: confirmLabel })
|
|
1715
|
+
] })
|
|
1716
|
+
] });
|
|
1717
|
+
}
|
|
1718
|
+
ConfirmDialog.displayName = "ConfirmDialog";
|
|
1719
|
+
function Drawer({
|
|
1720
|
+
open,
|
|
1721
|
+
onClose,
|
|
1722
|
+
children,
|
|
1723
|
+
title,
|
|
1724
|
+
description,
|
|
1725
|
+
width = "max-w-md",
|
|
1726
|
+
side = "right"
|
|
1727
|
+
}) {
|
|
1728
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1729
|
+
const lastActiveElement = React18__namespace.useRef(null);
|
|
1730
|
+
React18__namespace.useEffect(() => {
|
|
1731
|
+
if (!open) {
|
|
1732
|
+
if (lastActiveElement.current) {
|
|
1733
|
+
lastActiveElement.current.focus();
|
|
1734
|
+
lastActiveElement.current = null;
|
|
1735
|
+
}
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
lastActiveElement.current = document.activeElement;
|
|
1739
|
+
const container = containerRef.current;
|
|
1740
|
+
if (container) {
|
|
1741
|
+
const focusables = container.querySelectorAll(
|
|
1742
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
1743
|
+
);
|
|
1744
|
+
if (focusables.length > 0) {
|
|
1745
|
+
setTimeout(() => focusables[0].focus(), 50);
|
|
1746
|
+
} else {
|
|
1747
|
+
container.focus();
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
const handleKeyDown = (e) => {
|
|
1751
|
+
if (e.key === "Escape") {
|
|
1752
|
+
onClose();
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
if (e.key === "Tab") {
|
|
1756
|
+
const container2 = containerRef.current;
|
|
1757
|
+
if (!container2) return;
|
|
1758
|
+
const focusables = Array.from(
|
|
1759
|
+
container2.querySelectorAll(
|
|
1760
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
1761
|
+
)
|
|
1762
|
+
);
|
|
1763
|
+
if (focusables.length === 0) {
|
|
1764
|
+
e.preventDefault();
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
const first = focusables[0];
|
|
1768
|
+
const last = focusables[focusables.length - 1];
|
|
1769
|
+
if (e.shiftKey) {
|
|
1770
|
+
if (document.activeElement === first || document.activeElement === container2) {
|
|
1771
|
+
last.focus();
|
|
1772
|
+
e.preventDefault();
|
|
1773
|
+
}
|
|
1774
|
+
} else {
|
|
1775
|
+
if (document.activeElement === last) {
|
|
1776
|
+
first.focus();
|
|
1777
|
+
e.preventDefault();
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
};
|
|
1782
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1783
|
+
document.body.style.overflow = "hidden";
|
|
1784
|
+
return () => {
|
|
1785
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1786
|
+
document.body.style.overflow = "";
|
|
1787
|
+
};
|
|
1788
|
+
}, [open, onClose]);
|
|
1789
|
+
const sideClasses = {
|
|
1790
|
+
right: cn(
|
|
1791
|
+
"right-0 h-full border-l",
|
|
1792
|
+
open ? "translate-x-0" : "translate-x-full"
|
|
1793
|
+
),
|
|
1794
|
+
left: cn(
|
|
1795
|
+
"left-0 h-full border-r",
|
|
1796
|
+
open ? "translate-x-0" : "-translate-x-full"
|
|
1797
|
+
)
|
|
1798
|
+
}[side];
|
|
1799
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1245
1800
|
"div",
|
|
1246
1801
|
{
|
|
1247
|
-
|
|
1802
|
+
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
1248
1803
|
className: cn(
|
|
1249
|
-
"
|
|
1250
|
-
|
|
1804
|
+
"fixed inset-0 z-[100] transition-opacity duration-300 backdrop-blur-[2px]",
|
|
1805
|
+
"bg-[color-mix(in_oklch,#09090b_45%,transparent)]",
|
|
1806
|
+
open ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
|
1251
1807
|
),
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1808
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1809
|
+
"div",
|
|
1810
|
+
{
|
|
1811
|
+
ref: containerRef,
|
|
1812
|
+
role: "dialog",
|
|
1813
|
+
"aria-modal": "true",
|
|
1814
|
+
"aria-label": !title ? "Drawer" : void 0,
|
|
1815
|
+
"aria-labelledby": title ? "drawer-title" : void 0,
|
|
1816
|
+
"aria-describedby": description ? "drawer-description" : void 0,
|
|
1817
|
+
tabIndex: -1,
|
|
1818
|
+
className: cn(
|
|
1819
|
+
"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",
|
|
1820
|
+
width,
|
|
1821
|
+
sideClasses
|
|
1822
|
+
),
|
|
1823
|
+
children: [
|
|
1824
|
+
(title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-6 border-b border-border", children: [
|
|
1825
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
1826
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: "drawer-title", className: "text-lg font-bold tracking-tight text-foreground", children: title }),
|
|
1827
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "drawer-description", className: "text-xs text-muted-foreground", children: description })
|
|
1828
|
+
] }),
|
|
1829
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1830
|
+
"button",
|
|
1831
|
+
{
|
|
1832
|
+
type: "button",
|
|
1833
|
+
onClick: onClose,
|
|
1834
|
+
"aria-label": "Close",
|
|
1835
|
+
className: "p-1.5 rounded-kj-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer",
|
|
1836
|
+
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" }) })
|
|
1837
|
+
}
|
|
1838
|
+
)
|
|
1839
|
+
] }),
|
|
1840
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto p-6", children })
|
|
1841
|
+
]
|
|
1842
|
+
}
|
|
1843
|
+
)
|
|
1260
1844
|
}
|
|
1261
|
-
)
|
|
1262
|
-
|
|
1263
|
-
|
|
1845
|
+
);
|
|
1846
|
+
}
|
|
1847
|
+
Drawer.displayName = "Drawer";
|
|
1848
|
+
function CommandPalette({ open, onClose, items, placeholder = "Type a command or search..." }) {
|
|
1849
|
+
const [search, setSearch] = React18__namespace.useState("");
|
|
1850
|
+
const [activeIndex, setActiveIndex] = React18__namespace.useState(0);
|
|
1851
|
+
const containerRef = React18__namespace.useRef(null);
|
|
1852
|
+
const listRef = React18__namespace.useRef(null);
|
|
1853
|
+
React18__namespace.useEffect(() => {
|
|
1854
|
+
if (open) {
|
|
1855
|
+
setSearch("");
|
|
1856
|
+
setActiveIndex(0);
|
|
1857
|
+
document.body.style.overflow = "hidden";
|
|
1858
|
+
} else {
|
|
1859
|
+
document.body.style.overflow = "";
|
|
1860
|
+
}
|
|
1861
|
+
}, [open]);
|
|
1862
|
+
const filteredItems = React18__namespace.useMemo(() => {
|
|
1863
|
+
if (!search) return items;
|
|
1864
|
+
const cleanSearch = search.toLowerCase();
|
|
1865
|
+
return items.filter(
|
|
1866
|
+
(item) => item.title.toLowerCase().includes(cleanSearch) || item.subtitle?.toLowerCase().includes(cleanSearch) || item.category?.toLowerCase().includes(cleanSearch)
|
|
1867
|
+
);
|
|
1868
|
+
}, [search, items]);
|
|
1869
|
+
React18__namespace.useEffect(() => {
|
|
1870
|
+
setActiveIndex(0);
|
|
1871
|
+
}, [filteredItems]);
|
|
1872
|
+
React18__namespace.useEffect(() => {
|
|
1873
|
+
if (!open) return;
|
|
1874
|
+
const handleKeyDown = (e) => {
|
|
1875
|
+
if (e.key === "Escape") {
|
|
1876
|
+
onClose();
|
|
1877
|
+
return;
|
|
1878
|
+
}
|
|
1879
|
+
if (e.key === "ArrowDown") {
|
|
1880
|
+
e.preventDefault();
|
|
1881
|
+
setActiveIndex((prev) => filteredItems.length === 0 ? 0 : (prev + 1) % filteredItems.length);
|
|
1882
|
+
} else if (e.key === "ArrowUp") {
|
|
1883
|
+
e.preventDefault();
|
|
1884
|
+
setActiveIndex((prev) => filteredItems.length === 0 ? 0 : (prev - 1 + filteredItems.length) % filteredItems.length);
|
|
1885
|
+
} else if (e.key === "Enter") {
|
|
1886
|
+
e.preventDefault();
|
|
1887
|
+
if (filteredItems[activeIndex]) {
|
|
1888
|
+
filteredItems[activeIndex].action();
|
|
1889
|
+
onClose();
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
};
|
|
1893
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1894
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1895
|
+
}, [open, filteredItems, activeIndex, onClose]);
|
|
1896
|
+
React18__namespace.useEffect(() => {
|
|
1897
|
+
if (listRef.current) {
|
|
1898
|
+
const activeEl = listRef.current.children[activeIndex];
|
|
1899
|
+
if (activeEl) {
|
|
1900
|
+
activeEl.scrollIntoView({ block: "nearest" });
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
}, [activeIndex]);
|
|
1904
|
+
if (!open) return null;
|
|
1905
|
+
const groups = {};
|
|
1906
|
+
filteredItems.forEach((item) => {
|
|
1907
|
+
const cat = item.category || "General";
|
|
1908
|
+
if (!groups[cat]) groups[cat] = [];
|
|
1909
|
+
groups[cat].push(item);
|
|
1910
|
+
});
|
|
1911
|
+
let absoluteItemIndex = 0;
|
|
1912
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1913
|
+
"div",
|
|
1914
|
+
{
|
|
1915
|
+
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
1916
|
+
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)]",
|
|
1917
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1918
|
+
"div",
|
|
1919
|
+
{
|
|
1920
|
+
ref: containerRef,
|
|
1921
|
+
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]",
|
|
1922
|
+
children: [
|
|
1923
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
|
|
1924
|
+
/* @__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" }) }),
|
|
1925
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1926
|
+
"input",
|
|
1927
|
+
{
|
|
1928
|
+
type: "text",
|
|
1929
|
+
placeholder,
|
|
1930
|
+
value: search,
|
|
1931
|
+
onChange: (e) => setSearch(e.target.value),
|
|
1932
|
+
className: "flex-1 font-sans text-[0.95rem] bg-transparent text-foreground placeholder:text-muted-foreground outline-none border-none focus:ring-0",
|
|
1933
|
+
autoFocus: true
|
|
1934
|
+
}
|
|
1935
|
+
)
|
|
1936
|
+
] }),
|
|
1937
|
+
/* @__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: [
|
|
1938
|
+
'No results found for "',
|
|
1939
|
+
search,
|
|
1940
|
+
'"'
|
|
1941
|
+
] }) : /* @__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: [
|
|
1942
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground", children: cat }),
|
|
1943
|
+
itemsInCat.map((item) => {
|
|
1944
|
+
const currentIdx = absoluteItemIndex++;
|
|
1945
|
+
const isActive = currentIdx === activeIndex;
|
|
1946
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1947
|
+
"div",
|
|
1948
|
+
{
|
|
1949
|
+
onClick: () => {
|
|
1950
|
+
item.action();
|
|
1951
|
+
onClose();
|
|
1952
|
+
},
|
|
1953
|
+
className: cn(
|
|
1954
|
+
"flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
|
|
1955
|
+
isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1956
|
+
),
|
|
1957
|
+
children: [
|
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
1959
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
|
|
1960
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex flex-col", children: [
|
|
1961
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
|
|
1962
|
+
item.subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
|
|
1963
|
+
] })
|
|
1964
|
+
] }),
|
|
1965
|
+
item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1966
|
+
"kbd",
|
|
1967
|
+
{
|
|
1968
|
+
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",
|
|
1969
|
+
children: sc
|
|
1970
|
+
},
|
|
1971
|
+
scIdx
|
|
1972
|
+
)) })
|
|
1973
|
+
]
|
|
1974
|
+
},
|
|
1975
|
+
item.id
|
|
1976
|
+
);
|
|
1977
|
+
})
|
|
1978
|
+
] }, cat)) }) }),
|
|
1979
|
+
/* @__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: [
|
|
1980
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1981
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
1982
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "\u2191\u2193" }),
|
|
1983
|
+
" Navigate"
|
|
1984
|
+
] }),
|
|
1985
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
1986
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "Enter" }),
|
|
1987
|
+
" Select"
|
|
1988
|
+
] })
|
|
1989
|
+
] }),
|
|
1990
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1991
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "font-mono text-[9px] px-1 border rounded bg-surface", children: "Esc" }),
|
|
1992
|
+
" Close"
|
|
1993
|
+
] })
|
|
1994
|
+
] })
|
|
1995
|
+
]
|
|
1996
|
+
}
|
|
1997
|
+
)
|
|
1998
|
+
}
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
CommandPalette.displayName = "CommandPalette";
|
|
2002
|
+
function SidebarNav({ className, groups, currentHref, ...props }) {
|
|
2003
|
+
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: [
|
|
2004
|
+
group.title && /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "px-3 text-[10px] font-bold uppercase tracking-widest text-muted-foreground/85", children: group.title }),
|
|
2005
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: group.items.map((item) => {
|
|
2006
|
+
const isActive = item.active || item.href && currentHref && currentHref === item.href;
|
|
2007
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2008
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2.5 min-w-0", children: [
|
|
2009
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
2010
|
+
"[&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem] shrink-0",
|
|
2011
|
+
isActive ? "text-primary" : "text-muted-foreground group-hover:text-foreground"
|
|
2012
|
+
), children: item.icon }),
|
|
2013
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: item.label })
|
|
2014
|
+
] }),
|
|
2015
|
+
item.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 flex items-center justify-center", children: item.badge })
|
|
2016
|
+
] });
|
|
2017
|
+
const itemClass = cn(
|
|
2018
|
+
"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",
|
|
2019
|
+
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"
|
|
2020
|
+
);
|
|
2021
|
+
if (item.href) {
|
|
2022
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: itemClass, children: content }, item.id);
|
|
2023
|
+
}
|
|
2024
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2025
|
+
"button",
|
|
2026
|
+
{
|
|
2027
|
+
type: "button",
|
|
2028
|
+
onClick: item.onClick,
|
|
2029
|
+
className: itemClass,
|
|
2030
|
+
children: content
|
|
2031
|
+
},
|
|
2032
|
+
item.id
|
|
2033
|
+
);
|
|
2034
|
+
}) })
|
|
2035
|
+
] }, groupIdx)) });
|
|
2036
|
+
}
|
|
2037
|
+
SidebarNav.displayName = "SidebarNav";
|
|
1264
2038
|
|
|
1265
2039
|
exports.Accordion = Accordion;
|
|
1266
2040
|
exports.AccordionContent = AccordionContent;
|
|
@@ -1270,6 +2044,7 @@ exports.Alert = Alert;
|
|
|
1270
2044
|
exports.Avatar = Avatar;
|
|
1271
2045
|
exports.AvatarGroup = AvatarGroup;
|
|
1272
2046
|
exports.Badge = Badge;
|
|
2047
|
+
exports.BottomNavigation = BottomNavigation;
|
|
1273
2048
|
exports.Breadcrumb = Breadcrumb;
|
|
1274
2049
|
exports.BreadcrumbItem = BreadcrumbItem;
|
|
1275
2050
|
exports.BreadcrumbSeparator = BreadcrumbSeparator;
|
|
@@ -1281,8 +2056,13 @@ exports.CardFooter = CardFooter;
|
|
|
1281
2056
|
exports.CardHeader = CardHeader;
|
|
1282
2057
|
exports.CardTitle = CardTitle;
|
|
1283
2058
|
exports.Checkbox = Checkbox;
|
|
2059
|
+
exports.CheckboxField = CheckboxField;
|
|
2060
|
+
exports.CommandPalette = CommandPalette;
|
|
2061
|
+
exports.ConfirmDialog = ConfirmDialog;
|
|
1284
2062
|
exports.DashboardShell = DashboardShell;
|
|
1285
2063
|
exports.DataTable = DataTable;
|
|
2064
|
+
exports.DetailPageLayout = DetailPageLayout;
|
|
2065
|
+
exports.Drawer = Drawer;
|
|
1286
2066
|
exports.DropdownMenu = DropdownMenu;
|
|
1287
2067
|
exports.DropdownMenuContent = DropdownMenuContent;
|
|
1288
2068
|
exports.DropdownMenuItem = DropdownMenuItem;
|
|
@@ -1306,6 +2086,9 @@ exports.Progress = Progress;
|
|
|
1306
2086
|
exports.Radio = Radio;
|
|
1307
2087
|
exports.Segmented = Segmented;
|
|
1308
2088
|
exports.Select = Select;
|
|
2089
|
+
exports.SelectField = SelectField;
|
|
2090
|
+
exports.SettingsLayout = SettingsLayout;
|
|
2091
|
+
exports.SidebarNav = SidebarNav;
|
|
1309
2092
|
exports.Skeleton = Skeleton;
|
|
1310
2093
|
exports.Slider = Slider;
|
|
1311
2094
|
exports.Spinner = Spinner;
|
|
@@ -1317,11 +2100,13 @@ exports.TableCell = TableCell;
|
|
|
1317
2100
|
exports.TableHead = TableHead;
|
|
1318
2101
|
exports.TableHeader = TableHeader;
|
|
1319
2102
|
exports.TableRow = TableRow;
|
|
2103
|
+
exports.TableToolbar = TableToolbar;
|
|
1320
2104
|
exports.TableWrap = TableWrap;
|
|
1321
2105
|
exports.Tabs = Tabs;
|
|
1322
2106
|
exports.TabsContent = TabsContent;
|
|
1323
2107
|
exports.TabsList = TabsList;
|
|
1324
2108
|
exports.TabsTrigger = TabsTrigger;
|
|
2109
|
+
exports.TextField = TextField;
|
|
1325
2110
|
exports.Textarea = Textarea;
|
|
1326
2111
|
exports.ToastProvider = ToastProvider;
|
|
1327
2112
|
exports.Tooltip = Tooltip;
|