@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 CHANGED
@@ -327,7 +327,9 @@ var buttonVariants = classVarianceAuthority.cva(
327
327
  danger: "bg-(--ui-danger) text-(--ui-danger-text) hover:bg-(--ui-danger-hover) active:bg-(--ui-danger-hover)",
328
328
  success: "bg-(--ui-success) text-(--ui-success-text) hover:bg-(--ui-success-hover) active:bg-(--ui-success-hover)",
329
329
  default: "bg-white text-(--ui-text) border border-(--ui-border-strong) hover:bg-(--ui-surface-subtle) active:bg-(--ui-surface-muted)",
330
+ subtle: "bg-(--ui-surface-subtle) text-(--ui-text) border border-transparent hover:bg-(--ui-surface-muted) active:bg-(--ui-surface-muted)",
330
331
  ghost: "text-(--ui-text) hover:bg-(--ui-surface-muted) active:bg-(--ui-surface-subtle)",
332
+ text: "text-(--ui-text) hover:text-(--ui-text-strong) active:text-(--ui-text-strong) px-0! bg-transparent",
331
333
  link: "text-(--ui-primary) hover:underline p-0! h-auto!"
332
334
  },
333
335
  size: {
@@ -363,12 +365,14 @@ var Button = ({
363
365
  size = "middle",
364
366
  shape = "default",
365
367
  block = false,
368
+ fullWidthOnMobile = false,
366
369
  iconPosition = "left",
367
370
  ...props
368
371
  }) => {
369
372
  const iconSize = props.iconSize ?? iconSizeMap[size];
370
373
  const IconComponent = props.icon ?? (props.iconType ? getIcon(props.iconType) : void 0);
371
374
  const iconNode = IconComponent ? /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: iconSize, strokeWidth: 1.5, className: props.classNames?.icon }) : void 0;
375
+ const content = props.text ?? props.children;
372
376
  const handleClick = () => {
373
377
  if (props.disabled || props.loading) {
374
378
  return;
@@ -380,11 +384,16 @@ var Button = ({
380
384
  {
381
385
  type: props.htmlType ?? "button",
382
386
  disabled: props.disabled || props.loading,
383
- className: tailwindMerge.twMerge(buttonVariants({ variant, size, block, shape }), props.className),
387
+ className: tailwindMerge.twMerge(
388
+ buttonVariants({ variant, size, block, shape }),
389
+ fullWidthOnMobile && !block && "w-full sm:w-auto",
390
+ props.iconOnly && "px-0!",
391
+ props.className
392
+ ),
384
393
  onClick: props.confirm ? void 0 : handleClick,
385
394
  children: [
386
395
  props.loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: iconSize, color: "current", className: props.classNames?.spinner }) : iconPosition === "left" && iconNode,
387
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: props.classNames?.content, children: props.text ?? props.children }),
396
+ !props.iconOnly && content !== void 0 && content !== null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: props.classNames?.content, children: content }),
388
397
  !props.loading && iconPosition === "right" && iconNode
389
398
  ]
390
399
  }
@@ -404,6 +413,21 @@ var Button = ({
404
413
  }
405
414
  );
406
415
  };
416
+ var ConfirmButton = (props) => /* @__PURE__ */ jsxRuntime.jsx(
417
+ Button,
418
+ {
419
+ text: props.text,
420
+ onClick: props.onClick,
421
+ disabled: props.disabled,
422
+ loading: props.loading,
423
+ variant: props.variant,
424
+ size: props.size,
425
+ icon: props.icon,
426
+ className: props.className,
427
+ confirm: props.confirm,
428
+ children: props.children
429
+ }
430
+ );
407
431
  var InputField = ({ noMargin, className, children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex flex-col gap-1", !noMargin && "mb-3", className), children });
408
432
  var InputLabel = ({ label, required, className, requiredMarkClassName }) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: tailwindMerge.twMerge("text-sm text-(--ui-text)", className), children: [
409
433
  label,
@@ -417,12 +441,12 @@ var ErrorContext = react.createContext({
417
441
  var ErrorProvider = ({ resolveInputError, resolveServerError, children }) => /* @__PURE__ */ jsxRuntime.jsx(ErrorContext.Provider, { value: { resolveInputError, resolveServerError }, children });
418
442
  var useErrorResolver = () => react.useContext(ErrorContext).resolveInputError;
419
443
  var useServerError = () => react.useContext(ErrorContext).resolveServerError;
420
- var TextInput = ({
444
+ var TextInput = react.forwardRef(({
421
445
  size = "middle",
422
446
  password = false,
423
447
  newPassword = false,
424
448
  ...props
425
- }) => {
449
+ }, ref) => {
426
450
  const [showPassword, setShowPassword] = react.useState(false);
427
451
  const resolveError = useErrorResolver();
428
452
  const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
@@ -443,6 +467,7 @@ var TextInput = ({
443
467
  /* @__PURE__ */ jsxRuntime.jsx(
444
468
  "input",
445
469
  {
470
+ ref,
446
471
  type: inputType,
447
472
  autoComplete: newPassword ? "new-password" : void 0,
448
473
  placeholder: props.placeholder,
@@ -476,6 +501,27 @@ var TextInput = ({
476
501
  ] }),
477
502
  errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
478
503
  ] });
504
+ });
505
+ TextInput.displayName = "TextInput";
506
+ var Textarea = ({ rows = 4, ...props }) => {
507
+ const resolveError = useErrorResolver();
508
+ const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
509
+ const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
510
+ return /* @__PURE__ */ jsxRuntime.jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
511
+ props.label && /* @__PURE__ */ jsxRuntime.jsx(InputLabel, { label: props.label, required: props.required }),
512
+ /* @__PURE__ */ jsxRuntime.jsx(
513
+ "textarea",
514
+ {
515
+ rows,
516
+ value: props.value ?? "",
517
+ placeholder: props.placeholder,
518
+ disabled: props.disabled,
519
+ onChange: (e) => props.onChange?.(e.target.value),
520
+ className: tailwindMerge.twMerge(inputBaseClass, "min-h-24 py-2", errorDisplay && "border-(--ui-danger)")
521
+ }
522
+ ),
523
+ errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay) })
524
+ ] });
479
525
  };
480
526
  var numberInputClass = inputBaseClass + " [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none";
481
527
  var NumberInput = ({
@@ -584,6 +630,49 @@ var CheckboxInput = ({
584
630
  errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
585
631
  ] });
586
632
  };
633
+ var RadioGroup = ({
634
+ direction = "column",
635
+ ...props
636
+ }) => {
637
+ const resolveError = useErrorResolver();
638
+ const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
639
+ const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
640
+ return /* @__PURE__ */ jsxRuntime.jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
641
+ props.label && /* @__PURE__ */ jsxRuntime.jsx(InputLabel, { label: props.label, required: props.required }),
642
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex gap-2", direction === "column" ? "flex-col" : "flex-wrap items-stretch"), children: props.options.map((option) => {
643
+ const checked = props.value === option.value;
644
+ const isDisabled = props.disabled || option.disabled;
645
+ return /* @__PURE__ */ jsxRuntime.jsxs(
646
+ "label",
647
+ {
648
+ className: tailwindMerge.twMerge(
649
+ "flex items-start gap-3 rounded-(--ui-radius-md) border border-(--ui-border) bg-white px-3 py-2",
650
+ checked && "border-(--ui-border-focus) bg-(--ui-surface-subtle)",
651
+ isDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
652
+ ),
653
+ children: [
654
+ /* @__PURE__ */ jsxRuntime.jsx(
655
+ "input",
656
+ {
657
+ type: "radio",
658
+ className: "mt-1 h-4 w-4 accent-(--ui-primary)",
659
+ checked,
660
+ disabled: isDisabled,
661
+ onChange: () => props.onChange?.(option.value)
662
+ }
663
+ ),
664
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0", children: [
665
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-sm text-(--ui-text)", children: option.label }),
666
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("block text-xs", neutralTextClasses.soft), children: option.description })
667
+ ] })
668
+ ]
669
+ },
670
+ option.value
671
+ );
672
+ }) }),
673
+ errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay) })
674
+ ] });
675
+ };
587
676
  var SwitchInput = ({
588
677
  value = false,
589
678
  size = "middle",
@@ -651,7 +740,7 @@ var SwitchInput = ({
651
740
 
652
741
  // src/floating/layerStack.ts
653
742
  var FLOATING_ROOT_SELECTOR = "[data-ui-floating-root]";
654
- var DRAWER_ROOT_SELECTOR = "[data-ui-drawer-root]";
743
+ var LAYER_ROOT_SELECTOR = "[data-ui-layer-root]";
655
744
  function getTopmostElement(selector) {
656
745
  const elements = document.querySelectorAll(selector);
657
746
  return elements.length > 0 ? elements[elements.length - 1] : null;
@@ -662,8 +751,8 @@ function hasFloatingRootOpen() {
662
751
  function isTopmostFloatingRoot(element) {
663
752
  return element !== null && getTopmostElement(FLOATING_ROOT_SELECTOR) === element;
664
753
  }
665
- function isTopmostDrawerRoot(element) {
666
- return element !== null && getTopmostElement(DRAWER_ROOT_SELECTOR) === element;
754
+ function isTopmostLayerRoot(element) {
755
+ return element !== null && getTopmostElement(LAYER_ROOT_SELECTOR) === element;
667
756
  }
668
757
  function isTargetInsideFloatingRoot(target) {
669
758
  return target instanceof Element && target.closest(FLOATING_ROOT_SELECTOR) !== null;
@@ -1295,6 +1384,65 @@ var ColorInput = ({
1295
1384
  errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay), className: props.classNames?.error })
1296
1385
  ] });
1297
1386
  };
1387
+ var SearchInput = ({ ...props }) => {
1388
+ const resolveError = useErrorResolver();
1389
+ const resolvedErrors = props.errorName ? resolveError(props.errorName) : [];
1390
+ const errorDisplay = props.error ?? props.customError ?? (resolvedErrors.length > 0 ? resolvedErrors.join(", ") : void 0);
1391
+ const hasValue = !!props.value;
1392
+ return /* @__PURE__ */ jsxRuntime.jsxs(InputField, { noMargin: props.noMargin, className: props.className, children: [
1393
+ props.label && /* @__PURE__ */ jsxRuntime.jsx(InputLabel, { label: props.label }),
1394
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1395
+ /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconSearch, { size: 15, strokeWidth: 1.75, className: tailwindMerge.twMerge("pointer-events-none absolute left-3 top-1/2 -translate-y-1/2", neutralIconClasses.default) }),
1396
+ /* @__PURE__ */ jsxRuntime.jsx(
1397
+ "input",
1398
+ {
1399
+ value: props.value ?? "",
1400
+ onChange: (e) => props.onChange?.(e.target.value),
1401
+ placeholder: props.placeholder ?? "Hledat...",
1402
+ className: tailwindMerge.twMerge(inputBaseClass, "pl-9 pr-9", errorDisplay && "border-(--ui-danger)")
1403
+ }
1404
+ ),
1405
+ hasValue && /* @__PURE__ */ jsxRuntime.jsx(
1406
+ "button",
1407
+ {
1408
+ type: "button",
1409
+ onClick: () => {
1410
+ props.onChange?.("");
1411
+ props.onClear?.();
1412
+ },
1413
+ className: tailwindMerge.twMerge("absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer", neutralIconClasses.default, neutralIconClasses.hover),
1414
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconX, { size: 14, strokeWidth: 2 })
1415
+ }
1416
+ )
1417
+ ] }),
1418
+ errorDisplay && /* @__PURE__ */ jsxRuntime.jsx(InputError, { error: String(errorDisplay) })
1419
+ ] });
1420
+ };
1421
+ var InlineEdit = ({ value, placeholder = "Klikn\u011Bte pro editaci", multiline = false, onSave, label, className }) => {
1422
+ const [editing, setEditing] = react.useState(false);
1423
+ const [draft, setDraft] = react.useState(value ?? "");
1424
+ const cancel = () => {
1425
+ setDraft(value ?? "");
1426
+ setEditing(false);
1427
+ };
1428
+ const save = () => {
1429
+ onSave?.(draft);
1430
+ setEditing(false);
1431
+ };
1432
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("rounded-(--ui-radius-md) border border-(--ui-border) bg-white p-3", className), children: [
1433
+ label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-medium uppercase tracking-[0.08em] text-(--ui-text-soft)", children: label }),
1434
+ editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1435
+ multiline ? /* @__PURE__ */ jsxRuntime.jsx(Textarea, { value: draft, onChange: setDraft, noMargin: true, rows: 4 }) : /* @__PURE__ */ jsxRuntime.jsx(TextInput, { value: draft, onChange: setDraft, noMargin: true }),
1436
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1437
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", text: "Ulo\u017Eit", icon: iconsReact.IconCheck, onClick: save }),
1438
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", variant: "default", text: "Zru\u0161it", icon: iconsReact.IconX, onClick: cancel })
1439
+ ] })
1440
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: () => setEditing(true), className: "flex w-full items-start justify-between gap-3 text-left cursor-pointer", children: [
1441
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: value ? "text-(--ui-text)" : tailwindMerge.twMerge("italic", neutralTextClasses.soft), children: value || placeholder }),
1442
+ /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconPencil, { size: 14, strokeWidth: 1.75, className: neutralTextClasses.soft })
1443
+ ] })
1444
+ ] });
1445
+ };
1298
1446
  var Empty = ({
1299
1447
  text = "\u017D\xE1dn\xE9 z\xE1znamy k dispozici",
1300
1448
  description,
@@ -1625,145 +1773,155 @@ var Grid = (props) => {
1625
1773
  const next = selectedKeys.has(key) ? props.selection.selectedItems.filter((s) => getKey2(s, props.items, props.rowKey) !== key) : [...props.selection.selectedItems, item];
1626
1774
  props.selection.onChange(next);
1627
1775
  };
1628
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("relative border border-(--ui-border) rounded-(--ui-radius-lg) overflow-hidden", props.className), children: [
1629
- props.loading && !isInitialLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("absolute inset-0 z-10 bg-white/60 flex items-center justify-center", props.classNames?.overlay), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "large", color: "primary" }) }),
1630
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: tailwindMerge.twMerge("w-full border-collapse", props.classNames?.table), children: [
1631
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: tailwindMerge.twMerge("bg-(--ui-primary) text-(--ui-primary-text)", props.classNames?.headerRow), children: [
1632
- props.selection && /* @__PURE__ */ jsxRuntime.jsx("th", { className: tailwindMerge.twMerge(sc.th, "w-9", verticalBorders && tableHeaderVerticalBorderClass, props.classNames?.headerCell), children: /* @__PURE__ */ jsxRuntime.jsx(
1633
- "input",
1634
- {
1635
- type: "checkbox",
1636
- checked: allSelected,
1637
- ref: (el) => {
1638
- if (el) el.indeterminate = someSelected;
1639
- },
1640
- onChange: toggleAll,
1641
- className: "cursor-pointer accent-white"
1642
- }
1643
- ) }),
1644
- props.columns.map((col, i) => {
1645
- const isSortable = col.sortBy !== void 0;
1646
- const isCurrent = isSortable && grid.sortBy === col.sortBy;
1647
- return /* @__PURE__ */ jsxRuntime.jsx(
1648
- "th",
1649
- {
1650
- style: { width: col.width ?? columnTypeWidth2[col.type] },
1651
- onClick: isSortable ? () => handleSort(col) : void 0,
1652
- className: tailwindMerge.twMerge(
1653
- sc.th,
1654
- "font-normal text-left whitespace-nowrap",
1655
- verticalBorders && tableHeaderVerticalBorderClass,
1656
- isSortable && "cursor-pointer select-none hover:bg-white/10",
1657
- col.align === "center" && "text-center",
1658
- col.align === "right" && "text-right",
1659
- props.classNames?.headerCell
1660
- ),
1661
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
1662
- col.title,
1663
- isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70", children: isCurrent ? grid.direction === SortDirection.Asc ? /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronUp, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronDown, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconSelector, { size: 12, strokeWidth: 2 }) })
1664
- ] })
1665
- },
1666
- i
1667
- );
1668
- })
1669
- ] }) }),
1670
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: isInitialLoading ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
1671
- "td",
1672
- {
1673
- colSpan: props.columns.length + (props.selection ? 1 : 0),
1674
- className: tailwindMerge.twMerge("px-3 py-0", props.classNames?.loadingCell),
1675
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-28 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "large", color: "primary" }) })
1676
- }
1677
- ) }) : isEmpty ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
1678
- "td",
1679
- {
1680
- colSpan: props.columns.length + (props.selection ? 1 : 0),
1681
- className: tailwindMerge.twMerge("px-3", props.classNames?.emptyCell),
1682
- children: /* @__PURE__ */ jsxRuntime.jsx(Empty, { size: "compact", text: props.emptyText ?? "\u017D\xE1dn\xE9 z\xE1znamy", className: sc.emptyPy })
1683
- }
1684
- ) }) : props.items.map((item, rowIdx) => {
1685
- const key = getKey2(item, props.items, props.rowKey);
1686
- const isSelected = selectedKeys.has(key);
1687
- return /* @__PURE__ */ jsxRuntime.jsxs(
1688
- "tr",
1689
- {
1690
- onClick: props.onRowClick ? () => props.onRowClick(item) : void 0,
1691
- className: tailwindMerge.twMerge(
1692
- "border-t border-(--ui-border) transition-colors",
1693
- rowIdx % 2 === 1 && !isSelected && neutralSurfaceClasses.subtle,
1694
- isSelected && "bg-blue-50",
1695
- props.onRowClick && "cursor-pointer hover:bg-blue-50",
1696
- props.classNames?.bodyRow
1697
- ),
1698
- children: [
1699
- props.selection && /* @__PURE__ */ jsxRuntime.jsx(
1700
- "td",
1776
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1777
+ "div",
1778
+ {
1779
+ className: tailwindMerge.twMerge(
1780
+ "relative border border-(--ui-border) rounded-(--ui-radius-lg) overflow-hidden",
1781
+ props.attachedTop && "rounded-t-none border-t-0",
1782
+ props.className
1783
+ ),
1784
+ children: [
1785
+ props.loading && !isInitialLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("absolute inset-0 z-10 bg-white/60 flex items-center justify-center", props.classNames?.overlay), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "large", color: "primary" }) }),
1786
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: tailwindMerge.twMerge("w-full border-collapse", props.classNames?.table), children: [
1787
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: tailwindMerge.twMerge("bg-(--ui-primary) text-(--ui-primary-text)", props.classNames?.headerRow), children: [
1788
+ props.selection && /* @__PURE__ */ jsxRuntime.jsx("th", { className: tailwindMerge.twMerge(sc.th, "w-9", verticalBorders && tableHeaderVerticalBorderClass, props.classNames?.headerCell), children: /* @__PURE__ */ jsxRuntime.jsx(
1789
+ "input",
1790
+ {
1791
+ type: "checkbox",
1792
+ checked: allSelected,
1793
+ ref: (el) => {
1794
+ if (el) el.indeterminate = someSelected;
1795
+ },
1796
+ onChange: toggleAll,
1797
+ className: "cursor-pointer accent-white"
1798
+ }
1799
+ ) }),
1800
+ props.columns.map((col, i) => {
1801
+ const isSortable = col.sortBy !== void 0;
1802
+ const isCurrent = isSortable && grid.sortBy === col.sortBy;
1803
+ return /* @__PURE__ */ jsxRuntime.jsx(
1804
+ "th",
1701
1805
  {
1702
- className: tailwindMerge.twMerge(sc.td, "w-9 align-middle", verticalBorders && tableCellVerticalBorderClass, props.classNames?.bodyCell),
1703
- onClick: (e) => e.stopPropagation(),
1704
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1705
- "input",
1806
+ style: { width: col.width ?? columnTypeWidth2[col.type] },
1807
+ onClick: isSortable ? () => handleSort(col) : void 0,
1808
+ className: tailwindMerge.twMerge(
1809
+ sc.th,
1810
+ "font-normal text-left whitespace-nowrap",
1811
+ verticalBorders && tableHeaderVerticalBorderClass,
1812
+ isSortable && "cursor-pointer select-none hover:bg-white/10",
1813
+ col.align === "center" && "text-center",
1814
+ col.align === "right" && "text-right",
1815
+ props.classNames?.headerCell
1816
+ ),
1817
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
1818
+ col.title,
1819
+ isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70", children: isCurrent ? grid.direction === SortDirection.Asc ? /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronUp, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronDown, { size: 12, strokeWidth: 2 }) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconSelector, { size: 12, strokeWidth: 2 }) })
1820
+ ] })
1821
+ },
1822
+ i
1823
+ );
1824
+ })
1825
+ ] }) }),
1826
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: isInitialLoading ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
1827
+ "td",
1828
+ {
1829
+ colSpan: props.columns.length + (props.selection ? 1 : 0),
1830
+ className: tailwindMerge.twMerge("px-3 py-0", props.classNames?.loadingCell),
1831
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-28 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "large", color: "primary" }) })
1832
+ }
1833
+ ) }) : isEmpty ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
1834
+ "td",
1835
+ {
1836
+ colSpan: props.columns.length + (props.selection ? 1 : 0),
1837
+ className: tailwindMerge.twMerge("px-3", props.classNames?.emptyCell),
1838
+ children: /* @__PURE__ */ jsxRuntime.jsx(Empty, { size: "compact", text: props.emptyText ?? "\u017D\xE1dn\xE9 z\xE1znamy", className: sc.emptyPy })
1839
+ }
1840
+ ) }) : props.items.map((item, rowIdx) => {
1841
+ const key = getKey2(item, props.items, props.rowKey);
1842
+ const isSelected = selectedKeys.has(key);
1843
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1844
+ "tr",
1845
+ {
1846
+ onClick: props.onRowClick ? () => props.onRowClick(item) : void 0,
1847
+ className: tailwindMerge.twMerge(
1848
+ "border-t border-(--ui-border) transition-colors",
1849
+ rowIdx % 2 === 1 && !isSelected && neutralSurfaceClasses.subtle,
1850
+ isSelected && "bg-blue-50",
1851
+ props.onRowClick && "cursor-pointer hover:bg-blue-50",
1852
+ props.classNames?.bodyRow
1853
+ ),
1854
+ children: [
1855
+ props.selection && /* @__PURE__ */ jsxRuntime.jsx(
1856
+ "td",
1706
1857
  {
1707
- type: "checkbox",
1708
- checked: isSelected,
1709
- onChange: () => toggleRow(item),
1710
- className: "cursor-pointer"
1858
+ className: tailwindMerge.twMerge(sc.td, "w-9 align-middle", verticalBorders && tableCellVerticalBorderClass, props.classNames?.bodyCell),
1859
+ onClick: (e) => e.stopPropagation(),
1860
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1861
+ "input",
1862
+ {
1863
+ type: "checkbox",
1864
+ checked: isSelected,
1865
+ onChange: () => toggleRow(item),
1866
+ className: "cursor-pointer"
1867
+ }
1868
+ ) })
1711
1869
  }
1712
- ) })
1713
- }
1714
- ),
1715
- props.columns.map((col, colIdx) => {
1716
- const content = col.render ? col.render(item) : col.dataField ? formatCellValue(item[col.dataField], col.type) : null;
1717
- const centeredContent = col.align === "center";
1718
- const rightAlignedContent = col.align === "right";
1719
- return /* @__PURE__ */ jsxRuntime.jsx(
1720
- "td",
1721
- {
1722
- onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
1723
- className: tailwindMerge.twMerge(
1724
- sc.td,
1725
- "align-middle",
1726
- verticalBorders && tableCellVerticalBorderClass,
1727
- col.ellipsis && "max-w-60 truncate",
1728
- col.wrap && "whitespace-normal",
1729
- col.align === "center" && "text-center",
1730
- col.align === "right" && "text-right",
1731
- col.type === "dot" && "w-9",
1732
- props.classNames?.bodyCell
1733
- ),
1734
- children: centeredContent || rightAlignedContent ? /* @__PURE__ */ jsxRuntime.jsx(
1735
- "div",
1870
+ ),
1871
+ props.columns.map((col, colIdx) => {
1872
+ const content = col.render ? col.render(item) : col.dataField ? formatCellValue(item[col.dataField], col.type) : null;
1873
+ const centeredContent = col.align === "center";
1874
+ const rightAlignedContent = col.align === "right";
1875
+ return /* @__PURE__ */ jsxRuntime.jsx(
1876
+ "td",
1736
1877
  {
1878
+ onClick: col.type === "dot" ? (e) => e.stopPropagation() : void 0,
1737
1879
  className: tailwindMerge.twMerge(
1738
- "flex w-full items-center",
1739
- centeredContent ? "justify-center" : "justify-end"
1880
+ sc.td,
1881
+ "align-middle",
1882
+ verticalBorders && tableCellVerticalBorderClass,
1883
+ col.ellipsis && "max-w-60 truncate",
1884
+ col.wrap && "whitespace-normal",
1885
+ col.align === "center" && "text-center",
1886
+ col.align === "right" && "text-right",
1887
+ col.type === "dot" && "w-9",
1888
+ props.classNames?.bodyCell
1740
1889
  ),
1741
- children: content
1742
- }
1743
- ) : content
1744
- },
1745
- colIdx
1746
- );
1747
- })
1748
- ]
1749
- },
1750
- key
1751
- );
1752
- }) })
1753
- ] }) }),
1754
- /* @__PURE__ */ jsxRuntime.jsx(
1755
- Pagination,
1756
- {
1757
- current: grid.pageNumber,
1758
- pageSize: grid.pageSize,
1759
- total: props.totalCount,
1760
- showPageNumberChanger: props.showPageNumberChanger ?? false,
1761
- showPageSizeChanger: props.showPageSizeChanger ?? false,
1762
- onChange: (page, pageSize) => grid.onChange({ pageNumber: page, pageSize }),
1763
- classNames: props.classNames?.pagination
1764
- }
1765
- )
1766
- ] });
1890
+ children: centeredContent || rightAlignedContent ? /* @__PURE__ */ jsxRuntime.jsx(
1891
+ "div",
1892
+ {
1893
+ className: tailwindMerge.twMerge(
1894
+ "flex w-full items-center",
1895
+ centeredContent ? "justify-center" : "justify-end"
1896
+ ),
1897
+ children: content
1898
+ }
1899
+ ) : content
1900
+ },
1901
+ colIdx
1902
+ );
1903
+ })
1904
+ ]
1905
+ },
1906
+ key
1907
+ );
1908
+ }) })
1909
+ ] }) }),
1910
+ /* @__PURE__ */ jsxRuntime.jsx(
1911
+ Pagination,
1912
+ {
1913
+ current: grid.pageNumber,
1914
+ pageSize: grid.pageSize,
1915
+ total: props.totalCount,
1916
+ showPageNumberChanger: props.showPageNumberChanger ?? false,
1917
+ showPageSizeChanger: props.showPageSizeChanger ?? false,
1918
+ onChange: (page, pageSize) => grid.onChange({ pageNumber: page, pageSize }),
1919
+ classNames: props.classNames?.pagination
1920
+ }
1921
+ )
1922
+ ]
1923
+ }
1924
+ );
1767
1925
  };
1768
1926
  function isValueSet(v) {
1769
1927
  if (Array.isArray(v)) return v.length > 0;
@@ -2894,7 +3052,7 @@ var Drawer = ({ placement = "top", ...props }) => {
2894
3052
  if (isTargetInsideFloatingRoot(e.target)) {
2895
3053
  return;
2896
3054
  }
2897
- if (!isTopmostDrawerRoot(panelRef.current)) {
3055
+ if (!isTopmostLayerRoot(panelRef.current)) {
2898
3056
  return;
2899
3057
  }
2900
3058
  props.onClose(false);
@@ -2935,7 +3093,7 @@ var Drawer = ({ placement = "top", ...props }) => {
2935
3093
  "div",
2936
3094
  {
2937
3095
  ref: panelRef,
2938
- "data-ui-drawer-root": "",
3096
+ "data-ui-layer-root": "",
2939
3097
  className: tailwindMerge.twMerge(
2940
3098
  panelBase[placement],
2941
3099
  "bg-white shadow-xl transition-transform duration-220 ease-out",
@@ -3047,6 +3205,256 @@ var DrawerContent = ({ loading = false, children }) => {
3047
3205
  }
3048
3206
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
3049
3207
  };
3208
+ var ModalContext = react.createContext(null);
3209
+ function useModal() {
3210
+ const ctx = react.useContext(ModalContext);
3211
+ if (!ctx) {
3212
+ throw new Error("useModal must be used inside Modal");
3213
+ }
3214
+ return ctx;
3215
+ }
3216
+ var TRANSITION_MS2 = 220;
3217
+ var sizeClass = {
3218
+ small: "w-full max-w-lg",
3219
+ middle: "w-full max-w-3xl",
3220
+ large: "w-full max-w-5xl",
3221
+ auto: "w-auto"
3222
+ };
3223
+ var Modal = ({
3224
+ placement = "center",
3225
+ size = "middle",
3226
+ width,
3227
+ maxWidth,
3228
+ closeOnEscape = true,
3229
+ closeOnOverlayClick = true,
3230
+ showCloseButton = true,
3231
+ hideHeader = false,
3232
+ destroyOnClose = true,
3233
+ preventClose = false,
3234
+ beforeClose,
3235
+ initialFocusRef,
3236
+ ...props
3237
+ }) => {
3238
+ const [rendered, setRendered] = react.useState(props.isOpen);
3239
+ const [visible, setVisible] = react.useState(false);
3240
+ const [title, setTitle] = react.useState("");
3241
+ const [footer, setFooter] = react.useState(null);
3242
+ const [loading, setLoading] = react.useState(false);
3243
+ const frameRef = react.useRef(0);
3244
+ const panelRef = react.useRef(null);
3245
+ react.useEffect(() => {
3246
+ if (props.isOpen) {
3247
+ setRendered(true);
3248
+ frameRef.current = requestAnimationFrame(() => {
3249
+ frameRef.current = requestAnimationFrame(() => setVisible(true));
3250
+ });
3251
+ } else {
3252
+ setVisible(false);
3253
+ if (!destroyOnClose) {
3254
+ return () => cancelAnimationFrame(frameRef.current);
3255
+ }
3256
+ const t = setTimeout(() => setRendered(false), TRANSITION_MS2);
3257
+ return () => clearTimeout(t);
3258
+ }
3259
+ return () => cancelAnimationFrame(frameRef.current);
3260
+ }, [destroyOnClose, props.isOpen]);
3261
+ react.useEffect(() => {
3262
+ if (!props.isOpen) {
3263
+ return;
3264
+ }
3265
+ const focusTarget = initialFocusRef?.current;
3266
+ if (!focusTarget) {
3267
+ return;
3268
+ }
3269
+ const timeout = window.setTimeout(() => focusTarget.focus(), TRANSITION_MS2 / 2);
3270
+ return () => window.clearTimeout(timeout);
3271
+ }, [initialFocusRef, props.isOpen]);
3272
+ react.useEffect(() => {
3273
+ if (!props.isOpen) {
3274
+ return;
3275
+ }
3276
+ const handleKeyDown = (e) => {
3277
+ if (!closeOnEscape || e.key !== "Escape" || e.defaultPrevented) {
3278
+ return;
3279
+ }
3280
+ if (hasFloatingRootOpen() || isTargetInsideFloatingRoot(e.target)) {
3281
+ return;
3282
+ }
3283
+ if (!isTopmostLayerRoot(panelRef.current)) {
3284
+ return;
3285
+ }
3286
+ void requestClose();
3287
+ };
3288
+ document.body.style.overflow = "hidden";
3289
+ document.addEventListener("keydown", handleKeyDown);
3290
+ return () => {
3291
+ document.body.style.overflow = "";
3292
+ document.removeEventListener("keydown", handleKeyDown);
3293
+ };
3294
+ }, [closeOnEscape, props.isOpen]);
3295
+ if (!rendered) {
3296
+ return null;
3297
+ }
3298
+ const requestClose = async () => {
3299
+ if (preventClose) {
3300
+ return;
3301
+ }
3302
+ const canClose = await beforeClose?.();
3303
+ if (canClose === false) {
3304
+ return;
3305
+ }
3306
+ props.onClose(false);
3307
+ };
3308
+ const close = () => {
3309
+ void requestClose();
3310
+ };
3311
+ const saveAndClose = (message) => {
3312
+ if (message) {
3313
+ notification.success(message);
3314
+ }
3315
+ props.onClose(true);
3316
+ };
3317
+ const hasFooter = footer !== null;
3318
+ const isFullscreen = placement === "fullscreen";
3319
+ return reactDom.createPortal(
3320
+ /* @__PURE__ */ jsxRuntime.jsxs(ModalContext.Provider, { value: { close, saveAndClose, setTitle, setFooter, setLoading }, children: [
3321
+ /* @__PURE__ */ jsxRuntime.jsx(
3322
+ "div",
3323
+ {
3324
+ className: tailwindMerge.twMerge(
3325
+ "fixed inset-0 z-1000 bg-black/40 transition-opacity duration-220",
3326
+ visible ? "opacity-100" : "opacity-0",
3327
+ !props.isOpen && "pointer-events-none",
3328
+ props.classNames?.overlay
3329
+ ),
3330
+ onClick: () => closeOnOverlayClick && close()
3331
+ }
3332
+ ),
3333
+ /* @__PURE__ */ jsxRuntime.jsx(
3334
+ "div",
3335
+ {
3336
+ className: tailwindMerge.twMerge(
3337
+ "fixed inset-0 z-1001 flex p-4 transition-all duration-220",
3338
+ isFullscreen ? "items-stretch justify-stretch p-0" : "items-center justify-center",
3339
+ !props.isOpen && "pointer-events-none"
3340
+ ),
3341
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3342
+ "div",
3343
+ {
3344
+ ref: panelRef,
3345
+ "data-ui-layer-root": "",
3346
+ role: "dialog",
3347
+ "aria-modal": "true",
3348
+ "aria-hidden": !props.isOpen,
3349
+ style: !isFullscreen ? { width, maxWidth } : void 0,
3350
+ className: tailwindMerge.twMerge(
3351
+ "bg-white shadow-xl flex flex-col transition-all duration-220 ease-out",
3352
+ isFullscreen ? "h-full w-full rounded-none" : `${sizeClass[size]} max-h-[calc(100dvh-32px)] rounded-(--ui-radius-lg)`,
3353
+ visible ? "scale-100 opacity-100" : "scale-95 opacity-0",
3354
+ props.className,
3355
+ props.classNames?.panel
3356
+ ),
3357
+ onClick: (e) => e.stopPropagation(),
3358
+ children: [
3359
+ !hideHeader && /* @__PURE__ */ jsxRuntime.jsxs(
3360
+ "div",
3361
+ {
3362
+ className: tailwindMerge.twMerge(
3363
+ "flex items-center justify-between gap-2 bg-(--ui-primary) shrink-0 rounded-t-(--ui-radius-lg)",
3364
+ isFullscreen && "rounded-none",
3365
+ drawerLayoutClasses.header,
3366
+ props.classNames?.header
3367
+ ),
3368
+ children: [
3369
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge(componentTitleClasses.inverse, "truncate", props.classNames?.title), children: title }),
3370
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
3371
+ "button",
3372
+ {
3373
+ type: "button",
3374
+ onClick: close,
3375
+ className: tailwindMerge.twMerge(
3376
+ "shrink-0 text-(--ui-primary-text)/70 hover:text-(--ui-primary-text) cursor-pointer transition-colors",
3377
+ props.classNames?.closeButton
3378
+ ),
3379
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconX, { size: 18, strokeWidth: 1.5 })
3380
+ }
3381
+ )
3382
+ ]
3383
+ }
3384
+ ),
3385
+ /* @__PURE__ */ jsxRuntime.jsx(
3386
+ "div",
3387
+ {
3388
+ className: tailwindMerge.twMerge(
3389
+ "overflow-y-auto flex-1",
3390
+ isFullscreen ? "min-h-0" : "max-h-[calc(100dvh-120px)]",
3391
+ drawerLayoutClasses.body,
3392
+ props.classNames?.body
3393
+ ),
3394
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex items-center justify-center py-16", props.classNames?.loading), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "large", color: "primary" }) }) : props.children
3395
+ }
3396
+ ),
3397
+ hasFooter && /* @__PURE__ */ jsxRuntime.jsx(
3398
+ "div",
3399
+ {
3400
+ className: tailwindMerge.twMerge(
3401
+ "border-t border-(--ui-border) shrink-0 bg-white",
3402
+ isFullscreen ? "rounded-none" : "rounded-b-(--ui-radius-lg)",
3403
+ drawerLayoutClasses.footer,
3404
+ props.classNames?.footer
3405
+ ),
3406
+ children: footer
3407
+ }
3408
+ )
3409
+ ]
3410
+ }
3411
+ )
3412
+ }
3413
+ )
3414
+ ] }),
3415
+ document.body
3416
+ );
3417
+ };
3418
+ var ModalTitle = ({ children }) => {
3419
+ const { setTitle } = useModal();
3420
+ react.useEffect(() => {
3421
+ setTitle(String(children));
3422
+ return () => setTitle("");
3423
+ }, [children]);
3424
+ return null;
3425
+ };
3426
+ var alignClass2 = {
3427
+ left: "justify-start",
3428
+ center: "justify-center",
3429
+ right: "justify-end"
3430
+ };
3431
+ var ModalFooter = ({ children, align = "right" }) => {
3432
+ const { setFooter } = useModal();
3433
+ react.useEffect(() => {
3434
+ setFooter(
3435
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex items-center gap-2", alignClass2[align]), children })
3436
+ );
3437
+ return () => setFooter(null);
3438
+ }, [align, children]);
3439
+ return null;
3440
+ };
3441
+ var ModalSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-3", children: [
3442
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3" }),
3443
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" }),
3444
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3 mt-5" }),
3445
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" }),
3446
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-(--ui-surface-muted) rounded w-1/3 mt-5" }),
3447
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-(--ui-surface-muted) rounded" })
3448
+ ] });
3449
+ var ModalContent = ({ loading = false, children }) => {
3450
+ if (loading) {
3451
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-5", children: [
3452
+ /* @__PURE__ */ jsxRuntime.jsx(ModalSkeleton, {}),
3453
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { active: true, title: false, paragraph: { rows: 2 } })
3454
+ ] });
3455
+ }
3456
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
3457
+ };
3050
3458
  var Alert = ({ type = "info", message, description, closable = false, className, classNames }) => {
3051
3459
  const [closed, setClosed] = react.useState(false);
3052
3460
  if (closed) {
@@ -3138,31 +3546,214 @@ var Panel = ({
3138
3546
  }
3139
3547
  );
3140
3548
  };
3549
+ var Toolbar = ({ children, start, end, wrapped = true, inset = false, className, classNames }) => /* @__PURE__ */ jsxRuntime.jsxs(
3550
+ "div",
3551
+ {
3552
+ className: tailwindMerge.twMerge(
3553
+ "flex items-center justify-between gap-3 rounded-(--ui-radius-lg) border border-(--ui-border)",
3554
+ neutralSurfaceClasses.subtle,
3555
+ wrapped && "flex-wrap",
3556
+ inset ? "px-3 py-2" : "px-4 py-3",
3557
+ className
3558
+ ),
3559
+ children: [
3560
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex min-w-0 flex-1 items-center gap-2", wrapped && "flex-wrap", classNames?.start), children: start ?? children }),
3561
+ end && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex items-center gap-2", wrapped && "flex-wrap justify-end", classNames?.end), children: end })
3562
+ ]
3563
+ }
3564
+ );
3565
+ var ActionBar = Toolbar;
3566
+ var SectionHeader = ({ title, subtitle, actions, className }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex items-start justify-between gap-4", className), children: [
3567
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
3568
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-(--ui-text-strong)", children: title }),
3569
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: tailwindMerge.twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle })
3570
+ ] }),
3571
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
3572
+ ] });
3573
+ var PageHeader = ({ title, subtitle, breadcrumbs, actions, extra, className }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-5", className), children: [
3574
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("mb-2 text-xs", neutralTextClasses.soft), children: breadcrumbs }),
3575
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
3576
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
3577
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-(--ui-text-strong)", children: title }),
3578
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: tailwindMerge.twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle })
3579
+ ] }),
3580
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
3581
+ ] }),
3582
+ extra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 border-t border-(--ui-border) pt-4", children: extra })
3583
+ ] });
3584
+ var AVATAR_COLORS = [
3585
+ "bg-blue-500",
3586
+ "bg-green-500",
3587
+ "bg-purple-500",
3588
+ "bg-orange-500",
3589
+ "bg-pink-500",
3590
+ "bg-teal-500",
3591
+ "bg-red-500",
3592
+ "bg-indigo-500"
3593
+ ];
3594
+ function colorFromString(str) {
3595
+ let hash = 0;
3596
+ for (let i = 0; i < str.length; i++) {
3597
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
3598
+ }
3599
+ return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
3600
+ }
3601
+ function getInitials(name) {
3602
+ const parts = name.trim().split(/\s+/);
3603
+ if (parts.length === 1) {
3604
+ return parts[0].slice(0, 2).toUpperCase();
3605
+ }
3606
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
3607
+ }
3608
+ var sizeClasses = {
3609
+ xs: "w-6 h-6 text-[10px]",
3610
+ sm: "w-7 h-7 text-xs",
3611
+ md: "w-8 h-8 text-sm",
3612
+ lg: "w-10 h-10 text-base",
3613
+ xl: "w-12 h-12 text-lg"
3614
+ };
3615
+ var Avatar = ({ size = "md", ...props }) => {
3616
+ const initials = props.name ? getInitials(props.name) : "?";
3617
+ const bgColor = props.color ?? (props.name ? colorFromString(props.name) : "bg-gray-400");
3618
+ if (props.src) {
3619
+ return /* @__PURE__ */ jsxRuntime.jsx(
3620
+ "img",
3621
+ {
3622
+ src: props.src,
3623
+ alt: props.name ?? "avatar",
3624
+ className: tailwindMerge.twMerge(
3625
+ "rounded-full object-cover shrink-0",
3626
+ sizeClasses[size],
3627
+ props.className
3628
+ )
3629
+ }
3630
+ );
3631
+ }
3632
+ return /* @__PURE__ */ jsxRuntime.jsx(
3633
+ "span",
3634
+ {
3635
+ title: props.name,
3636
+ className: tailwindMerge.twMerge(
3637
+ "inline-flex items-center justify-center rounded-full text-white font-medium shrink-0 select-none",
3638
+ sizeClasses[size],
3639
+ bgColor,
3640
+ props.className
3641
+ ),
3642
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: props.initialsClassName, children: initials })
3643
+ }
3644
+ );
3645
+ };
3646
+ var EntityHeader = ({ title, subtitle, avatarName, icon: Icon, meta, tags, actions, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-5", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
3647
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [
3648
+ avatarName ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { name: avatarName, size: "lg" }) : Icon ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-11 w-11 items-center justify-center rounded-(--ui-radius-lg) bg-(--ui-surface-subtle)", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 20, strokeWidth: 1.8, className: "text-(--ui-text)" }) }) : null,
3649
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
3650
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xl font-semibold text-(--ui-text-strong)", children: title }),
3651
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("mt-1 text-sm", neutralTextClasses.muted), children: subtitle }),
3652
+ (meta || tags) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
3653
+ meta,
3654
+ tags
3655
+ ] })
3656
+ ] })
3657
+ ] }),
3658
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
3659
+ ] }) });
3660
+ var alignClass3 = {
3661
+ left: "justify-start",
3662
+ center: "justify-center",
3663
+ right: "justify-end",
3664
+ between: "justify-between"
3665
+ };
3666
+ var FormActions = ({ children, align = "right", className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex flex-wrap items-center gap-2 border-t border-(--ui-border) pt-4", alignClass3[align], className), children });
3667
+ var FormSection = ({ title, description, actions, children, className }) => /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: tailwindMerge.twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4", className), children: [
3668
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 flex items-start justify-between gap-4", children: [
3669
+ /* @__PURE__ */ jsxRuntime.jsxs("legend", { className: "min-w-0", children: [
3670
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-(--ui-text-strong)", children: title }),
3671
+ description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("mt-1 text-xs", neutralTextClasses.soft), children: description })
3672
+ ] }),
3673
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: actions })
3674
+ ] }),
3675
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children })
3676
+ ] });
3677
+ var Fieldset = FormSection;
3678
+ var listVariantClass = {
3679
+ segmented: "inline-flex gap-0 rounded-(--ui-radius-lg) p-1",
3680
+ underline: "inline-flex gap-1 border-b border-(--ui-border-strong)",
3681
+ cards: "inline-flex gap-2"
3682
+ };
3683
+ var listSurfaceClass = {
3684
+ segmented: neutralSurfaceClasses.subtle,
3685
+ underline: "",
3686
+ cards: ""
3687
+ };
3688
+ var tabSizeClass = {
3689
+ small: "h-8 px-3 text-[12px]",
3690
+ middle: "h-9 px-4 text-[14px]",
3691
+ large: "h-10 px-5 text-[15px]"
3692
+ };
3693
+ var tabVariantClass = {
3694
+ segmented: "rounded-[calc(var(--ui-radius-lg)-4px)]",
3695
+ underline: "border-b-2 border-transparent rounded-none -mb-px",
3696
+ cards: "rounded-(--ui-radius-lg) border border-(--ui-border) bg-white shadow-sm"
3697
+ };
3698
+ var activeVariantClass = {
3699
+ segmented: "bg-white text-(--ui-text-strong) shadow-sm font-semibold",
3700
+ underline: "border-(--ui-primary) text-(--ui-text-strong) font-semibold",
3701
+ cards: "border-(--ui-border-focus) bg-(--ui-surface-subtle) text-(--ui-text-strong) font-semibold shadow-none"
3702
+ };
3703
+ var inactiveVariantClass = {
3704
+ segmented: "text-(--ui-text-muted) hover:text-(--ui-text)",
3705
+ underline: "text-(--ui-text-muted) hover:text-(--ui-text)",
3706
+ cards: "text-(--ui-text-muted) hover:border-(--ui-border-focus) hover:text-(--ui-text)"
3707
+ };
3141
3708
  var Tabs = ({
3142
3709
  block = true,
3710
+ variant = "segmented",
3711
+ size = "middle",
3143
3712
  ...props
3144
3713
  }) => /* @__PURE__ */ jsxRuntime.jsx(
3145
3714
  "div",
3146
3715
  {
3716
+ role: "tablist",
3147
3717
  className: tailwindMerge.twMerge(
3148
- "inline-flex gap-0 rounded-(--ui-radius-lg) p-1",
3149
- neutralSurfaceClasses.subtle,
3718
+ listVariantClass[variant],
3719
+ listSurfaceClass[variant],
3150
3720
  block && "flex w-full",
3151
3721
  props.className,
3152
3722
  props.classNames?.list
3153
3723
  ),
3154
- children: props.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
3724
+ children: props.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
3155
3725
  "button",
3156
3726
  {
3157
3727
  type: "button",
3158
- onClick: () => props.onChange(opt.value),
3728
+ role: "tab",
3729
+ "aria-selected": props.value === opt.value,
3730
+ disabled: opt.disabled,
3731
+ onClick: () => !opt.disabled && props.onChange(opt.value),
3159
3732
  className: tailwindMerge.twMerge(
3160
- "flex-1 h-9 px-4 text-[14px] rounded-[calc(var(--ui-radius-lg)-4px)] transition-all duration-150 cursor-pointer select-none whitespace-nowrap",
3161
- props.value === opt.value ? "bg-white text-(--ui-text-strong) shadow-sm font-semibold" : "text-(--ui-text-muted) hover:text-(--ui-text)",
3733
+ "flex-1 min-w-0 transition-all duration-150 cursor-pointer select-none whitespace-nowrap",
3734
+ "inline-flex items-center justify-center gap-2",
3735
+ tabSizeClass[size],
3736
+ tabVariantClass[variant],
3737
+ props.value === opt.value ? activeVariantClass[variant] : inactiveVariantClass[variant],
3738
+ opt.disabled && "cursor-not-allowed opacity-45 hover:border-(--ui-border) hover:text-(--ui-text-muted)",
3162
3739
  props.classNames?.tab,
3163
3740
  props.value === opt.value ? props.classNames?.activeTab : props.classNames?.inactiveTab
3164
3741
  ),
3165
- children: opt.label
3742
+ children: [
3743
+ opt.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("shrink-0", props.classNames?.icon), children: opt.icon }),
3744
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: opt.label }),
3745
+ opt.badge && /* @__PURE__ */ jsxRuntime.jsx(
3746
+ "span",
3747
+ {
3748
+ className: tailwindMerge.twMerge(
3749
+ "shrink-0 rounded-full px-2 py-0.5 text-[11px] leading-none",
3750
+ props.value === opt.value ? "bg-(--ui-primary) text-(--ui-primary-text)" : "bg-(--ui-surface-muted) text-(--ui-text-muted)",
3751
+ props.classNames?.badge
3752
+ ),
3753
+ children: opt.badge
3754
+ }
3755
+ )
3756
+ ]
3166
3757
  },
3167
3758
  opt.value
3168
3759
  ))
@@ -3244,68 +3835,6 @@ var FlagTag = ({ value, label, color = "geekblue", variant }) => {
3244
3835
  }
3245
3836
  return /* @__PURE__ */ jsxRuntime.jsx(Tag, { color, variant, children: label });
3246
3837
  };
3247
- var AVATAR_COLORS = [
3248
- "bg-blue-500",
3249
- "bg-green-500",
3250
- "bg-purple-500",
3251
- "bg-orange-500",
3252
- "bg-pink-500",
3253
- "bg-teal-500",
3254
- "bg-red-500",
3255
- "bg-indigo-500"
3256
- ];
3257
- function colorFromString(str) {
3258
- let hash = 0;
3259
- for (let i = 0; i < str.length; i++) {
3260
- hash = str.charCodeAt(i) + ((hash << 5) - hash);
3261
- }
3262
- return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
3263
- }
3264
- function getInitials(name) {
3265
- const parts = name.trim().split(/\s+/);
3266
- if (parts.length === 1) {
3267
- return parts[0].slice(0, 2).toUpperCase();
3268
- }
3269
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
3270
- }
3271
- var sizeClasses = {
3272
- xs: "w-6 h-6 text-[10px]",
3273
- sm: "w-7 h-7 text-xs",
3274
- md: "w-8 h-8 text-sm",
3275
- lg: "w-10 h-10 text-base",
3276
- xl: "w-12 h-12 text-lg"
3277
- };
3278
- var Avatar = ({ size = "md", ...props }) => {
3279
- const initials = props.name ? getInitials(props.name) : "?";
3280
- const bgColor = props.color ?? (props.name ? colorFromString(props.name) : "bg-gray-400");
3281
- if (props.src) {
3282
- return /* @__PURE__ */ jsxRuntime.jsx(
3283
- "img",
3284
- {
3285
- src: props.src,
3286
- alt: props.name ?? "avatar",
3287
- className: tailwindMerge.twMerge(
3288
- "rounded-full object-cover shrink-0",
3289
- sizeClasses[size],
3290
- props.className
3291
- )
3292
- }
3293
- );
3294
- }
3295
- return /* @__PURE__ */ jsxRuntime.jsx(
3296
- "span",
3297
- {
3298
- title: props.name,
3299
- className: tailwindMerge.twMerge(
3300
- "inline-flex items-center justify-center rounded-full text-white font-medium shrink-0 select-none",
3301
- sizeClasses[size],
3302
- bgColor,
3303
- props.className
3304
- ),
3305
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: props.initialsClassName, children: initials })
3306
- }
3307
- );
3308
- };
3309
3838
  var defaultToolbar = [
3310
3839
  "bold",
3311
3840
  "italic",
@@ -3979,6 +4508,88 @@ var useNotification = () => {
3979
4508
  info: (message, options) => add("info", message, options)
3980
4509
  };
3981
4510
  };
4511
+ var EmptyState = ({
4512
+ primaryActionText,
4513
+ onPrimaryAction,
4514
+ secondaryActionText,
4515
+ onSecondaryAction,
4516
+ extra,
4517
+ className,
4518
+ classNames,
4519
+ ...props
4520
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white", className), children: [
4521
+ /* @__PURE__ */ jsxRuntime.jsx(Empty, { className: "py-10", ...props }),
4522
+ (primaryActionText || secondaryActionText || extra) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex flex-wrap items-center justify-center gap-2 px-4 pb-6", classNames?.actions), children: [
4523
+ secondaryActionText && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "default", text: secondaryActionText, onClick: onSecondaryAction }),
4524
+ primaryActionText && /* @__PURE__ */ jsxRuntime.jsx(Button, { text: primaryActionText, onClick: onPrimaryAction }),
4525
+ extra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.extra, children: extra })
4526
+ ] })
4527
+ ] });
4528
+ var trendConfig = {
4529
+ up: {
4530
+ icon: iconsReact.IconArrowUpRight,
4531
+ className: "text-(--ui-success)"
4532
+ },
4533
+ down: {
4534
+ icon: iconsReact.IconArrowDownRight,
4535
+ className: "text-(--ui-danger)"
4536
+ },
4537
+ neutral: {
4538
+ icon: iconsReact.IconMinus,
4539
+ className: neutralTextClasses.soft
4540
+ }
4541
+ };
4542
+ var StatCard = ({ label, value, description, icon: Icon, trend, footer, className }) => {
4543
+ const trendDirection = trend?.direction ?? "neutral";
4544
+ const TrendIcon = trend ? trendConfig[trendDirection].icon : null;
4545
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4 shadow-sm", className), children: [
4546
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
4547
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
4548
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: tailwindMerge.twMerge("text-sm", neutralTextClasses.muted), children: label }),
4549
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-2xl font-semibold text-(--ui-text-strong)", children: value }),
4550
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: tailwindMerge.twMerge("mt-1 text-xs", neutralTextClasses.soft), children: description })
4551
+ ] }),
4552
+ Icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex h-10 w-10 items-center justify-center rounded-(--ui-radius-lg)", neutralSurfaceClasses.subtle), children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 18, strokeWidth: 1.75, className: neutralTextClasses.default }) })
4553
+ ] }),
4554
+ trend && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex items-center gap-2 text-sm", children: [
4555
+ TrendIcon && /* @__PURE__ */ jsxRuntime.jsx(TrendIcon, { size: 15, strokeWidth: 2, className: trendConfig[trendDirection].className }),
4556
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("font-medium", trendConfig[trendDirection].className), children: trend.value }),
4557
+ trend.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: neutralTextClasses.soft, children: trend.label })
4558
+ ] }),
4559
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 border-t border-(--ui-border) pt-3", children: footer })
4560
+ ] });
4561
+ };
4562
+ var DescriptionList = ({ items, columns = 2, className }) => /* @__PURE__ */ jsxRuntime.jsx(
4563
+ "div",
4564
+ {
4565
+ className: tailwindMerge.twMerge(
4566
+ "grid gap-x-6 gap-y-4 rounded-(--ui-radius-lg) border border-(--ui-border) bg-white p-4",
4567
+ columns === 1 && "grid-cols-1",
4568
+ columns === 2 && "grid-cols-1 md:grid-cols-2",
4569
+ columns === 3 && "grid-cols-1 md:grid-cols-3",
4570
+ className
4571
+ ),
4572
+ children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
4573
+ "div",
4574
+ {
4575
+ className: tailwindMerge.twMerge(
4576
+ "min-w-0",
4577
+ item.span === 2 && columns > 1 && "md:col-span-2",
4578
+ item.span === 3 && columns > 2 && "md:col-span-3"
4579
+ ),
4580
+ children: [
4581
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: tailwindMerge.twMerge("text-xs font-medium uppercase tracking-[0.08em]", neutralTextClasses.soft), children: item.label }),
4582
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "mt-1 text-sm text-(--ui-text)", children: item.value })
4583
+ ]
4584
+ },
4585
+ index
4586
+ ))
4587
+ }
4588
+ );
4589
+ var KeyValue = ({ label, value, className }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex items-start justify-between gap-4 border-b border-(--ui-border) py-2 last:border-b-0", className), children: [
4590
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("text-sm", neutralTextClasses.muted), children: label }),
4591
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-right text-sm text-(--ui-text)", children: value })
4592
+ ] });
3982
4593
  var Pretty = ({ data, className }) => /* @__PURE__ */ jsxRuntime.jsx(
3983
4594
  "pre",
3984
4595
  {
@@ -3989,6 +4600,10 @@ var Pretty = ({ data, className }) => /* @__PURE__ */ jsxRuntime.jsx(
3989
4600
  children: JSON.stringify(data, null, 2)
3990
4601
  }
3991
4602
  );
4603
+ var SkeletonTable = ({ rows = 5, columns = 4, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("overflow-hidden rounded-(--ui-radius-lg) border border-(--ui-border) bg-white", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse", children: [
4604
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("div", { className: "h-3 w-20 rounded bg-white/30" }, index)) }),
4605
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-(--ui-border)", children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("div", { className: "h-3 rounded bg-(--ui-surface-muted)" }, columnIndex)) }, rowIndex)) })
4606
+ ] }) });
3992
4607
  var GAP2 = 10;
3993
4608
  var VIEWPORT_MARGIN2 = 8;
3994
4609
  function calcPosition3(trigger, tooltip, placement) {
@@ -4143,6 +4758,47 @@ var Tooltip = ({
4143
4758
  )
4144
4759
  ] });
4145
4760
  };
4761
+ var Stepper = ({ items, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex flex-wrap gap-4", className), children: items.map((item, index) => {
4762
+ const status = item.status ?? "upcoming";
4763
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-40 flex-1 items-start gap-3", children: [
4764
+ /* @__PURE__ */ jsxRuntime.jsx(
4765
+ "div",
4766
+ {
4767
+ className: tailwindMerge.twMerge(
4768
+ "mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-xs font-semibold",
4769
+ status === "complete" && "border-(--ui-success) bg-(--ui-success) text-white",
4770
+ status === "current" && "border-(--ui-primary) bg-(--ui-primary) text-white",
4771
+ status === "upcoming" && "border-(--ui-border) bg-white text-(--ui-text-soft)"
4772
+ ),
4773
+ children: status === "complete" ? /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconCheck, { size: 14, strokeWidth: 2.5 }) : index + 1
4774
+ }
4775
+ ),
4776
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
4777
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("text-sm font-medium", status === "upcoming" ? neutralTextClasses.muted : "text-(--ui-text-strong)"), children: item.title }),
4778
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("mt-1 text-xs", neutralTextClasses.soft), children: item.description })
4779
+ ] })
4780
+ ] }, index);
4781
+ }) });
4782
+ var colorClass = {
4783
+ primary: "bg-(--ui-primary)",
4784
+ success: "bg-(--ui-success)",
4785
+ danger: "bg-(--ui-danger)",
4786
+ warning: "bg-(--ui-warning)",
4787
+ neutral: "bg-(--ui-border-strong)"
4788
+ };
4789
+ var Timeline = ({ items, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("space-y-4", className), children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex gap-3 pl-1", children: [
4790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center", children: [
4791
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("mt-1 h-2.5 w-2.5 rounded-full", colorClass[item.color ?? "primary"]) }),
4792
+ index < items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 h-full w-px bg-(--ui-border)" })
4793
+ ] }),
4794
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 pb-4", children: [
4795
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4796
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-(--ui-text-strong)", children: item.title }),
4797
+ item.time && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("text-xs", neutralTextClasses.soft), children: item.time })
4798
+ ] }),
4799
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("mt-1 text-sm", neutralTextClasses.muted), children: item.description })
4800
+ ] })
4801
+ ] }, index)) });
4146
4802
 
4147
4803
  // src/initUI.ts
4148
4804
  function initUI(config) {
@@ -4256,6 +4912,7 @@ function initUI(config) {
4256
4912
  r.style.setProperty("--ui-empty-compact-description", layout.empty.compactDescription);
4257
4913
  }
4258
4914
 
4915
+ exports.ActionBar = ActionBar;
4259
4916
  exports.ActiveTag = ActiveTag;
4260
4917
  exports.Alert = Alert;
4261
4918
  exports.Avatar = Avatar;
@@ -4263,14 +4920,19 @@ exports.Badge = Badge;
4263
4920
  exports.Button = Button;
4264
4921
  exports.CheckboxInput = CheckboxInput;
4265
4922
  exports.ColorInput = ColorInput;
4923
+ exports.ConfirmButton = ConfirmButton;
4266
4924
  exports.DateInput = DateInput;
4925
+ exports.DescriptionList = DescriptionList;
4267
4926
  exports.Drawer = Drawer;
4268
4927
  exports.DrawerContent = DrawerContent;
4269
4928
  exports.DrawerFooter = DrawerFooter;
4270
4929
  exports.DrawerTitle = DrawerTitle;
4271
4930
  exports.Dropdown = Dropdown;
4272
4931
  exports.Empty = Empty;
4932
+ exports.EmptyState = EmptyState;
4933
+ exports.EntityHeader = EntityHeader;
4273
4934
  exports.ErrorProvider = ErrorProvider;
4935
+ exports.Fieldset = Fieldset;
4274
4936
  exports.FilterCheckboxInput = FilterCheckboxInput;
4275
4937
  exports.FilterDateInput = FilterDateInput;
4276
4938
  exports.FilterDateRangePopover = FilterDateRangePopover;
@@ -4279,28 +4941,46 @@ exports.FilterSelectGroupPopover = FilterSelectGroupPopover;
4279
4941
  exports.FilterSelectInput = FilterSelectInput;
4280
4942
  exports.FilterTextInput = FilterTextInput;
4281
4943
  exports.FlagTag = FlagTag;
4944
+ exports.FormActions = FormActions;
4945
+ exports.FormSection = FormSection;
4282
4946
  exports.Grid = Grid;
4283
4947
  exports.GridFilters = GridFilters;
4284
4948
  exports.HtmlInput = HtmlInput;
4949
+ exports.InlineEdit = InlineEdit;
4285
4950
  exports.InputError = InputError;
4286
4951
  exports.InputField = InputField;
4287
4952
  exports.InputLabel = InputLabel;
4953
+ exports.KeyValue = KeyValue;
4954
+ exports.Modal = Modal;
4955
+ exports.ModalContent = ModalContent;
4956
+ exports.ModalFooter = ModalFooter;
4957
+ exports.ModalTitle = ModalTitle;
4288
4958
  exports.MultiSelectInput = MultiSelectInput;
4289
4959
  exports.NotificationProvider = NotificationProvider;
4290
4960
  exports.NumberInput = NumberInput;
4961
+ exports.PageHeader = PageHeader;
4291
4962
  exports.Panel = Panel;
4292
4963
  exports.Popconfirm = Popconfirm;
4293
4964
  exports.Pretty = Pretty;
4965
+ exports.RadioGroup = RadioGroup;
4966
+ exports.SearchInput = SearchInput;
4967
+ exports.SectionHeader = SectionHeader;
4294
4968
  exports.SelectInput = SelectInput;
4295
4969
  exports.ServerError = ServerError;
4296
4970
  exports.Skeleton = Skeleton;
4971
+ exports.SkeletonTable = SkeletonTable;
4297
4972
  exports.SortDirection = SortDirection;
4298
4973
  exports.Spinner = Spinner;
4974
+ exports.StatCard = StatCard;
4975
+ exports.Stepper = Stepper;
4299
4976
  exports.SwitchInput = SwitchInput;
4300
4977
  exports.Table = Table;
4301
4978
  exports.Tabs = Tabs;
4302
4979
  exports.Tag = Tag;
4303
4980
  exports.TextInput = TextInput;
4981
+ exports.Textarea = Textarea;
4982
+ exports.Timeline = Timeline;
4983
+ exports.Toolbar = Toolbar;
4304
4984
  exports.Tooltip = Tooltip;
4305
4985
  exports.UploadInput = UploadInput;
4306
4986
  exports.UploadProvider = UploadProvider;
@@ -4311,6 +4991,7 @@ exports.registerIcons = registerIcons;
4311
4991
  exports.uiTheme = uiTheme;
4312
4992
  exports.useDrawer = useDrawer;
4313
4993
  exports.useGrid = useGrid;
4994
+ exports.useModal = useModal;
4314
4995
  exports.useNotification = useNotification;
4315
4996
  exports.useUploadConfig = useUploadConfig;
4316
4997
  //# sourceMappingURL=index.cjs.map