@martinsura/ui 0.1.3 → 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 +628 -204
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.cts +237 -5
- package/dist/index.d.ts +237 -5
- package/dist/index.js +610 -206
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cva } from 'class-variance-authority';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import { IconEyeOff, IconEye, IconDownload, IconPaperclip, IconFileSpreadsheet, IconX, IconTrashX, IconPlus, IconPencil, IconDotsVertical, IconCheck, IconDroplet, IconDatabaseOff, IconChevronUp, IconChevronDown, IconSelector, IconCalendar, IconUsers, IconInfoCircle, IconAlertTriangle, IconCircleX, IconBold, IconItalic, IconUnderline, IconList, IconListNumbers, IconLink, IconUnlink, IconClearFormatting, IconUpload, IconAlertCircle, IconTrash, IconLoader2, IconChevronLeft, IconChevronRight
|
|
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
5
|
import { createContext, forwardRef, useState, useContext, useRef, useLayoutEffect, useEffect, useMemo, useCallback, useId } from 'react';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
@@ -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,
|
|
@@ -473,6 +497,26 @@ var TextInput = forwardRef(({
|
|
|
473
497
|
] });
|
|
474
498
|
});
|
|
475
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
|
+
] });
|
|
519
|
+
};
|
|
476
520
|
var numberInputClass = inputBaseClass + " [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none";
|
|
477
521
|
var NumberInput = ({
|
|
478
522
|
size = "middle",
|
|
@@ -580,6 +624,49 @@ var CheckboxInput = ({
|
|
|
580
624
|
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
|
|
581
625
|
] });
|
|
582
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
|
+
};
|
|
583
670
|
var SwitchInput = ({
|
|
584
671
|
value = false,
|
|
585
672
|
size = "middle",
|
|
@@ -1291,6 +1378,65 @@ var ColorInput = ({
|
|
|
1291
1378
|
errorDisplay && /* @__PURE__ */ jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
|
|
1292
1379
|
] });
|
|
1293
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
|
+
};
|
|
1294
1440
|
var Empty = ({
|
|
1295
1441
|
text = "\u017D\xE1dn\xE9 z\xE1znamy k dispozici",
|
|
1296
1442
|
description,
|
|
@@ -1621,145 +1767,155 @@ var Grid = (props) => {
|
|
|
1621
1767
|
const next = selectedKeys.has(key) ? props.selection.selectedItems.filter((s) => getKey2(s, props.items, props.rowKey) !== key) : [...props.selection.selectedItems, item];
|
|
1622
1768
|
props.selection.onChange(next);
|
|
1623
1769
|
};
|
|
1624
|
-
return /* @__PURE__ */ jsxs(
|
|
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
|
-
|
|
1652
|
-
|
|
1653
|
-
col.align === "center" && "text-center",
|
|
1654
|
-
col.align === "right" && "text-right",
|
|
1655
|
-
props.classNames?.headerCell
|
|
1656
|
-
),
|
|
1657
|
-
children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1658
|
-
col.title,
|
|
1659
|
-
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 }) })
|
|
1660
|
-
] })
|
|
1661
|
-
},
|
|
1662
|
-
i
|
|
1663
|
-
);
|
|
1664
|
-
})
|
|
1665
|
-
] }) }),
|
|
1666
|
-
/* @__PURE__ */ jsx("tbody", { children: isInitialLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1667
|
-
"td",
|
|
1668
|
-
{
|
|
1669
|
-
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1670
|
-
className: twMerge("px-3 py-0", props.classNames?.loadingCell),
|
|
1671
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex min-h-28 items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { size: "large", color: "primary" }) })
|
|
1672
|
-
}
|
|
1673
|
-
) }) : isEmpty ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
1674
|
-
"td",
|
|
1675
|
-
{
|
|
1676
|
-
colSpan: props.columns.length + (props.selection ? 1 : 0),
|
|
1677
|
-
className: twMerge("px-3", props.classNames?.emptyCell),
|
|
1678
|
-
children: /* @__PURE__ */ jsx(Empty, { size: "compact", text: props.emptyText ?? "\u017D\xE1dn\xE9 z\xE1znamy", className: sc.emptyPy })
|
|
1679
|
-
}
|
|
1680
|
-
) }) : props.items.map((item, rowIdx) => {
|
|
1681
|
-
const key = getKey2(item, props.items, props.rowKey);
|
|
1682
|
-
const isSelected = selectedKeys.has(key);
|
|
1683
|
-
return /* @__PURE__ */ jsxs(
|
|
1684
|
-
"tr",
|
|
1685
|
-
{
|
|
1686
|
-
onClick: props.onRowClick ? () => props.onRowClick(item) : void 0,
|
|
1687
|
-
className: twMerge(
|
|
1688
|
-
"border-t border-(--ui-border) transition-colors",
|
|
1689
|
-
rowIdx % 2 === 1 && !isSelected && neutralSurfaceClasses.subtle,
|
|
1690
|
-
isSelected && "bg-blue-50",
|
|
1691
|
-
props.onRowClick && "cursor-pointer hover:bg-blue-50",
|
|
1692
|
-
props.classNames?.bodyRow
|
|
1693
|
-
),
|
|
1694
|
-
children: [
|
|
1695
|
-
props.selection && /* @__PURE__ */ jsx(
|
|
1696
|
-
"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",
|
|
1697
1799
|
{
|
|
1698
|
-
|
|
1699
|
-
onClick: (
|
|
1700
|
-
|
|
1701
|
-
|
|
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",
|
|
1702
1851
|
{
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
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
|
+
) })
|
|
1707
1863
|
}
|
|
1708
|
-
)
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
return /* @__PURE__ */ jsx(
|
|
1716
|
-
"td",
|
|
1717
|
-
{
|
|
1718
|
-
onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
|
|
1719
|
-
className: twMerge(
|
|
1720
|
-
sc.td,
|
|
1721
|
-
"align-middle",
|
|
1722
|
-
verticalBorders && tableCellVerticalBorderClass,
|
|
1723
|
-
col.ellipsis && "max-w-60 truncate",
|
|
1724
|
-
col.wrap && "whitespace-normal",
|
|
1725
|
-
col.align === "center" && "text-center",
|
|
1726
|
-
col.align === "right" && "text-right",
|
|
1727
|
-
col.type === "dot" && "w-9",
|
|
1728
|
-
props.classNames?.bodyCell
|
|
1729
|
-
),
|
|
1730
|
-
children: centeredContent || rightAlignedContent ? /* @__PURE__ */ jsx(
|
|
1731
|
-
"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",
|
|
1732
1871
|
{
|
|
1872
|
+
onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
|
|
1733
1873
|
className: twMerge(
|
|
1734
|
-
|
|
1735
|
-
|
|
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
|
|
1736
1883
|
),
|
|
1737
|
-
children:
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
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
|
+
);
|
|
1763
1919
|
};
|
|
1764
1920
|
function isValueSet(v) {
|
|
1765
1921
|
if (Array.isArray(v)) return v.length > 0;
|
|
@@ -3384,31 +3540,214 @@ var Panel = ({
|
|
|
3384
3540
|
}
|
|
3385
3541
|
);
|
|
3386
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
|
+
};
|
|
3387
3702
|
var Tabs = ({
|
|
3388
3703
|
block = true,
|
|
3704
|
+
variant = "segmented",
|
|
3705
|
+
size = "middle",
|
|
3389
3706
|
...props
|
|
3390
3707
|
}) => /* @__PURE__ */ jsx(
|
|
3391
3708
|
"div",
|
|
3392
3709
|
{
|
|
3710
|
+
role: "tablist",
|
|
3393
3711
|
className: twMerge(
|
|
3394
|
-
|
|
3395
|
-
|
|
3712
|
+
listVariantClass[variant],
|
|
3713
|
+
listSurfaceClass[variant],
|
|
3396
3714
|
block && "flex w-full",
|
|
3397
3715
|
props.className,
|
|
3398
3716
|
props.classNames?.list
|
|
3399
3717
|
),
|
|
3400
|
-
children: props.options.map((opt) => /* @__PURE__ */
|
|
3718
|
+
children: props.options.map((opt) => /* @__PURE__ */ jsxs(
|
|
3401
3719
|
"button",
|
|
3402
3720
|
{
|
|
3403
3721
|
type: "button",
|
|
3404
|
-
|
|
3722
|
+
role: "tab",
|
|
3723
|
+
"aria-selected": props.value === opt.value,
|
|
3724
|
+
disabled: opt.disabled,
|
|
3725
|
+
onClick: () => !opt.disabled && props.onChange(opt.value),
|
|
3405
3726
|
className: twMerge(
|
|
3406
|
-
"flex-1
|
|
3407
|
-
|
|
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)",
|
|
3408
3733
|
props.classNames?.tab,
|
|
3409
3734
|
props.value === opt.value ? props.classNames?.activeTab : props.classNames?.inactiveTab
|
|
3410
3735
|
),
|
|
3411
|
-
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
|
+
]
|
|
3412
3751
|
},
|
|
3413
3752
|
opt.value
|
|
3414
3753
|
))
|
|
@@ -3490,68 +3829,6 @@ var FlagTag = ({ value, label, color = "geekblue", variant }) => {
|
|
|
3490
3829
|
}
|
|
3491
3830
|
return /* @__PURE__ */ jsx(Tag, { color, variant, children: label });
|
|
3492
3831
|
};
|
|
3493
|
-
var AVATAR_COLORS = [
|
|
3494
|
-
"bg-blue-500",
|
|
3495
|
-
"bg-green-500",
|
|
3496
|
-
"bg-purple-500",
|
|
3497
|
-
"bg-orange-500",
|
|
3498
|
-
"bg-pink-500",
|
|
3499
|
-
"bg-teal-500",
|
|
3500
|
-
"bg-red-500",
|
|
3501
|
-
"bg-indigo-500"
|
|
3502
|
-
];
|
|
3503
|
-
function colorFromString(str) {
|
|
3504
|
-
let hash = 0;
|
|
3505
|
-
for (let i = 0; i < str.length; i++) {
|
|
3506
|
-
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
3507
|
-
}
|
|
3508
|
-
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
3509
|
-
}
|
|
3510
|
-
function getInitials(name) {
|
|
3511
|
-
const parts = name.trim().split(/\s+/);
|
|
3512
|
-
if (parts.length === 1) {
|
|
3513
|
-
return parts[0].slice(0, 2).toUpperCase();
|
|
3514
|
-
}
|
|
3515
|
-
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
3516
|
-
}
|
|
3517
|
-
var sizeClasses = {
|
|
3518
|
-
xs: "w-6 h-6 text-[10px]",
|
|
3519
|
-
sm: "w-7 h-7 text-xs",
|
|
3520
|
-
md: "w-8 h-8 text-sm",
|
|
3521
|
-
lg: "w-10 h-10 text-base",
|
|
3522
|
-
xl: "w-12 h-12 text-lg"
|
|
3523
|
-
};
|
|
3524
|
-
var Avatar = ({ size = "md", ...props }) => {
|
|
3525
|
-
const initials = props.name ? getInitials(props.name) : "?";
|
|
3526
|
-
const bgColor = props.color ?? (props.name ? colorFromString(props.name) : "bg-gray-400");
|
|
3527
|
-
if (props.src) {
|
|
3528
|
-
return /* @__PURE__ */ jsx(
|
|
3529
|
-
"img",
|
|
3530
|
-
{
|
|
3531
|
-
src: props.src,
|
|
3532
|
-
alt: props.name ?? "avatar",
|
|
3533
|
-
className: twMerge(
|
|
3534
|
-
"rounded-full object-cover shrink-0",
|
|
3535
|
-
sizeClasses[size],
|
|
3536
|
-
props.className
|
|
3537
|
-
)
|
|
3538
|
-
}
|
|
3539
|
-
);
|
|
3540
|
-
}
|
|
3541
|
-
return /* @__PURE__ */ jsx(
|
|
3542
|
-
"span",
|
|
3543
|
-
{
|
|
3544
|
-
title: props.name,
|
|
3545
|
-
className: twMerge(
|
|
3546
|
-
"inline-flex items-center justify-center rounded-full text-white font-medium shrink-0 select-none",
|
|
3547
|
-
sizeClasses[size],
|
|
3548
|
-
bgColor,
|
|
3549
|
-
props.className
|
|
3550
|
-
),
|
|
3551
|
-
children: /* @__PURE__ */ jsx("span", { className: props.initialsClassName, children: initials })
|
|
3552
|
-
}
|
|
3553
|
-
);
|
|
3554
|
-
};
|
|
3555
3832
|
var defaultToolbar = [
|
|
3556
3833
|
"bold",
|
|
3557
3834
|
"italic",
|
|
@@ -4225,6 +4502,88 @@ var useNotification = () => {
|
|
|
4225
4502
|
info: (message, options) => add("info", message, options)
|
|
4226
4503
|
};
|
|
4227
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
|
+
] });
|
|
4228
4587
|
var Pretty = ({ data, className }) => /* @__PURE__ */ jsx(
|
|
4229
4588
|
"pre",
|
|
4230
4589
|
{
|
|
@@ -4235,6 +4594,10 @@ var Pretty = ({ data, className }) => /* @__PURE__ */ jsx(
|
|
|
4235
4594
|
children: JSON.stringify(data, null, 2)
|
|
4236
4595
|
}
|
|
4237
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
|
+
] }) });
|
|
4238
4601
|
var GAP2 = 10;
|
|
4239
4602
|
var VIEWPORT_MARGIN2 = 8;
|
|
4240
4603
|
function calcPosition3(trigger, tooltip, placement) {
|
|
@@ -4389,6 +4752,47 @@ var Tooltip = ({
|
|
|
4389
4752
|
)
|
|
4390
4753
|
] });
|
|
4391
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)) });
|
|
4392
4796
|
|
|
4393
4797
|
// src/initUI.ts
|
|
4394
4798
|
function initUI(config) {
|
|
@@ -4502,6 +4906,6 @@ function initUI(config) {
|
|
|
4502
4906
|
r.style.setProperty("--ui-empty-compact-description", layout.empty.compactDescription);
|
|
4503
4907
|
}
|
|
4504
4908
|
|
|
4505
|
-
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, Modal, ModalContent, ModalFooter, ModalTitle, 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, useModal, 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 };
|
|
4506
4910
|
//# sourceMappingURL=index.js.map
|
|
4507
4911
|
//# sourceMappingURL=index.js.map
|