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