@martinsura/ui 0.1.2 → 0.1.4
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 +892 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.cts +297 -7
- package/dist/index.d.ts +297 -7
- package/dist/index.js +870 -214
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cva } from 'class-variance-authority';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import { IconDownload, IconPaperclip, IconFileSpreadsheet, IconX, IconTrashX, IconPlus, IconPencil, IconDotsVertical,
|
|
3
|
+
import { IconEyeOff, IconEye, IconDownload, IconPaperclip, IconFileSpreadsheet, IconX, IconTrashX, IconPlus, IconPencil, IconDotsVertical, IconCheck, IconDroplet, IconSearch, IconDatabaseOff, IconChevronUp, IconChevronDown, IconSelector, IconCalendar, IconUsers, IconInfoCircle, IconAlertTriangle, IconCircleX, IconBold, IconItalic, IconUnderline, IconList, IconListNumbers, IconLink, IconUnlink, IconClearFormatting, IconUpload, IconAlertCircle, IconTrash, IconMinus, IconArrowDownRight, IconArrowUpRight, IconLoader2, IconChevronLeft, IconChevronRight } from '@tabler/icons-react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
|
-
import { createContext,
|
|
5
|
+
import { createContext, forwardRef, useState, useContext, useRef, useLayoutEffect, useEffect, useMemo, useCallback, useId } from 'react';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
7
7
|
import dayjs from 'dayjs';
|
|
8
8
|
|
|
@@ -321,7 +321,9 @@ var buttonVariants = cva(
|
|
|
321
321
|
danger: "bg-(--ui-danger) text-(--ui-danger-text) hover:bg-(--ui-danger-hover) active:bg-(--ui-danger-hover)",
|
|
322
322
|
success: "bg-(--ui-success) text-(--ui-success-text) hover:bg-(--ui-success-hover) active:bg-(--ui-success-hover)",
|
|
323
323
|
default: "bg-white text-(--ui-text) border border-(--ui-border-strong) hover:bg-(--ui-surface-subtle) active:bg-(--ui-surface-muted)",
|
|
324
|
+
subtle: "bg-(--ui-surface-subtle) text-(--ui-text) border border-transparent hover:bg-(--ui-surface-muted) active:bg-(--ui-surface-muted)",
|
|
324
325
|
ghost: "text-(--ui-text) hover:bg-(--ui-surface-muted) active:bg-(--ui-surface-subtle)",
|
|
326
|
+
text: "text-(--ui-text) hover:text-(--ui-text-strong) active:text-(--ui-text-strong) px-0! bg-transparent",
|
|
325
327
|
link: "text-(--ui-primary) hover:underline p-0! h-auto!"
|
|
326
328
|
},
|
|
327
329
|
size: {
|
|
@@ -357,12 +359,14 @@ var Button = ({
|
|
|
357
359
|
size = "middle",
|
|
358
360
|
shape = "default",
|
|
359
361
|
block = false,
|
|
362
|
+
fullWidthOnMobile = false,
|
|
360
363
|
iconPosition = "left",
|
|
361
364
|
...props
|
|
362
365
|
}) => {
|
|
363
366
|
const iconSize = props.iconSize ?? iconSizeMap[size];
|
|
364
367
|
const IconComponent = props.icon ?? (props.iconType ? getIcon(props.iconType) : void 0);
|
|
365
368
|
const iconNode = IconComponent ? /* @__PURE__ */ jsx(IconComponent, { size: iconSize, strokeWidth: 1.5, className: props.classNames?.icon }) : void 0;
|
|
369
|
+
const content = props.text ?? props.children;
|
|
366
370
|
const handleClick = () => {
|
|
367
371
|
if (props.disabled || props.loading) {
|
|
368
372
|
return;
|
|
@@ -374,11 +378,16 @@ var Button = ({
|
|
|
374
378
|
{
|
|
375
379
|
type: props.htmlType ?? "button",
|
|
376
380
|
disabled: props.disabled || props.loading,
|
|
377
|
-
className: twMerge(
|
|
381
|
+
className: twMerge(
|
|
382
|
+
buttonVariants({ variant, size, block, shape }),
|
|
383
|
+
fullWidthOnMobile && !block && "w-full sm:w-auto",
|
|
384
|
+
props.iconOnly && "px-0!",
|
|
385
|
+
props.className
|
|
386
|
+
),
|
|
378
387
|
onClick: props.confirm ? void 0 : handleClick,
|
|
379
388
|
children: [
|
|
380
389
|
props.loading ? /* @__PURE__ */ jsx(Spinner, { size: iconSize, color: "current", className: props.classNames?.spinner }) : iconPosition === "left" && iconNode,
|
|
381
|
-
/* @__PURE__ */ jsx("span", { className: props.classNames?.content, children:
|
|
390
|
+
!props.iconOnly && content !== void 0 && content !== null && /* @__PURE__ */ jsx("span", { className: props.classNames?.content, children: content }),
|
|
382
391
|
!props.loading && iconPosition === "right" && iconNode
|
|
383
392
|
]
|
|
384
393
|
}
|
|
@@ -398,6 +407,21 @@ var Button = ({
|
|
|
398
407
|
}
|
|
399
408
|
);
|
|
400
409
|
};
|
|
410
|
+
var ConfirmButton = (props) => /* @__PURE__ */ jsx(
|
|
411
|
+
Button,
|
|
412
|
+
{
|
|
413
|
+
text: props.text,
|
|
414
|
+
onClick: props.onClick,
|
|
415
|
+
disabled: props.disabled,
|
|
416
|
+
loading: props.loading,
|
|
417
|
+
variant: props.variant,
|
|
418
|
+
size: props.size,
|
|
419
|
+
icon: props.icon,
|
|
420
|
+
className: props.className,
|
|
421
|
+
confirm: props.confirm,
|
|
422
|
+
children: props.children
|
|
423
|
+
}
|
|
424
|
+
);
|
|
401
425
|
var InputField = ({ noMargin, className, children }) => /* @__PURE__ */ jsx("div", { className: twMerge("flex flex-col gap-1", !noMargin && "mb-3", className), children });
|
|
402
426
|
var InputLabel = ({ label, required, className, requiredMarkClassName }) => /* @__PURE__ */ jsxs("label", { className: twMerge("text-sm text-(--ui-text)", className), children: [
|
|
403
427
|
label,
|
|
@@ -411,12 +435,12 @@ var ErrorContext = createContext({
|
|
|
411
435
|
var ErrorProvider = ({ resolveInputError, resolveServerError, children }) => /* @__PURE__ */ jsx(ErrorContext.Provider, { value: { resolveInputError, resolveServerError }, children });
|
|
412
436
|
var useErrorResolver = () => useContext(ErrorContext).resolveInputError;
|
|
413
437
|
var useServerError = () => useContext(ErrorContext).resolveServerError;
|
|
414
|
-
var TextInput = ({
|
|
438
|
+
var TextInput = forwardRef(({
|
|
415
439
|
size = "middle",
|
|
416
440
|
password = false,
|
|
417
441
|
newPassword = false,
|
|
418
442
|
...props
|
|
419
|
-
}) => {
|
|
443
|
+
}, ref) => {
|
|
420
444
|
const [showPassword, setShowPassword] = useState(false);
|
|
421
445
|
const resolveError = useErrorResolver();
|
|
422
446
|
const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
|
|
@@ -437,6 +461,7 @@ var TextInput = ({
|
|
|
437
461
|
/* @__PURE__ */ jsx(
|
|
438
462
|
"input",
|
|
439
463
|
{
|
|
464
|
+
ref,
|
|
440
465
|
type: inputType,
|
|
441
466
|
autoComplete: newPassword ? "new-password" : void 0,
|
|
442
467
|
placeholder: props.placeholder,
|
|
@@ -470,6 +495,27 @@ var TextInput = ({
|
|
|
470
495
|
] }),
|
|
471
496
|
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
|
|
472
497
|
] });
|
|
498
|
+
});
|
|
499
|
+
TextInput.displayName = "TextInput";
|
|
500
|
+
var Textarea = ({ rows = 4, ...props }) => {
|
|
501
|
+
const resolveError = useErrorResolver();
|
|
502
|
+
const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
|
|
503
|
+
const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
|
|
504
|
+
return /* @__PURE__ */ jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
|
|
505
|
+
props.label && /* @__PURE__ */ jsx(InputLabel, { label: props.label, required: props.required }),
|
|
506
|
+
/* @__PURE__ */ jsx(
|
|
507
|
+
"textarea",
|
|
508
|
+
{
|
|
509
|
+
rows,
|
|
510
|
+
value: props.value ?? "",
|
|
511
|
+
placeholder: props.placeholder,
|
|
512
|
+
disabled: props.disabled,
|
|
513
|
+
onChange: (e) => props.onChange?.(e.target.value),
|
|
514
|
+
className: twMerge(inputBaseClass, "min-h-24 py-2", errorDisplay && "border-(--ui-danger)")
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay) })
|
|
518
|
+
] });
|
|
473
519
|
};
|
|
474
520
|
var numberInputClass = inputBaseClass + " [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none";
|
|
475
521
|
var NumberInput = ({
|
|
@@ -578,6 +624,49 @@ var CheckboxInput = ({
|
|
|
578
624
|
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
|
|
579
625
|
] });
|
|
580
626
|
};
|
|
627
|
+
var RadioGroup = ({
|
|
628
|
+
direction = "column",
|
|
629
|
+
...props
|
|
630
|
+
}) => {
|
|
631
|
+
const resolveError = useErrorResolver();
|
|
632
|
+
const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
|
|
633
|
+
const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
|
|
634
|
+
return /* @__PURE__ */ jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
|
|
635
|
+
props.label && /* @__PURE__ */ jsx(InputLabel, { label: props.label, required: props.required }),
|
|
636
|
+
/* @__PURE__ */ jsx("div", { className: twMerge("flex gap-2", direction === "column" ? "flex-col" : "flex-wrap items-stretch"), children: props.options.map((option) => {
|
|
637
|
+
const checked = props.value === option.value;
|
|
638
|
+
const isDisabled = props.disabled || option.disabled;
|
|
639
|
+
return /* @__PURE__ */ jsxs(
|
|
640
|
+
"label",
|
|
641
|
+
{
|
|
642
|
+
className: twMerge(
|
|
643
|
+
"flex items-start gap-3 rounded-(--ui-radius-md) border border-(--ui-border) bg-white px-3 py-2",
|
|
644
|
+
checked && "border-(--ui-border-focus) bg-(--ui-surface-subtle)",
|
|
645
|
+
isDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
|
|
646
|
+
),
|
|
647
|
+
children: [
|
|
648
|
+
/* @__PURE__ */ jsx(
|
|
649
|
+
"input",
|
|
650
|
+
{
|
|
651
|
+
type: "radio",
|
|
652
|
+
className: "mt-1 h-4 w-4 accent-(--ui-primary)",
|
|
653
|
+
checked,
|
|
654
|
+
disabled: isDisabled,
|
|
655
|
+
onChange: () => props.onChange?.(option.value)
|
|
656
|
+
}
|
|
657
|
+
),
|
|
658
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
659
|
+
/* @__PURE__ */ jsx("span", { className: "block text-sm text-(--ui-text)", children: option.label }),
|
|
660
|
+
option.description && /* @__PURE__ */ jsx("span", { className: twMerge("block text-xs", neutralTextClasses.soft), children: option.description })
|
|
661
|
+
] })
|
|
662
|
+
]
|
|
663
|
+
},
|
|
664
|
+
option.value
|
|
665
|
+
);
|
|
666
|
+
}) }),
|
|
667
|
+
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay) })
|
|
668
|
+
] });
|
|
669
|
+
};
|
|
581
670
|
var SwitchInput = ({
|
|
582
671
|
value = false,
|
|
583
672
|
size = "middle",
|
|
@@ -645,7 +734,7 @@ var SwitchInput = ({
|
|
|
645
734
|
|
|
646
735
|
// src/floating/layerStack.ts
|
|
647
736
|
var FLOATING_ROOT_SELECTOR = "[data-ui-floating-root]";
|
|
648
|
-
var
|
|
737
|
+
var LAYER_ROOT_SELECTOR = "[data-ui-layer-root]";
|
|
649
738
|
function getTopmostElement(selector) {
|
|
650
739
|
const elements = document.querySelectorAll(selector);
|
|
651
740
|
return elements.length > 0 ? elements[elements.length - 1] : null;
|
|
@@ -656,8 +745,8 @@ function hasFloatingRootOpen() {
|
|
|
656
745
|
function isTopmostFloatingRoot(element) {
|
|
657
746
|
return element !== null && getTopmostElement(FLOATING_ROOT_SELECTOR) === element;
|
|
658
747
|
}
|
|
659
|
-
function
|
|
660
|
-
return element !== null && getTopmostElement(
|
|
748
|
+
function isTopmostLayerRoot(element) {
|
|
749
|
+
return element !== null && getTopmostElement(LAYER_ROOT_SELECTOR) === element;
|
|
661
750
|
}
|
|
662
751
|
function isTargetInsideFloatingRoot(target) {
|
|
663
752
|
return target instanceof Element && target.closest(FLOATING_ROOT_SELECTOR) !== null;
|
|
@@ -1289,6 +1378,65 @@ var ColorInput = ({
|
|
|
1289
1378
|
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
|
|
1290
1379
|
] });
|
|
1291
1380
|
};
|
|
1381
|
+
var SearchInput = ({ ...props }) => {
|
|
1382
|
+
const resolveError = useErrorResolver();
|
|
1383
|
+
const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
|
|
1384
|
+
const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
|
|
1385
|
+
const hasValue = !!props.value;
|
|
1386
|
+
return /* @__PURE__ */ jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
|
|
1387
|
+
props.label && /* @__PURE__ */ jsx(InputLabel, { label: props.label }),
|
|
1388
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1389
|
+
/* @__PURE__ */ jsx(IconSearch, { size: 15, strokeWidth: 1.75, className: twMerge("pointer-events-none absolute left-3 top-1/2 -translate-y-1/2", neutralIconClasses.default) }),
|
|
1390
|
+
/* @__PURE__ */ jsx(
|
|
1391
|
+
"input",
|
|
1392
|
+
{
|
|
1393
|
+
value: props.value ?? "",
|
|
1394
|
+
onChange: (e) => props.onChange?.(e.target.value),
|
|
1395
|
+
placeholder: props.placeholder ?? "Hledat...",
|
|
1396
|
+
className: twMerge(inputBaseClass, "pl-9 pr-9", errorDisplay && "border-(--ui-danger)")
|
|
1397
|
+
}
|
|
1398
|
+
),
|
|
1399
|
+
hasValue && /* @__PURE__ */ jsx(
|
|
1400
|
+
"button",
|
|
1401
|
+
{
|
|
1402
|
+
type: "button",
|
|
1403
|
+
onClick: () => {
|
|
1404
|
+
props.onChange?.("");
|
|
1405
|
+
props.onClear?.();
|
|
1406
|
+
},
|
|
1407
|
+
className: twMerge("absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer", neutralIconClasses.default, neutralIconClasses.hover),
|
|
1408
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 14, strokeWidth: 2 })
|
|
1409
|
+
}
|
|
1410
|
+
)
|
|
1411
|
+
] }),
|
|
1412
|
+
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay) })
|
|
1413
|
+
] });
|
|
1414
|
+
};
|
|
1415
|
+
var InlineEdit = ({ value, placeholder = "Klikn\u011Bte pro editaci", multiline = false, onSave, label, className }) => {
|
|
1416
|
+
const [editing, setEditing] = useState(false);
|
|
1417
|
+
const [draft, setDraft] = useState(value ?? "");
|
|
1418
|
+
const cancel = () => {
|
|
1419
|
+
setDraft(value ?? "");
|
|
1420
|
+
setEditing(false);
|
|
1421
|
+
};
|
|
1422
|
+
const save = () => {
|
|
1423
|
+
onSave?.(draft);
|
|
1424
|
+
setEditing(false);
|
|
1425
|
+
};
|
|
1426
|
+
return /* @__PURE__ */ jsxs("div", { className: twMerge("rounded-(--ui-radius-md) border border-(--ui-border) bg-white p-3", className), children: [
|
|
1427
|
+
label && /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium uppercase tracking-[0.08em] text-(--ui-text-soft)", children: label }),
|
|
1428
|
+
editing ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1429
|
+
multiline ? /* @__PURE__ */ jsx(Textarea, { value: draft, onChange: setDraft, noMargin: true, rows: 4 }) : /* @__PURE__ */ jsx(TextInput, { value: draft, onChange: setDraft, noMargin: true }),
|
|
1430
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1431
|
+
/* @__PURE__ */ jsx(Button, { size: "small", text: "Ulo\u017Eit", icon: IconCheck, onClick: save }),
|
|
1432
|
+
/* @__PURE__ */ jsx(Button, { size: "small", variant: "default", text: "Zru\u0161it", icon: IconX, onClick: cancel })
|
|
1433
|
+
] })
|
|
1434
|
+
] }) : /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => setEditing(true), className: "flex w-full items-start justify-between gap-3 text-left cursor-pointer", children: [
|
|
1435
|
+
/* @__PURE__ */ jsx("span", { className: value ? "text-(--ui-text)" : twMerge("italic", neutralTextClasses.soft), children: value || placeholder }),
|
|
1436
|
+
/* @__PURE__ */ jsx(IconPencil, { size: 14, strokeWidth: 1.75, className: neutralTextClasses.soft })
|
|
1437
|
+
] })
|
|
1438
|
+
] });
|
|
1439
|
+
};
|
|
1292
1440
|
var Empty = ({
|
|
1293
1441
|
text = "\u017D\xE1dn\xE9 z\xE1znamy k dispozici",
|
|
1294
1442
|
description,
|
|
@@ -1619,145 +1767,155 @@ var Grid = (props) => {
|
|
|
1619
1767
|
const next = selectedKeys.has(key) ? props.selection.selectedItems.filter((s) => getKey2(s, props.items, props.rowKey) !== key) : [...props.selection.selectedItems, item];
|
|
1620
1768
|
props.selection.onChange(next);
|
|
1621
1769
|
};
|
|
1622
|
-
return /* @__PURE__ */ jsxs(
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
col.align === "center" && "text-center",
|
|
1652
|
-
col.align === "right" && "text-right",
|
|
1653
|
-
props.classNames?.headerCell
|
|
1654
|
-
),
|
|
1655
|
-
children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1656
|
-
col.title,
|
|
1657
|
-
isSortable && /* @__PURE__ */ jsx("span", { className: "opacity-70", children: isCurrent ? grid.direction === SortDirection.Asc ? /* @__PURE__ */ jsx(IconChevronUp, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsx(IconChevronDown, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsx(IconSelector, { size: 12, strokeWidth: 2 }) })
|
|
1658
|
-
] })
|
|
1659
|
-
},
|
|
1660
|
-
i
|
|
1661
|
-
);
|
|
1662
|
-
})
|
|
1663
|
-
] }) }),
|
|
1664
|
-
/* @__PURE__ */ jsx("tbody", { children: isInitialLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1665
|
-
"td",
|
|
1666
|
-
{
|
|
1667
|
-
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1668
|
-
className: twMerge("px-3 py-0", props.classNames?.loadingCell),
|
|
1669
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex min-h-28 items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { size: "large", color: "primary" }) })
|
|
1670
|
-
}
|
|
1671
|
-
) }) : isEmpty ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1672
|
-
"td",
|
|
1673
|
-
{
|
|
1674
|
-
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1675
|
-
className: twMerge("px-3", props.classNames?.emptyCell),
|
|
1676
|
-
children: /* @__PURE__ */ jsx(Empty, { size: "compact", text: props.emptyText ?? "\u017D\xE1dn\xE9 z\xE1znamy", className: sc.emptyPy })
|
|
1677
|
-
}
|
|
1678
|
-
) }) : props.items.map((item, rowIdx) => {
|
|
1679
|
-
const key = getKey2(item, props.items, props.rowKey);
|
|
1680
|
-
const isSelected = selectedKeys.has(key);
|
|
1681
|
-
return /* @__PURE__ */ jsxs(
|
|
1682
|
-
"tr",
|
|
1683
|
-
{
|
|
1684
|
-
onClick: props.onRowClick ? () => props.onRowClick(item) : void 0,
|
|
1685
|
-
className: twMerge(
|
|
1686
|
-
"border-t border-(--ui-border) transition-colors",
|
|
1687
|
-
rowIdx % 2 === 1 && !isSelected && neutralSurfaceClasses.subtle,
|
|
1688
|
-
isSelected && "bg-blue-50",
|
|
1689
|
-
props.onRowClick && "cursor-pointer hover:bg-blue-50",
|
|
1690
|
-
props.classNames?.bodyRow
|
|
1691
|
-
),
|
|
1692
|
-
children: [
|
|
1693
|
-
props.selection && /* @__PURE__ */ jsx(
|
|
1694
|
-
"td",
|
|
1770
|
+
return /* @__PURE__ */ jsxs(
|
|
1771
|
+
"div",
|
|
1772
|
+
{
|
|
1773
|
+
className: twMerge(
|
|
1774
|
+
"relative border border-(--ui-border) rounded-(--ui-radius-lg) overflow-hidden",
|
|
1775
|
+
props.attachedTop && "rounded-t-none border-t-0",
|
|
1776
|
+
props.className
|
|
1777
|
+
),
|
|
1778
|
+
children: [
|
|
1779
|
+
props.loading && !isInitialLoading && /* @__PURE__ */ jsx("div", { className: twMerge("absolute inset-0 z-10 bg-white/60 flex items-center justify-center", props.classNames?.overlay), children: /* @__PURE__ */ jsx(Spinner, { size: "large", color: "primary" }) }),
|
|
1780
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: twMerge("w-full border-collapse", props.classNames?.table), children: [
|
|
1781
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: twMerge("bg-(--ui-primary) text-(--ui-primary-text)", props.classNames?.headerRow), children: [
|
|
1782
|
+
props.selection && /* @__PURE__ */ jsx("th", { className: twMerge(sc.th, "w-9", verticalBorders && tableHeaderVerticalBorderClass, props.classNames?.headerCell), children: /* @__PURE__ */ jsx(
|
|
1783
|
+
"input",
|
|
1784
|
+
{
|
|
1785
|
+
type: "checkbox",
|
|
1786
|
+
checked: allSelected,
|
|
1787
|
+
ref: (el) => {
|
|
1788
|
+
if (el) el.indeterminate = someSelected;
|
|
1789
|
+
},
|
|
1790
|
+
onChange: toggleAll,
|
|
1791
|
+
className: "cursor-pointer accent-white"
|
|
1792
|
+
}
|
|
1793
|
+
) }),
|
|
1794
|
+
props.columns.map((col, i) => {
|
|
1795
|
+
const isSortable = col.sortBy !== void 0;
|
|
1796
|
+
const isCurrent = isSortable && grid.sortBy === col.sortBy;
|
|
1797
|
+
return /* @__PURE__ */ jsx(
|
|
1798
|
+
"th",
|
|
1695
1799
|
{
|
|
1696
|
-
|
|
1697
|
-
onClick: (
|
|
1698
|
-
|
|
1699
|
-
|
|
1800
|
+
style: { width: col.width ?? columnTypeWidth2[col.type] },
|
|
1801
|
+
onClick: isSortable ? () => handleSort(col) : void 0,
|
|
1802
|
+
className: twMerge(
|
|
1803
|
+
sc.th,
|
|
1804
|
+
"font-normal text-left whitespace-nowrap",
|
|
1805
|
+
verticalBorders && tableHeaderVerticalBorderClass,
|
|
1806
|
+
isSortable && "cursor-pointer select-none hover:bg-white/10",
|
|
1807
|
+
col.align === "center" && "text-center",
|
|
1808
|
+
col.align === "right" && "text-right",
|
|
1809
|
+
props.classNames?.headerCell
|
|
1810
|
+
),
|
|
1811
|
+
children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1812
|
+
col.title,
|
|
1813
|
+
isSortable && /* @__PURE__ */ jsx("span", { className: "opacity-70", children: isCurrent ? grid.direction === SortDirection.Asc ? /* @__PURE__ */ jsx(IconChevronUp, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsx(IconChevronDown, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsx(IconSelector, { size: 12, strokeWidth: 2 }) })
|
|
1814
|
+
] })
|
|
1815
|
+
},
|
|
1816
|
+
i
|
|
1817
|
+
);
|
|
1818
|
+
})
|
|
1819
|
+
] }) }),
|
|
1820
|
+
/* @__PURE__ */ jsx("tbody", { children: isInitialLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1821
|
+
"td",
|
|
1822
|
+
{
|
|
1823
|
+
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1824
|
+
className: twMerge("px-3 py-0", props.classNames?.loadingCell),
|
|
1825
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex min-h-28 items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { size: "large", color: "primary" }) })
|
|
1826
|
+
}
|
|
1827
|
+
) }) : isEmpty ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1828
|
+
"td",
|
|
1829
|
+
{
|
|
1830
|
+
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1831
|
+
className: twMerge("px-3", props.classNames?.emptyCell),
|
|
1832
|
+
children: /* @__PURE__ */ jsx(Empty, { size: "compact", text: props.emptyText ?? "\u017D\xE1dn\xE9 z\xE1znamy", className: sc.emptyPy })
|
|
1833
|
+
}
|
|
1834
|
+
) }) : props.items.map((item, rowIdx) => {
|
|
1835
|
+
const key = getKey2(item, props.items, props.rowKey);
|
|
1836
|
+
const isSelected = selectedKeys.has(key);
|
|
1837
|
+
return /* @__PURE__ */ jsxs(
|
|
1838
|
+
"tr",
|
|
1839
|
+
{
|
|
1840
|
+
onClick: props.onRowClick ? () => props.onRowClick(item) : void 0,
|
|
1841
|
+
className: twMerge(
|
|
1842
|
+
"border-t border-(--ui-border) transition-colors",
|
|
1843
|
+
rowIdx % 2 === 1 && !isSelected && neutralSurfaceClasses.subtle,
|
|
1844
|
+
isSelected && "bg-blue-50",
|
|
1845
|
+
props.onRowClick && "cursor-pointer hover:bg-blue-50",
|
|
1846
|
+
props.classNames?.bodyRow
|
|
1847
|
+
),
|
|
1848
|
+
children: [
|
|
1849
|
+
props.selection && /* @__PURE__ */ jsx(
|
|
1850
|
+
"td",
|
|
1700
1851
|
{
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1852
|
+
className: twMerge(sc.td, "w-9 align-middle", verticalBorders && tableCellVerticalBorderClass, props.classNames?.bodyCell),
|
|
1853
|
+
onClick: (e) => e.stopPropagation(),
|
|
1854
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
1855
|
+
"input",
|
|
1856
|
+
{
|
|
1857
|
+
type: "checkbox",
|
|
1858
|
+
checked: isSelected,
|
|
1859
|
+
onChange: () => toggleRow(item),
|
|
1860
|
+
className: "cursor-pointer"
|
|
1861
|
+
}
|
|
1862
|
+
) })
|
|
1705
1863
|
}
|
|
1706
|
-
)
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
return /* @__PURE__ */ jsx(
|
|
1714
|
-
"td",
|
|
1715
|
-
{
|
|
1716
|
-
onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
|
|
1717
|
-
className: twMerge(
|
|
1718
|
-
sc.td,
|
|
1719
|
-
"align-middle",
|
|
1720
|
-
verticalBorders && tableCellVerticalBorderClass,
|
|
1721
|
-
col.ellipsis && "max-w-60 truncate",
|
|
1722
|
-
col.wrap && "whitespace-normal",
|
|
1723
|
-
col.align === "center" && "text-center",
|
|
1724
|
-
col.align === "right" && "text-right",
|
|
1725
|
-
col.type === "dot" && "w-9",
|
|
1726
|
-
props.classNames?.bodyCell
|
|
1727
|
-
),
|
|
1728
|
-
children: centeredContent || rightAlignedContent ? /* @__PURE__ */ jsx(
|
|
1729
|
-
"div",
|
|
1864
|
+
),
|
|
1865
|
+
props.columns.map((col, colIdx) => {
|
|
1866
|
+
const content = col.render ? col.render(item) : col.dataField ? formatCellValue(item[col.dataField], col.type) : null;
|
|
1867
|
+
const centeredContent = col.align === "center";
|
|
1868
|
+
const rightAlignedContent = col.align === "right";
|
|
1869
|
+
return /* @__PURE__ */ jsx(
|
|
1870
|
+
"td",
|
|
1730
1871
|
{
|
|
1872
|
+
onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
|
|
1731
1873
|
className: twMerge(
|
|
1732
|
-
|
|
1733
|
-
|
|
1874
|
+
sc.td,
|
|
1875
|
+
"align-middle",
|
|
1876
|
+
verticalBorders && tableCellVerticalBorderClass,
|
|
1877
|
+
col.ellipsis && "max-w-60 truncate",
|
|
1878
|
+
col.wrap && "whitespace-normal",
|
|
1879
|
+
col.align === "center" && "text-center",
|
|
1880
|
+
col.align === "right" && "text-right",
|
|
1881
|
+
col.type === "dot" && "w-9",
|
|
1882
|
+
props.classNames?.bodyCell
|
|
1734
1883
|
),
|
|
1735
|
-
children:
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1884
|
+
children: centeredContent || rightAlignedContent ? /* @__PURE__ */ jsx(
|
|
1885
|
+
"div",
|
|
1886
|
+
{
|
|
1887
|
+
className: twMerge(
|
|
1888
|
+
"flex w-full items-center",
|
|
1889
|
+
centeredContent ? "justify-center" : "justify-end"
|
|
1890
|
+
),
|
|
1891
|
+
children: content
|
|
1892
|
+
}
|
|
1893
|
+
) : content
|
|
1894
|
+
},
|
|
1895
|
+
colIdx
|
|
1896
|
+
);
|
|
1897
|
+
})
|
|
1898
|
+
]
|
|
1899
|
+
},
|
|
1900
|
+
key
|
|
1901
|
+
);
|
|
1902
|
+
}) })
|
|
1903
|
+
] }) }),
|
|
1904
|
+
/* @__PURE__ */ jsx(
|
|
1905
|
+
Pagination,
|
|
1906
|
+
{
|
|
1907
|
+
current: grid.pageNumber,
|
|
1908
|
+
pageSize: grid.pageSize,
|
|
1909
|
+
total: props.totalCount,
|
|
1910
|
+
showPageNumberChanger: props.showPageNumberChanger ?? false,
|
|
1911
|
+
showPageSizeChanger: props.showPageSizeChanger ?? false,
|
|
1912
|
+
onChange: (page, pageSize) => grid.onChange({ pageNumber: page, pageSize }),
|
|
1913
|
+
classNames: props.classNames?.pagination
|
|
1914
|
+
}
|
|
1915
|
+
)
|
|
1916
|
+
]
|
|
1917
|
+
}
|
|
1918
|
+
);
|
|
1761
1919
|
};
|
|
1762
1920
|
function isValueSet(v) {
|
|
1763
1921
|
if (Array.isArray(v)) return v.length > 0;
|
|
@@ -2888,7 +3046,7 @@ var Drawer = ({ placement = "top", ...props }) => {
|
|
|
2888
3046
|
if (isTargetInsideFloatingRoot(e.target)) {
|
|
2889
3047
|
return;
|
|
2890
3048
|
}
|
|
2891
|
-
if (!
|
|
3049
|
+
if (!isTopmostLayerRoot(panelRef.current)) {
|
|
2892
3050
|
return;
|
|
2893
3051
|
}
|
|
2894
3052
|
props.onClose(false);
|
|
@@ -2929,7 +3087,7 @@ var Drawer = ({ placement = "top", ...props }) => {
|
|
|
2929
3087
|
"div",
|
|
2930
3088
|
{
|
|
2931
3089
|
ref: panelRef,
|
|
2932
|
-
"data-ui-
|
|
3090
|
+
"data-ui-layer-root": "",
|
|
2933
3091
|
className: twMerge(
|
|
2934
3092
|
panelBase[placement],
|
|
2935
3093
|
"bg-white shadow-xl transition-transform duration-220 ease-out",
|
|
@@ -3041,6 +3199,256 @@ var DrawerContent = ({ loading = false, children }) => {
|
|
|
3041
3199
|
}
|
|
3042
3200
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
3043
3201
|
};
|
|
3202
|
+
var ModalContext = createContext(null);
|
|
3203
|
+
function useModal() {
|
|
3204
|
+
const ctx = useContext(ModalContext);
|
|
3205
|
+
if (!ctx) {
|
|
3206
|
+
throw new Error("useModal must be used inside Modal");
|
|
3207
|
+
}
|
|
3208
|
+
return ctx;
|
|
3209
|
+
}
|
|
3210
|
+
var TRANSITION_MS2 = 220;
|
|
3211
|
+
var sizeClass = {
|
|
3212
|
+
small: "w-full max-w-lg",
|
|
3213
|
+
middle: "w-full max-w-3xl",
|
|
3214
|
+
large: "w-full max-w-5xl",
|
|
3215
|
+
auto: "w-auto"
|
|
3216
|
+
};
|
|
3217
|
+
var Modal = ({
|
|
3218
|
+
placement = "center",
|
|
3219
|
+
size = "middle",
|
|
3220
|
+
width,
|
|
3221
|
+
maxWidth,
|
|
3222
|
+
closeOnEscape = true,
|
|
3223
|
+
closeOnOverlayClick = true,
|
|
3224
|
+
showCloseButton = true,
|
|
3225
|
+
hideHeader = false,
|
|
3226
|
+
destroyOnClose = true,
|
|
3227
|
+
preventClose = false,
|
|
3228
|
+
beforeClose,
|
|
3229
|
+
initialFocusRef,
|
|
3230
|
+
...props
|
|
3231
|
+
}) => {
|
|
3232
|
+
const [rendered, setRendered] = useState(props.isOpen);
|
|
3233
|
+
const [visible, setVisible] = useState(false);
|
|
3234
|
+
const [title, setTitle] = useState("");
|
|
3235
|
+
const [footer, setFooter] = useState(null);
|
|
3236
|
+
const [loading, setLoading] = useState(false);
|
|
3237
|
+
const frameRef = useRef(0);
|
|
3238
|
+
const panelRef = useRef(null);
|
|
3239
|
+
useEffect(() => {
|
|
3240
|
+
if (props.isOpen) {
|
|
3241
|
+
setRendered(true);
|
|
3242
|
+
frameRef.current = requestAnimationFrame(() => {
|
|
3243
|
+
frameRef.current = requestAnimationFrame(() => setVisible(true));
|
|
3244
|
+
});
|
|
3245
|
+
} else {
|
|
3246
|
+
setVisible(false);
|
|
3247
|
+
if (!destroyOnClose) {
|
|
3248
|
+
return () => cancelAnimationFrame(frameRef.current);
|
|
3249
|
+
}
|
|
3250
|
+
const t = setTimeout(() => setRendered(false), TRANSITION_MS2);
|
|
3251
|
+
return () => clearTimeout(t);
|
|
3252
|
+
}
|
|
3253
|
+
return () => cancelAnimationFrame(frameRef.current);
|
|
3254
|
+
}, [destroyOnClose, props.isOpen]);
|
|
3255
|
+
useEffect(() => {
|
|
3256
|
+
if (!props.isOpen) {
|
|
3257
|
+
return;
|
|
3258
|
+
}
|
|
3259
|
+
const focusTarget = initialFocusRef?.current;
|
|
3260
|
+
if (!focusTarget) {
|
|
3261
|
+
return;
|
|
3262
|
+
}
|
|
3263
|
+
const timeout = window.setTimeout(() => focusTarget.focus(), TRANSITION_MS2 / 2);
|
|
3264
|
+
return () => window.clearTimeout(timeout);
|
|
3265
|
+
}, [initialFocusRef, props.isOpen]);
|
|
3266
|
+
useEffect(() => {
|
|
3267
|
+
if (!props.isOpen) {
|
|
3268
|
+
return;
|
|
3269
|
+
}
|
|
3270
|
+
const handleKeyDown = (e) => {
|
|
3271
|
+
if (!closeOnEscape || e.key !== "Escape" || e.defaultPrevented) {
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
if (hasFloatingRootOpen() || isTargetInsideFloatingRoot(e.target)) {
|
|
3275
|
+
return;
|
|
3276
|
+
}
|
|
3277
|
+
if (!isTopmostLayerRoot(panelRef.current)) {
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3280
|
+
void requestClose();
|
|
3281
|
+
};
|
|
3282
|
+
document.body.style.overflow = "hidden";
|
|
3283
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
3284
|
+
return () => {
|
|
3285
|
+
document.body.style.overflow = "";
|
|
3286
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
3287
|
+
};
|
|
3288
|
+
}, [closeOnEscape, props.isOpen]);
|
|
3289
|
+
if (!rendered) {
|
|
3290
|
+
return null;
|
|
3291
|
+
}
|
|
3292
|
+
const requestClose = async () => {
|
|
3293
|
+
if (preventClose) {
|
|
3294
|
+
return;
|
|
3295
|
+
}
|
|
3296
|
+
const canClose = await beforeClose?.();
|
|
3297
|
+
if (canClose === false) {
|
|
3298
|
+
return;
|
|
3299
|
+
}
|
|
3300
|
+
props.onClose(false);
|
|
3301
|
+
};
|
|
3302
|
+
const close = () => {
|
|
3303
|
+
void requestClose();
|
|
3304
|
+
};
|
|
3305
|
+
const saveAndClose = (message) => {
|
|
3306
|
+
if (message) {
|
|
3307
|
+
notification.success(message);
|
|
3308
|
+
}
|
|
3309
|
+
props.onClose(true);
|
|
3310
|
+
};
|
|
3311
|
+
const hasFooter = footer !== null;
|
|
3312
|
+
const isFullscreen = placement === "fullscreen";
|
|
3313
|
+
return createPortal(
|
|
3314
|
+
/* @__PURE__ */ jsxs(ModalContext.Provider, { value: { close, saveAndClose, setTitle, setFooter, setLoading }, children: [
|
|
3315
|
+
/* @__PURE__ */ jsx(
|
|
3316
|
+
"div",
|
|
3317
|
+
{
|
|
3318
|
+
className: twMerge(
|
|
3319
|
+
"fixed inset-0 z-1000 bg-black/40 transition-opacity duration-220",
|
|
3320
|
+
visible ? "opacity-100" : "opacity-0",
|
|
3321
|
+
!props.isOpen && "pointer-events-none",
|
|
3322
|
+
props.classNames?.overlay
|
|
3323
|
+
),
|
|
3324
|
+
onClick: () => closeOnOverlayClick && close()
|
|
3325
|
+
}
|
|
3326
|
+
),
|
|
3327
|
+
/* @__PURE__ */ jsx(
|
|
3328
|
+
"div",
|
|
3329
|
+
{
|
|
3330
|
+
className: twMerge(
|
|
3331
|
+
"fixed inset-0 z-1001 flex p-4 transition-all duration-220",
|
|
3332
|
+
isFullscreen ? "items-stretch justify-stretch p-0" : "items-center justify-center",
|
|
3333
|
+
!props.isOpen && "pointer-events-none"
|
|
3334
|
+
),
|
|
3335
|
+
children: /* @__PURE__ */ jsxs(
|
|
3336
|
+
"div",
|
|
3337
|
+
{
|
|
3338
|
+
ref: panelRef,
|
|
3339
|
+
"data-ui-layer-root": "",
|
|
3340
|
+
role: "dialog",
|
|
3341
|
+
"aria-modal": "true",
|
|
3342
|
+
"aria-hidden": !props.isOpen,
|
|
3343
|
+
style: !isFullscreen ? { width, maxWidth } : void 0,
|
|
3344
|
+
className: twMerge(
|
|
3345
|
+
"bg-white shadow-xl flex flex-col transition-all duration-220 ease-out",
|
|
3346
|
+
isFullscreen ? "h-full w-full rounded-none" : `${sizeClass[size]} max-h-[calc(100dvh-32px)] rounded-(--ui-radius-lg)`,
|
|
3347
|
+
visible ? "scale-100 opacity-100" : "scale-95 opacity-0",
|
|
3348
|
+
props.className,
|
|
3349
|
+
props.classNames?.panel
|
|
3350
|
+
),
|
|
3351
|
+
onClick: (e) => e.stopPropagation(),
|
|
3352
|
+
children: [
|
|
3353
|
+
!hideHeader && /* @__PURE__ */ jsxs(
|
|
3354
|
+
"div",
|
|
3355
|
+
{
|
|
3356
|
+
className: twMerge(
|
|
3357
|
+
"flex items-center justify-between gap-2 bg-(--ui-primary) shrink-0 rounded-t-(--ui-radius-lg)",
|
|
3358
|
+
isFullscreen && "rounded-none",
|
|
3359
|
+
drawerLayoutClasses.header,
|
|
3360
|
+
props.classNames?.header
|
|
3361
|
+
),
|
|
3362
|
+
children: [
|
|
3363
|
+
/* @__PURE__ */ jsx("span", { className: twMerge(componentTitleClasses.inverse, "truncate", props.classNames?.title), children: title }),
|
|
3364
|
+
showCloseButton && /* @__PURE__ */ jsx(
|
|
3365
|
+
"button",
|
|
3366
|
+
{
|
|
3367
|
+
type: "button",
|
|
3368
|
+
onClick: close,
|
|
3369
|
+
className: twMerge(
|
|
3370
|
+
"shrink-0 text-(--ui-primary-text)/70 hover:text-(--ui-primary-text) cursor-pointer transition-colors",
|
|
3371
|
+
props.classNames?.closeButton
|
|
3372
|
+
),
|
|
3373
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 18, strokeWidth: 1.5 })
|
|
3374
|
+
}
|
|
3375
|
+
)
|
|
3376
|
+
]
|
|
3377
|
+
}
|
|
3378
|
+
),
|
|
3379
|
+
/* @__PURE__ */ jsx(
|
|
3380
|
+
"div",
|
|
3381
|
+
{
|
|
3382
|
+
className: twMerge(
|
|
3383
|
+
"overflow-y-auto flex-1",
|
|
3384
|
+
isFullscreen ? "min-h-0" : "max-h-[calc(100dvh-120px)]",
|
|
3385
|
+
drawerLayoutClasses.body,
|
|
3386
|
+
props.classNames?.body
|
|
3387
|
+
),
|
|
3388
|
+
children: loading ? /* @__PURE__ */ jsx("div", { className: twMerge("flex items-center justify-center py-16", props.classNames?.loading), children: /* @__PURE__ */ jsx(Spinner, { size: "large", color: "primary" }) }) : props.children
|
|
3389
|
+
}
|
|
3390
|
+
),
|
|
3391
|
+
hasFooter && /* @__PURE__ */ jsx(
|
|
3392
|
+
"div",
|
|
3393
|
+
{
|
|
3394
|
+
className: twMerge(
|
|
3395
|
+
"border-t border-(--ui-border) shrink-0 bg-white",
|
|
3396
|
+
isFullscreen ? "rounded-none" : "rounded-b-(--ui-radius-lg)",
|
|
3397
|
+
drawerLayoutClasses.footer,
|
|
3398
|
+
props.classNames?.footer
|
|
3399
|
+
),
|
|
3400
|
+
children: footer
|
|
3401
|
+
}
|
|
3402
|
+
)
|
|
3403
|
+
]
|
|
3404
|
+
}
|
|
3405
|
+
)
|
|
3406
|
+
}
|
|
3407
|
+
)
|
|
3408
|
+
] }),
|
|
3409
|
+
document.body
|
|
3410
|
+
);
|
|
3411
|
+
};
|
|
3412
|
+
var ModalTitle = ({ children }) => {
|
|
3413
|
+
const { setTitle } = useModal();
|
|
3414
|
+
useEffect(() => {
|
|
3415
|
+
setTitle(String(children));
|
|
3416
|
+
return () => setTitle("");
|
|
3417
|
+
}, [children]);
|
|
3418
|
+
return null;
|
|
3419
|
+
};
|
|
3420
|
+
var alignClass2 = {
|
|
3421
|
+
left: "justify-start",
|
|
3422
|
+
center: "justify-center",
|
|
3423
|
+
right: "justify-end"
|
|
3424
|
+
};
|
|
3425
|
+
var ModalFooter = ({ children, align = "right" }) => {
|
|
3426
|
+
const { setFooter } = useModal();
|
|
3427
|
+
useEffect(() => {
|
|
3428
|
+
setFooter(
|
|
3429
|
+
/* @__PURE__ */ jsx("div", { className: twMerge("flex items-center gap-2", alignClass2[align]), children })
|
|
3430
|
+
);
|
|
3431
|
+
return () => setFooter(null);
|
|
3432
|
+
}, [align, children]);
|
|
3433
|
+
return null;
|
|
3434
|
+
};
|
|
3435
|
+
var ModalSkeleton = () => /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-3", children: [
|
|
3436
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3" }),
|
|
3437
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" }),
|
|
3438
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3 mt-5" }),
|
|
3439
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" }),
|
|
3440
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3 mt-5" }),
|
|
3441
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" })
|
|
3442
|
+
] });
|
|
3443
|
+
var ModalContent = ({ loading = false, children }) => {
|
|
3444
|
+
if (loading) {
|
|
3445
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
3446
|
+
/* @__PURE__ */ jsx(ModalSkeleton, {}),
|
|
3447
|
+
/* @__PURE__ */ jsx(Skeleton, { active: true, title: false, paragraph: { rows: 2 } })
|
|
3448
|
+
] });
|
|
3449
|
+
}
|
|
3450
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
3451
|
+
};
|
|
3044
3452
|
var Alert = ({ type = "info", message, description, closable = false, className, classNames }) => {
|
|
3045
3453
|
const [closed, setClosed] = useState(false);
|
|
3046
3454
|
if (closed) {
|
|
@@ -3132,31 +3540,214 @@ var Panel = ({
|
|
|
3132
3540
|
}
|
|
3133
3541
|
);
|
|
3134
3542
|
};
|
|
3543
|
+
var Toolbar = ({ children, start, end, wrapped = true, inset = false, className, classNames }) => /* @__PURE__ */ jsxs(
|
|
3544
|
+
"div",
|
|
3545
|
+
{
|
|
3546
|
+
className: twMerge(
|
|
3547
|
+
"flex items-center justify-between gap-3 rounded-(--ui-radius-lg) border border-(--ui-border)",
|
|
3548
|
+
neutralSurfaceClasses.subtle,
|
|
3549
|
+
wrapped && "flex-wrap",
|
|
3550
|
+
inset ? "px-3 py-2" : "px-4 py-3",
|
|
3551
|
+
className
|
|
3552
|
+
),
|
|
3553
|
+
children: [
|
|
3554
|
+
/* @__PURE__ */ jsx("div", { className: twMerge("flex min-w-0 flex-1 items-center gap-2", wrapped && "flex-wrap", classNames?.start), children: start ?? children }),
|
|
3555
|
+
end && /* @__PURE__ */ jsx("div", { className: twMerge("flex items-center gap-2", wrapped && "flex-wrap justify-end", classNames?.end), children: end })
|
|
3556
|
+
]
|
|
3557
|
+
}
|
|
3558
|
+
);
|
|
3559
|
+
var ActionBar = Toolbar;
|
|
3560
|
+
var SectionHeader = ({ title, subtitle, actions, className }) => /* @__PURE__ */ jsxs("div", { className: twMerge("flex items-start justify-between gap-4", className), children: [
|
|
3561
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3562
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-(--ui-text-strong)", children: title }),
|
|
3563
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle })
|
|
3564
|
+
] }),
|
|
3565
|
+
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
3566
|
+
] });
|
|
3567
|
+
var PageHeader = ({ title, subtitle, breadcrumbs, actions, extra, className }) => /* @__PURE__ */ jsxs("div", { className: twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-5", className), children: [
|
|
3568
|
+
breadcrumbs && /* @__PURE__ */ jsx("div", { className: twMerge("mb-2 text-xs", neutralTextClasses.soft), children: breadcrumbs }),
|
|
3569
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
3570
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3571
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-(--ui-text-strong)", children: title }),
|
|
3572
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle })
|
|
3573
|
+
] }),
|
|
3574
|
+
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
3575
|
+
] }),
|
|
3576
|
+
extra && /* @__PURE__ */ jsx("div", { className: "mt-4 border-t border-(--ui-border) pt-4", children: extra })
|
|
3577
|
+
] });
|
|
3578
|
+
var AVATAR_COLORS = [
|
|
3579
|
+
"bg-blue-500",
|
|
3580
|
+
"bg-green-500",
|
|
3581
|
+
"bg-purple-500",
|
|
3582
|
+
"bg-orange-500",
|
|
3583
|
+
"bg-pink-500",
|
|
3584
|
+
"bg-teal-500",
|
|
3585
|
+
"bg-red-500",
|
|
3586
|
+
"bg-indigo-500"
|
|
3587
|
+
];
|
|
3588
|
+
function colorFromString(str) {
|
|
3589
|
+
let hash = 0;
|
|
3590
|
+
for (let i = 0; i < str.length; i++) {
|
|
3591
|
+
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
3592
|
+
}
|
|
3593
|
+
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
3594
|
+
}
|
|
3595
|
+
function getInitials(name) {
|
|
3596
|
+
const parts = name.trim().split(/\s+/);
|
|
3597
|
+
if (parts.length === 1) {
|
|
3598
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
3599
|
+
}
|
|
3600
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
3601
|
+
}
|
|
3602
|
+
var sizeClasses = {
|
|
3603
|
+
xs: "w-6 h-6 text-[10px]",
|
|
3604
|
+
sm: "w-7 h-7 text-xs",
|
|
3605
|
+
md: "w-8 h-8 text-sm",
|
|
3606
|
+
lg: "w-10 h-10 text-base",
|
|
3607
|
+
xl: "w-12 h-12 text-lg"
|
|
3608
|
+
};
|
|
3609
|
+
var Avatar = ({ size = "md", ...props }) => {
|
|
3610
|
+
const initials = props.name ? getInitials(props.name) : "?";
|
|
3611
|
+
const bgColor = props.color ?? (props.name ? colorFromString(props.name) : "bg-gray-400");
|
|
3612
|
+
if (props.src) {
|
|
3613
|
+
return /* @__PURE__ */ jsx(
|
|
3614
|
+
"img",
|
|
3615
|
+
{
|
|
3616
|
+
src: props.src,
|
|
3617
|
+
alt: props.name ?? "avatar",
|
|
3618
|
+
className: twMerge(
|
|
3619
|
+
"rounded-full object-cover shrink-0",
|
|
3620
|
+
sizeClasses[size],
|
|
3621
|
+
props.className
|
|
3622
|
+
)
|
|
3623
|
+
}
|
|
3624
|
+
);
|
|
3625
|
+
}
|
|
3626
|
+
return /* @__PURE__ */ jsx(
|
|
3627
|
+
"span",
|
|
3628
|
+
{
|
|
3629
|
+
title: props.name,
|
|
3630
|
+
className: twMerge(
|
|
3631
|
+
"inline-flex items-center justify-center rounded-full text-white font-medium shrink-0 select-none",
|
|
3632
|
+
sizeClasses[size],
|
|
3633
|
+
bgColor,
|
|
3634
|
+
props.className
|
|
3635
|
+
),
|
|
3636
|
+
children: /* @__PURE__ */ jsx("span", { className: props.initialsClassName, children: initials })
|
|
3637
|
+
}
|
|
3638
|
+
);
|
|
3639
|
+
};
|
|
3640
|
+
var EntityHeader = ({ title, subtitle, avatarName, icon: Icon, meta, tags, actions, className }) => /* @__PURE__ */ jsx("div", { className: twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-5", className), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
3641
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [
|
|
3642
|
+
avatarName ? /* @__PURE__ */ jsx(Avatar, { name: avatarName, size: "lg" }) : Icon ? /* @__PURE__ */ jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-(--ui-radius-lg) bg-(--ui-surface-subtle)", children: /* @__PURE__ */ jsx(Icon, { size: 20, strokeWidth: 1.8, className: "text-(--ui-text)" }) }) : null,
|
|
3643
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3644
|
+
/* @__PURE__ */ jsx("div", { className: "text-xl font-semibold text-(--ui-text-strong)", children: title }),
|
|
3645
|
+
subtitle && /* @__PURE__ */ jsx("div", { className: twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle }),
|
|
3646
|
+
(meta || tags) && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
|
|
3647
|
+
meta,
|
|
3648
|
+
tags
|
|
3649
|
+
] })
|
|
3650
|
+
] })
|
|
3651
|
+
] }),
|
|
3652
|
+
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
3653
|
+
] }) });
|
|
3654
|
+
var alignClass3 = {
|
|
3655
|
+
left: "justify-start",
|
|
3656
|
+
center: "justify-center",
|
|
3657
|
+
right: "justify-end",
|
|
3658
|
+
between: "justify-between"
|
|
3659
|
+
};
|
|
3660
|
+
var FormActions = ({ children, align = "right", className }) => /* @__PURE__ */ jsx("div", { className: twMerge("flex flex-wrap items-center gap-2 border-t border-(--ui-border) pt-4", alignClass3[align], className), children });
|
|
3661
|
+
var FormSection = ({ title, description, actions, children, className }) => /* @__PURE__ */ jsxs("fieldset", { className: twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4", className), children: [
|
|
3662
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 flex items-start justify-between gap-4", children: [
|
|
3663
|
+
/* @__PURE__ */ jsxs("legend", { className: "min-w-0", children: [
|
|
3664
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-(--ui-text-strong)", children: title }),
|
|
3665
|
+
description && /* @__PURE__ */ jsx("div", { className: twMerge("mt-1 text-xs", neutralTextClasses.soft), children: description })
|
|
3666
|
+
] }),
|
|
3667
|
+
actions && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: actions })
|
|
3668
|
+
] }),
|
|
3669
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-4", children })
|
|
3670
|
+
] });
|
|
3671
|
+
var Fieldset = FormSection;
|
|
3672
|
+
var listVariantClass = {
|
|
3673
|
+
segmented: "inline-flex gap-0 rounded-(--ui-radius-lg) p-1",
|
|
3674
|
+
underline: "inline-flex gap-1 border-b border-(--ui-border-strong)",
|
|
3675
|
+
cards: "inline-flex gap-2"
|
|
3676
|
+
};
|
|
3677
|
+
var listSurfaceClass = {
|
|
3678
|
+
segmented: neutralSurfaceClasses.subtle,
|
|
3679
|
+
underline: "",
|
|
3680
|
+
cards: ""
|
|
3681
|
+
};
|
|
3682
|
+
var tabSizeClass = {
|
|
3683
|
+
small: "h-8 px-3 text-[12px]",
|
|
3684
|
+
middle: "h-9 px-4 text-[14px]",
|
|
3685
|
+
large: "h-10 px-5 text-[15px]"
|
|
3686
|
+
};
|
|
3687
|
+
var tabVariantClass = {
|
|
3688
|
+
segmented: "rounded-[calc(var(--ui-radius-lg)-4px)]",
|
|
3689
|
+
underline: "border-b-2 border-transparent rounded-none -mb-px",
|
|
3690
|
+
cards: "rounded-(--ui-radius-lg) border border-(--ui-border) bg-white shadow-sm"
|
|
3691
|
+
};
|
|
3692
|
+
var activeVariantClass = {
|
|
3693
|
+
segmented: "bg-white text-(--ui-text-strong) shadow-sm font-semibold",
|
|
3694
|
+
underline: "border-(--ui-primary) text-(--ui-text-strong) font-semibold",
|
|
3695
|
+
cards: "border-(--ui-border-focus) bg-(--ui-surface-subtle) text-(--ui-text-strong) font-semibold shadow-none"
|
|
3696
|
+
};
|
|
3697
|
+
var inactiveVariantClass = {
|
|
3698
|
+
segmented: "text-(--ui-text-muted) hover:text-(--ui-text)",
|
|
3699
|
+
underline: "text-(--ui-text-muted) hover:text-(--ui-text)",
|
|
3700
|
+
cards: "text-(--ui-text-muted) hover:border-(--ui-border-focus) hover:text-(--ui-text)"
|
|
3701
|
+
};
|
|
3135
3702
|
var Tabs = ({
|
|
3136
3703
|
block = true,
|
|
3704
|
+
variant = "segmented",
|
|
3705
|
+
size = "middle",
|
|
3137
3706
|
...props
|
|
3138
3707
|
}) => /* @__PURE__ */ jsx(
|
|
3139
3708
|
"div",
|
|
3140
3709
|
{
|
|
3710
|
+
role: "tablist",
|
|
3141
3711
|
className: twMerge(
|
|
3142
|
-
|
|
3143
|
-
|
|
3712
|
+
listVariantClass[variant],
|
|
3713
|
+
listSurfaceClass[variant],
|
|
3144
3714
|
block && "flex w-full",
|
|
3145
3715
|
props.className,
|
|
3146
3716
|
props.classNames?.list
|
|
3147
3717
|
),
|
|
3148
|
-
children: props.options.map((opt) => /* @__PURE__ */
|
|
3718
|
+
children: props.options.map((opt) => /* @__PURE__ */ jsxs(
|
|
3149
3719
|
"button",
|
|
3150
3720
|
{
|
|
3151
3721
|
type: "button",
|
|
3152
|
-
|
|
3722
|
+
role: "tab",
|
|
3723
|
+
"aria-selected": props.value === opt.value,
|
|
3724
|
+
disabled: opt.disabled,
|
|
3725
|
+
onClick: () => !opt.disabled && props.onChange(opt.value),
|
|
3153
3726
|
className: twMerge(
|
|
3154
|
-
"flex-1
|
|
3155
|
-
|
|
3727
|
+
"flex-1 min-w-0 transition-all duration-150 cursor-pointer select-none whitespace-nowrap",
|
|
3728
|
+
"inline-flex items-center justify-center gap-2",
|
|
3729
|
+
tabSizeClass[size],
|
|
3730
|
+
tabVariantClass[variant],
|
|
3731
|
+
props.value === opt.value ? activeVariantClass[variant] : inactiveVariantClass[variant],
|
|
3732
|
+
opt.disabled && "cursor-not-allowed opacity-45 hover:border-(--ui-border) hover:text-(--ui-text-muted)",
|
|
3156
3733
|
props.classNames?.tab,
|
|
3157
3734
|
props.value === opt.value ? props.classNames?.activeTab : props.classNames?.inactiveTab
|
|
3158
3735
|
),
|
|
3159
|
-
children:
|
|
3736
|
+
children: [
|
|
3737
|
+
opt.icon && /* @__PURE__ */ jsx("span", { className: twMerge("shrink-0", props.classNames?.icon), children: opt.icon }),
|
|
3738
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: opt.label }),
|
|
3739
|
+
opt.badge && /* @__PURE__ */ jsx(
|
|
3740
|
+
"span",
|
|
3741
|
+
{
|
|
3742
|
+
className: twMerge(
|
|
3743
|
+
"shrink-0 rounded-full px-2 py-0.5 text-[11px] leading-none",
|
|
3744
|
+
props.value === opt.value ? "bg-(--ui-primary) text-(--ui-primary-text)" : "bg-(--ui-surface-muted) text-(--ui-text-muted)",
|
|
3745
|
+
props.classNames?.badge
|
|
3746
|
+
),
|
|
3747
|
+
children: opt.badge
|
|
3748
|
+
}
|
|
3749
|
+
)
|
|
3750
|
+
]
|
|
3160
3751
|
},
|
|
3161
3752
|
opt.value
|
|
3162
3753
|
))
|
|
@@ -3238,68 +3829,6 @@ var FlagTag = ({ value, label, color = "geekblue", variant }) => {
|
|
|
3238
3829
|
}
|
|
3239
3830
|
return /* @__PURE__ */ jsx(Tag, { color, variant, children: label });
|
|
3240
3831
|
};
|
|
3241
|
-
var AVATAR_COLORS = [
|
|
3242
|
-
"bg-blue-500",
|
|
3243
|
-
"bg-green-500",
|
|
3244
|
-
"bg-purple-500",
|
|
3245
|
-
"bg-orange-500",
|
|
3246
|
-
"bg-pink-500",
|
|
3247
|
-
"bg-teal-500",
|
|
3248
|
-
"bg-red-500",
|
|
3249
|
-
"bg-indigo-500"
|
|
3250
|
-
];
|
|
3251
|
-
function colorFromString(str) {
|
|
3252
|
-
let hash = 0;
|
|
3253
|
-
for (let i = 0; i < str.length; i++) {
|
|
3254
|
-
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
3255
|
-
}
|
|
3256
|
-
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
3257
|
-
}
|
|
3258
|
-
function getInitials(name) {
|
|
3259
|
-
const parts = name.trim().split(/\s+/);
|
|
3260
|
-
if (parts.length === 1) {
|
|
3261
|
-
return parts[0].slice(0, 2).toUpperCase();
|
|
3262
|
-
}
|
|
3263
|
-
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
3264
|
-
}
|
|
3265
|
-
var sizeClasses = {
|
|
3266
|
-
xs: "w-6 h-6 text-[10px]",
|
|
3267
|
-
sm: "w-7 h-7 text-xs",
|
|
3268
|
-
md: "w-8 h-8 text-sm",
|
|
3269
|
-
lg: "w-10 h-10 text-base",
|
|
3270
|
-
xl: "w-12 h-12 text-lg"
|
|
3271
|
-
};
|
|
3272
|
-
var Avatar = ({ size = "md", ...props }) => {
|
|
3273
|
-
const initials = props.name ? getInitials(props.name) : "?";
|
|
3274
|
-
const bgColor = props.color ?? (props.name ? colorFromString(props.name) : "bg-gray-400");
|
|
3275
|
-
if (props.src) {
|
|
3276
|
-
return /* @__PURE__ */ jsx(
|
|
3277
|
-
"img",
|
|
3278
|
-
{
|
|
3279
|
-
src: props.src,
|
|
3280
|
-
alt: props.name ?? "avatar",
|
|
3281
|
-
className: twMerge(
|
|
3282
|
-
"rounded-full object-cover shrink-0",
|
|
3283
|
-
sizeClasses[size],
|
|
3284
|
-
props.className
|
|
3285
|
-
)
|
|
3286
|
-
}
|
|
3287
|
-
);
|
|
3288
|
-
}
|
|
3289
|
-
return /* @__PURE__ */ jsx(
|
|
3290
|
-
"span",
|
|
3291
|
-
{
|
|
3292
|
-
title: props.name,
|
|
3293
|
-
className: twMerge(
|
|
3294
|
-
"inline-flex items-center justify-center rounded-full text-white font-medium shrink-0 select-none",
|
|
3295
|
-
sizeClasses[size],
|
|
3296
|
-
bgColor,
|
|
3297
|
-
props.className
|
|
3298
|
-
),
|
|
3299
|
-
children: /* @__PURE__ */ jsx("span", { className: props.initialsClassName, children: initials })
|
|
3300
|
-
}
|
|
3301
|
-
);
|
|
3302
|
-
};
|
|
3303
3832
|
var defaultToolbar = [
|
|
3304
3833
|
"bold",
|
|
3305
3834
|
"italic",
|
|
@@ -3973,6 +4502,88 @@ var useNotification = () => {
|
|
|
3973
4502
|
info: (message, options) => add("info", message, options)
|
|
3974
4503
|
};
|
|
3975
4504
|
};
|
|
4505
|
+
var EmptyState = ({
|
|
4506
|
+
primaryActionText,
|
|
4507
|
+
onPrimaryAction,
|
|
4508
|
+
secondaryActionText,
|
|
4509
|
+
onSecondaryAction,
|
|
4510
|
+
extra,
|
|
4511
|
+
className,
|
|
4512
|
+
classNames,
|
|
4513
|
+
...props
|
|
4514
|
+
}) => /* @__PURE__ */ jsxs("div", { className: twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white", className), children: [
|
|
4515
|
+
/* @__PURE__ */ jsx(Empty, { className: "py-10", ...props }),
|
|
4516
|
+
(primaryActionText || secondaryActionText || extra) && /* @__PURE__ */ jsxs("div", { className: twMerge("flex flex-wrap items-center justify-center gap-2 px-4 pb-6", classNames?.actions), children: [
|
|
4517
|
+
secondaryActionText && /* @__PURE__ */ jsx(Button, { variant: "default", text: secondaryActionText, onClick: onSecondaryAction }),
|
|
4518
|
+
primaryActionText && /* @__PURE__ */ jsx(Button, { text: primaryActionText, onClick: onPrimaryAction }),
|
|
4519
|
+
extra && /* @__PURE__ */ jsx("div", { className: classNames?.extra, children: extra })
|
|
4520
|
+
] })
|
|
4521
|
+
] });
|
|
4522
|
+
var trendConfig = {
|
|
4523
|
+
up: {
|
|
4524
|
+
icon: IconArrowUpRight,
|
|
4525
|
+
className: "text-(--ui-success)"
|
|
4526
|
+
},
|
|
4527
|
+
down: {
|
|
4528
|
+
icon: IconArrowDownRight,
|
|
4529
|
+
className: "text-(--ui-danger)"
|
|
4530
|
+
},
|
|
4531
|
+
neutral: {
|
|
4532
|
+
icon: IconMinus,
|
|
4533
|
+
className: neutralTextClasses.soft
|
|
4534
|
+
}
|
|
4535
|
+
};
|
|
4536
|
+
var StatCard = ({ label, value, description, icon: Icon, trend, footer, className }) => {
|
|
4537
|
+
const trendDirection = trend?.direction ?? "neutral";
|
|
4538
|
+
const TrendIcon = trend ? trendConfig[trendDirection].icon : null;
|
|
4539
|
+
return /* @__PURE__ */ jsxs("div", { className: twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4 shadow-sm", className), children: [
|
|
4540
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
4541
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
4542
|
+
/* @__PURE__ */ jsx("p", { className: twMerge("text-sm", neutralTextClasses.muted), children: label }),
|
|
4543
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold text-(--ui-text-strong)", children: value }),
|
|
4544
|
+
description && /* @__PURE__ */ jsx("p", { className: twMerge("mt-1 text-xs", neutralTextClasses.soft), children: description })
|
|
4545
|
+
] }),
|
|
4546
|
+
Icon && /* @__PURE__ */ jsx("div", { className: twMerge("flex h-10 w-10 items-center justify-center rounded-(--ui-radius-lg)", neutralSurfaceClasses.subtle), children: /* @__PURE__ */ jsx(Icon, { size: 18, strokeWidth: 1.75, className: neutralTextClasses.default }) })
|
|
4547
|
+
] }),
|
|
4548
|
+
trend && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center gap-2 text-sm", children: [
|
|
4549
|
+
TrendIcon && /* @__PURE__ */ jsx(TrendIcon, { size: 15, strokeWidth: 2, className: trendConfig[trendDirection].className }),
|
|
4550
|
+
/* @__PURE__ */ jsx("span", { className: twMerge("font-medium", trendConfig[trendDirection].className), children: trend.value }),
|
|
4551
|
+
trend.label && /* @__PURE__ */ jsx("span", { className: neutralTextClasses.soft, children: trend.label })
|
|
4552
|
+
] }),
|
|
4553
|
+
footer && /* @__PURE__ */ jsx("div", { className: "mt-4 border-t border-(--ui-border) pt-3", children: footer })
|
|
4554
|
+
] });
|
|
4555
|
+
};
|
|
4556
|
+
var DescriptionList = ({ items, columns = 2, className }) => /* @__PURE__ */ jsx(
|
|
4557
|
+
"div",
|
|
4558
|
+
{
|
|
4559
|
+
className: twMerge(
|
|
4560
|
+
"grid gap-x-6 gap-y-4 rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4",
|
|
4561
|
+
columns === 1 && "grid-cols-1",
|
|
4562
|
+
columns === 2 && "grid-cols-1 md:grid-cols-2",
|
|
4563
|
+
columns === 3 && "grid-cols-1 md:grid-cols-3",
|
|
4564
|
+
className
|
|
4565
|
+
),
|
|
4566
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
4567
|
+
"div",
|
|
4568
|
+
{
|
|
4569
|
+
className: twMerge(
|
|
4570
|
+
"min-w-0",
|
|
4571
|
+
item.span === 2 && columns > 1 && "md:col-span-2",
|
|
4572
|
+
item.span === 3 && columns > 2 && "md:col-span-3"
|
|
4573
|
+
),
|
|
4574
|
+
children: [
|
|
4575
|
+
/* @__PURE__ */ jsx("dt", { className: twMerge("text-xs font-medium uppercase tracking-[0.08em]", neutralTextClasses.soft), children: item.label }),
|
|
4576
|
+
/* @__PURE__ */ jsx("dd", { className: "mt-1 text-sm text-(--ui-text)", children: item.value })
|
|
4577
|
+
]
|
|
4578
|
+
},
|
|
4579
|
+
index
|
|
4580
|
+
))
|
|
4581
|
+
}
|
|
4582
|
+
);
|
|
4583
|
+
var KeyValue = ({ label, value, className }) => /* @__PURE__ */ jsxs("div", { className: twMerge("flex items-start justify-between gap-4 border-b border-(--ui-border) py-2 last:border-b-0", className), children: [
|
|
4584
|
+
/* @__PURE__ */ jsx("span", { className: twMerge("text-sm", neutralTextClasses.muted), children: label }),
|
|
4585
|
+
/* @__PURE__ */ jsx("span", { className: "text-right text-sm text-(--ui-text)", children: value })
|
|
4586
|
+
] });
|
|
3976
4587
|
var Pretty = ({ data, className }) => /* @__PURE__ */ jsx(
|
|
3977
4588
|
"pre",
|
|
3978
4589
|
{
|
|
@@ -3983,6 +4594,10 @@ var Pretty = ({ data, className }) => /* @__PURE__ */ jsx(
|
|
|
3983
4594
|
children: JSON.stringify(data, null, 2)
|
|
3984
4595
|
}
|
|
3985
4596
|
);
|
|
4597
|
+
var SkeletonTable = ({ rows = 5, columns = 4, className }) => /* @__PURE__ */ jsx("div", { className: twMerge("overflow-hidden rounded-(--ui-radius-lg) border border-(--ui-border) bg-white", className), children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
4598
|
+
/* @__PURE__ */ jsx("div", { className: "grid bg-(--ui-primary) px-4 py-3", style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }, children: Array.from({ length: columns }).map((_, index) => /* @__PURE__ */ jsx("div", { className: "h-3 w-20 rounded bg-white/30" }, index)) }),
|
|
4599
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-(--ui-border)", children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsx("div", { className: "grid gap-4 px-4 py-3", style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }, children: Array.from({ length: columns }).map((__, columnIndex) => /* @__PURE__ */ jsx("div", { className: "h-3 rounded bg-(--ui-surface-muted)" }, columnIndex)) }, rowIndex)) })
|
|
4600
|
+
] }) });
|
|
3986
4601
|
var GAP2 = 10;
|
|
3987
4602
|
var VIEWPORT_MARGIN2 = 8;
|
|
3988
4603
|
function calcPosition3(trigger, tooltip, placement) {
|
|
@@ -4137,6 +4752,47 @@ var Tooltip = ({
|
|
|
4137
4752
|
)
|
|
4138
4753
|
] });
|
|
4139
4754
|
};
|
|
4755
|
+
var Stepper = ({ items, className }) => /* @__PURE__ */ jsx("div", { className: twMerge("flex flex-wrap gap-4", className), children: items.map((item, index) => {
|
|
4756
|
+
const status = item.status ?? "upcoming";
|
|
4757
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-40 flex-1 items-start gap-3", children: [
|
|
4758
|
+
/* @__PURE__ */ jsx(
|
|
4759
|
+
"div",
|
|
4760
|
+
{
|
|
4761
|
+
className: twMerge(
|
|
4762
|
+
"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-xs font-semibold",
|
|
4763
|
+
status === "complete" && "border-(--ui-success) bg-(--ui-success) text-white",
|
|
4764
|
+
status === "current" && "border-(--ui-primary) bg-(--ui-primary) text-white",
|
|
4765
|
+
status === "upcoming" && "border-(--ui-border) bg-white text-(--ui-text-soft)"
|
|
4766
|
+
),
|
|
4767
|
+
children: status === "complete" ? /* @__PURE__ */ jsx(IconCheck, { size: 14, strokeWidth: 2.5 }) : index + 1
|
|
4768
|
+
}
|
|
4769
|
+
),
|
|
4770
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
4771
|
+
/* @__PURE__ */ jsx("div", { className: twMerge("text-sm font-medium", status === "upcoming" ? neutralTextClasses.muted : "text-(--ui-text-strong)"), children: item.title }),
|
|
4772
|
+
item.description && /* @__PURE__ */ jsx("div", { className: twMerge("mt-1 text-xs", neutralTextClasses.soft), children: item.description })
|
|
4773
|
+
] })
|
|
4774
|
+
] }, index);
|
|
4775
|
+
}) });
|
|
4776
|
+
var colorClass = {
|
|
4777
|
+
primary: "bg-(--ui-primary)",
|
|
4778
|
+
success: "bg-(--ui-success)",
|
|
4779
|
+
danger: "bg-(--ui-danger)",
|
|
4780
|
+
warning: "bg-(--ui-warning)",
|
|
4781
|
+
neutral: "bg-(--ui-border-strong)"
|
|
4782
|
+
};
|
|
4783
|
+
var Timeline = ({ items, className }) => /* @__PURE__ */ jsx("div", { className: twMerge("space-y-4", className), children: items.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "relative flex gap-3 pl-1", children: [
|
|
4784
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col items-center", children: [
|
|
4785
|
+
/* @__PURE__ */ jsx("span", { className: twMerge("mt-1 h-2.5 w-2.5 rounded-full", colorClass[item.color ?? "primary"]) }),
|
|
4786
|
+
index < items.length - 1 && /* @__PURE__ */ jsx("span", { className: "mt-1 h-full w-px bg-(--ui-border)" })
|
|
4787
|
+
] }),
|
|
4788
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 pb-4", children: [
|
|
4789
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
4790
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-(--ui-text-strong)", children: item.title }),
|
|
4791
|
+
item.time && /* @__PURE__ */ jsx("div", { className: twMerge("text-xs", neutralTextClasses.soft), children: item.time })
|
|
4792
|
+
] }),
|
|
4793
|
+
item.description && /* @__PURE__ */ jsx("div", { className: twMerge("mt-1 text-sm", neutralTextClasses.muted), children: item.description })
|
|
4794
|
+
] })
|
|
4795
|
+
] }, index)) });
|
|
4140
4796
|
|
|
4141
4797
|
// src/initUI.ts
|
|
4142
4798
|
function initUI(config) {
|
|
@@ -4250,6 +4906,6 @@ function initUI(config) {
|
|
|
4250
4906
|
r.style.setProperty("--ui-empty-compact-description", layout.empty.compactDescription);
|
|
4251
4907
|
}
|
|
4252
4908
|
|
|
4253
|
-
export { ActiveTag, Alert, Avatar, Badge, Button, CheckboxInput, ColorInput, DateInput, Drawer, DrawerContent, DrawerFooter, DrawerTitle, Dropdown, Empty, ErrorProvider, FilterCheckboxInput, FilterDateInput, FilterDateRangePopover, FilterNumberInput, FilterSelectGroupPopover, FilterSelectInput, FilterTextInput, FlagTag, Grid, GridFilters, HtmlInput, InputError, InputField, InputLabel, MultiSelectInput, NotificationProvider, NumberInput, Panel, Popconfirm, Pretty, SelectInput, ServerError, Skeleton, SortDirection, Spinner, SwitchInput, Table, Tabs, Tag, TextInput, Tooltip, UploadInput, UploadProvider, getIcon, initUI, notification, registerIcons, uiTheme, useDrawer, useGrid, useNotification, useUploadConfig };
|
|
4909
|
+
export { ActionBar, ActiveTag, Alert, Avatar, Badge, Button, CheckboxInput, ColorInput, ConfirmButton, DateInput, DescriptionList, Drawer, DrawerContent, DrawerFooter, DrawerTitle, Dropdown, Empty, EmptyState, EntityHeader, ErrorProvider, Fieldset, FilterCheckboxInput, FilterDateInput, FilterDateRangePopover, FilterNumberInput, FilterSelectGroupPopover, FilterSelectInput, FilterTextInput, FlagTag, FormActions, FormSection, Grid, GridFilters, HtmlInput, InlineEdit, InputError, InputField, InputLabel, KeyValue, Modal, ModalContent, ModalFooter, ModalTitle, MultiSelectInput, NotificationProvider, NumberInput, PageHeader, Panel, Popconfirm, Pretty, RadioGroup, SearchInput, SectionHeader, SelectInput, ServerError, Skeleton, SkeletonTable, SortDirection, Spinner, StatCard, Stepper, SwitchInput, Table, Tabs, Tag, TextInput, Textarea, Timeline, Toolbar, Tooltip, UploadInput, UploadProvider, getIcon, initUI, notification, registerIcons, uiTheme, useDrawer, useGrid, useModal, useNotification, useUploadConfig };
|
|
4254
4910
|
//# sourceMappingURL=index.js.map
|
|
4255
4911
|
//# sourceMappingURL=index.js.map
|