@lindle/linoardo 1.0.21 → 1.0.23

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
@@ -182,6 +182,7 @@ var Button = React3__namespace.forwardRef(
182
182
  children,
183
183
  disabled,
184
184
  onClick,
185
+ type,
185
186
  as,
186
187
  ...rest
187
188
  }, ref) => {
@@ -192,7 +193,7 @@ var Button = React3__namespace.forwardRef(
192
193
  const blockClass = block ? "w-full" : null;
193
194
  const isNativeButton = Component === "button";
194
195
  const isDisabled = disabled || loading;
195
- const cursor = onClick && !isDisabled ? "cursor-pointer" : "cursor-default";
196
+ const cursor = (onClick || type === "submit") && !isDisabled ? "cursor-pointer" : "cursor-default";
196
197
  const resolvedIconClass = resolveIconClassName(icon);
197
198
  const shouldRenderIcon = Boolean(resolvedIconClass && !loading);
198
199
  const isLoadingTextProvided = loadingText !== void 0 && loadingText !== null;
@@ -1564,6 +1565,45 @@ function hasNestedChildren(element) {
1564
1565
  const props = element.props;
1565
1566
  return "children" in props;
1566
1567
  }
1568
+ var blockBase = "block-base relative overflow-hidden text-gray-900 dark:text-slate-100";
1569
+ var blurClasses = {
1570
+ none: "backdrop-blur-none",
1571
+ sm: "backdrop-blur-sm",
1572
+ base: "backdrop-blur",
1573
+ md: "backdrop-blur-md",
1574
+ lg: "backdrop-blur-lg",
1575
+ xl: "backdrop-blur-xl",
1576
+ "2xl": "backdrop-blur-2xl",
1577
+ "3xl": "backdrop-blur-3xl"
1578
+ };
1579
+ var variantClasses2 = {
1580
+ solid: "rounded-xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
1581
+ outline: "rounded-xl bg-white/10 backdrop-opacity-5 border border-white/60 dark:bg-slate-900/30 dark:border-white/20",
1582
+ text: "rounded-xl bg-transparent border border-transparent",
1583
+ ghost: "rounded-xl bg-white/20 backdrop-opacity-5 border border-white/20 dark:bg-slate-900/30 dark:border-white/10",
1584
+ filled: "rounded-xl bg-white/60 backdrop-opacity-5 border border-white/40 dark:bg-slate-900/70 dark:border-white/15",
1585
+ underlined: "rounded-xl bg-white/20 backdrop-opacity-5 border-b border-white/40 dark:bg-slate-900/30 dark:border-white/20",
1586
+ rounded: "rounded-3xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
1587
+ sharp: "rounded-none bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10"
1588
+ };
1589
+ var Block = React3__namespace.forwardRef(function Block2({ className, variant = "solid", blur = "sm", interactive = false, children, ...rest }, ref) {
1590
+ const variantClass = variantClasses2[variant] ?? variantClasses2.solid;
1591
+ const blurClass = blurClasses[blur] ?? blurClasses.sm;
1592
+ const interactiveClass = interactive ? "transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900" : void 0;
1593
+ const tabIndexValue = interactive && rest.tabIndex === void 0 ? 0 : rest.tabIndex;
1594
+ return /* @__PURE__ */ jsxRuntime.jsx(
1595
+ "div",
1596
+ {
1597
+ ...rest,
1598
+ ref,
1599
+ tabIndex: tabIndexValue,
1600
+ className: tailwindMerge.twMerge(blockBase, variantClass, blurClass, "p-2", interactiveClass, className),
1601
+ children
1602
+ }
1603
+ );
1604
+ });
1605
+ Block.displayName = "Block";
1606
+ var Block_default = Block;
1567
1607
  var masonryBaseClass = "masonry-grid w-full";
1568
1608
  var itemBaseClass = "masonry-item block break-inside-avoid";
1569
1609
  var MasonryBase = (props, ref) => {
@@ -1649,6 +1689,143 @@ function resolveItemContent(item, index, renderItem) {
1649
1689
  }
1650
1690
  return item;
1651
1691
  }
1692
+ var positionClasses = {
1693
+ fixed: "fixed inset-x-0 top-0",
1694
+ absolute: "absolute inset-x-0 top-0",
1695
+ sticky: "sticky inset-x-0 top-0",
1696
+ static: "static",
1697
+ relative: "relative"
1698
+ };
1699
+ var colorClasses = {
1700
+ primary: "bg-primary text-white",
1701
+ surface: "bg-white text-gray-900 border-b border-gray-200",
1702
+ muted: "bg-gray-50 text-gray-900 border-b border-gray-200",
1703
+ dark: "bg-gray-900 text-white",
1704
+ transparent: "bg-transparent text-inherit"
1705
+ };
1706
+ var AppBar = ({
1707
+ title,
1708
+ logo,
1709
+ logoAlt = "Logo",
1710
+ brandHref,
1711
+ navigation = [],
1712
+ actions,
1713
+ position = "static",
1714
+ color = "surface",
1715
+ dense = false,
1716
+ elevated = true,
1717
+ contained = true,
1718
+ titlePosition = "start",
1719
+ className,
1720
+ children,
1721
+ ...rest
1722
+ }) => {
1723
+ const [mobileOpen, setMobileOpen] = React3__namespace.useState(false);
1724
+ const isDark = color === "primary" || color === "dark";
1725
+ const isTransparent = color === "transparent";
1726
+ const barClass = tailwindMerge.twMerge(
1727
+ "app-bar z-40 w-full backdrop-blur-md",
1728
+ positionClasses[position] ?? positionClasses.static,
1729
+ colorClasses[color] ?? colorClasses.surface,
1730
+ elevated && !isTransparent ? "shadow-sm shadow-black/10" : void 0,
1731
+ "relative",
1732
+ className
1733
+ );
1734
+ const innerClass = tailwindMerge.twMerge(
1735
+ "mx-auto flex w-full items-center gap-4",
1736
+ contained ? "max-w-6xl px-4 sm:px-6 lg:px-8" : "px-4",
1737
+ dense ? "py-2.5" : "py-4"
1738
+ );
1739
+ const brandTextClass = isDark ? "text-white" : "text-gray-900";
1740
+ const navBaseClass = tailwindMerge.twMerge(
1741
+ "inline-flex items-center gap-2 rounded-xl px-3 py-2 text-sm font-medium transition focus-visible:outline-none",
1742
+ isDark ? "hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/70" : "hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
1743
+ );
1744
+ const navActiveClass = isDark ? "bg-white/15 text-white" : "bg-primary/10 text-primary";
1745
+ const renderNavItem = (item, index) => {
1746
+ const { href, label, active, onClick } = item;
1747
+ const Component = href ? "a" : "button";
1748
+ const resolvedHref = href && href.trim().length > 0 ? href : void 0;
1749
+ return /* @__PURE__ */ jsxRuntime.jsx(
1750
+ Component,
1751
+ {
1752
+ href: resolvedHref,
1753
+ onClick,
1754
+ className: tailwindMerge.twMerge(navBaseClass, active ? navActiveClass : void 0),
1755
+ "aria-current": active ? "page" : void 0,
1756
+ children: label
1757
+ },
1758
+ `${resolvedHref ?? "item"}-${index}`
1759
+ );
1760
+ };
1761
+ const brandAlignClass = titlePosition === "center" ? "justify-self-center text-center" : titlePosition === "end" ? "justify-self-end text-right" : "justify-self-start";
1762
+ const brandNode = title || logo ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex min-w-0 items-center gap-3", brandAlignClass), children: [
1763
+ logo ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-white/10 ring-1 ring-black/5", children: /* @__PURE__ */ jsxRuntime.jsx(
1764
+ "img",
1765
+ {
1766
+ src: logo,
1767
+ alt: logoAlt,
1768
+ className: "h-full w-full object-cover",
1769
+ loading: "lazy",
1770
+ decoding: "async"
1771
+ }
1772
+ ) }) : null,
1773
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("text-base font-semibold leading-tight", brandTextClass), children: brandHref ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: brandHref, className: "hover:underline focus-visible:outline-none", children: title }) : title }) : null })
1774
+ ] }) : null;
1775
+ return /* @__PURE__ */ jsxRuntime.jsxs("header", { ...rest, className: barClass, children: [
1776
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: innerClass, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full grid-cols-[auto_1fr_auto] items-center gap-3", children: [
1777
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1778
+ navigation.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1779
+ "button",
1780
+ {
1781
+ type: "button",
1782
+ "aria-label": "Otev\u0159\xEDt navigaci",
1783
+ className: tailwindMerge.twMerge(
1784
+ "inline-flex h-10 w-10 items-center justify-center rounded-xl text-xl sm:hidden",
1785
+ isDark ? "text-white hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/60" : "text-gray-700 hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
1786
+ ),
1787
+ "aria-expanded": mobileOpen,
1788
+ onClick: () => setMobileOpen((open) => !open),
1789
+ children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: mobileOpen ? "mdi mdi-close" : "mdi mdi-menu", "aria-hidden": true })
1790
+ }
1791
+ ) : null,
1792
+ navigation.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "hidden items-center gap-1 sm:flex", "aria-label": "Hlavni navigace", children: navigation.map(renderNavItem) }) : null
1793
+ ] }),
1794
+ brandNode,
1795
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center justify-end gap-2", children: [
1796
+ children,
1797
+ actions
1798
+ ] })
1799
+ ] }) }),
1800
+ navigation.length > 0 && mobileOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "absolute inset-x-0 top-full border-t border-gray-200/70 bg-white/95 p-3 shadow-lg shadow-gray-900/5 backdrop-blur-md", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", "aria-label": "Mobilni navigace", children: navigation.map((item, index) => {
1801
+ const { href, label, active, onClick } = item;
1802
+ const Component = href ? "a" : "button";
1803
+ const resolvedHref = href && href.trim().length > 0 ? href : void 0;
1804
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1805
+ Component,
1806
+ {
1807
+ href: resolvedHref,
1808
+ onClick: (event) => {
1809
+ onClick?.(event);
1810
+ setMobileOpen(false);
1811
+ },
1812
+ className: tailwindMerge.twMerge(
1813
+ "flex items-center justify-between rounded-xl px-3 py-2 text-sm font-medium transition",
1814
+ active ? "bg-primary/10 text-primary" : "text-gray-800 hover:bg-gray-100"
1815
+ ),
1816
+ "aria-current": active ? "page" : void 0,
1817
+ children: [
1818
+ label,
1819
+ active ? /* @__PURE__ */ jsxRuntime.jsx("i", { className: "mdi mdi-circle-small text-primary", "aria-hidden": true }) : null
1820
+ ]
1821
+ },
1822
+ `${resolvedHref ?? "mobile-item"}-${index}`
1823
+ );
1824
+ }) }) }) }) : null
1825
+ ] });
1826
+ };
1827
+ AppBar.displayName = "AppBar";
1828
+ var AppBar_default = AppBar;
1652
1829
  var containerVariants = {
1653
1830
  solid: "bg-gradient-to-br from-primary via-primary/90 to-indigo-600 text-white shadow-2xl shadow-primary/30",
1654
1831
  outline: "border border-gray-200 bg-white text-gray-900",
@@ -1990,7 +2167,7 @@ var Input = ({
1990
2167
  const hidePlaceholderUntilFocus = hasLabel && hasProvidedPlaceholder;
1991
2168
  const [isFocused, setIsFocused] = React3__namespace.default.useState(false);
1992
2169
  const classBase = "input-base focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed w-full text-gray-900 dark:text-gray-100 placeholder:text-gray-500 dark:placeholder:text-gray-400";
1993
- const variantClasses3 = {
2170
+ const variantClasses4 = {
1994
2171
  solid: "rounded border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40",
1995
2172
  sharp: "rounded-none border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40",
1996
2173
  outline: "rounded border-2 border-black bg-white focus-visible:border-black focus-visible:ring-2 focus-visible:ring-black/30 dark:border-black dark:bg-transparent dark:focus-visible:border-black dark:focus-visible:ring-black/40",
@@ -2026,7 +2203,7 @@ var Input = ({
2026
2203
  warn: "text-amber-600 dark:text-amber-300",
2027
2204
  success: "text-emerald-600 dark:text-emerald-300"
2028
2205
  };
2029
- const variantClass = variantClasses3[variant] ?? variantClasses3.outline;
2206
+ const variantClass = variantClasses4[variant] ?? variantClasses4.outline;
2030
2207
  const toneClass = status ? statusClasses[status.tone] : void 0;
2031
2208
  let prependIconClass = resolveIconClassName3(icon);
2032
2209
  const sizeConfig = sizeClasses4[size] ?? sizeClasses4.medium;
@@ -2116,7 +2293,7 @@ function generateString(length = 5) {
2116
2293
  return result;
2117
2294
  }
2118
2295
  var baseClass = "select-base w-full appearance-none focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed bg-white text-gray-900 placeholder:text-gray-500 dark:bg-slate-900 dark:text-gray-100 dark:placeholder:text-gray-400";
2119
- var variantClasses2 = {
2296
+ var variantClasses3 = {
2120
2297
  solid: "rounded border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40",
2121
2298
  sharp: "rounded-none border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40",
2122
2299
  outline: "rounded border-2 border-black bg-white focus-visible:border-black focus-visible:ring-2 focus-visible:ring-black/30 dark:border-black dark:bg-transparent dark:focus-visible:border-black dark:focus-visible:ring-black/40",
@@ -2159,7 +2336,7 @@ var Select = ({
2159
2336
  }) => {
2160
2337
  const selectId = id || name || generateString();
2161
2338
  const selectName = name || selectId;
2162
- const variantClass = variantClasses2[variant] ?? variantClasses2.outline;
2339
+ const variantClass = variantClasses3[variant] ?? variantClasses3.outline;
2163
2340
  const sizeConfig = sizeClasses2[size] ?? sizeClasses2.medium;
2164
2341
  const sizeClass = `${sizeConfig.padding} ${sizeConfig.text}`;
2165
2342
  const normalizedOptions = options.map(normalizeOption);
@@ -2540,7 +2717,7 @@ var sizeClasses3 = {
2540
2717
  large: "text-lg",
2541
2718
  "x-large": "text-2xl"
2542
2719
  };
2543
- var colorClasses = {
2720
+ var colorClasses2 = {
2544
2721
  primary: "text-primary",
2545
2722
  neutral: "text-gray-700",
2546
2723
  info: "text-sky-600",
@@ -2572,11 +2749,522 @@ var Icon = ({ className, icon, size, color, ...rest }) => {
2572
2749
  }
2573
2750
  const classBase = "mdi";
2574
2751
  const sizeClass = size ? sizeClasses3[size] ?? sizeClasses3.medium : void 0;
2575
- const colorClass = color ? colorClasses[color] ?? colorClasses.primary : void 0;
2752
+ const colorClass = color ? colorClasses2[color] ?? colorClasses2.primary : void 0;
2576
2753
  return /* @__PURE__ */ jsxRuntime.jsx("i", { ...rest, className: tailwindMerge.twMerge(classBase, iconValue, sizeClass, colorClass, className) });
2577
2754
  };
2578
2755
  var Icon_default = Icon;
2756
+ var placementClasses3 = {
2757
+ topLeft: "top-4 left-4 items-start",
2758
+ topRight: "top-4 right-4 items-end",
2759
+ bottomLeft: "bottom-4 left-4 items-start",
2760
+ bottomRight: "bottom-4 right-4 items-end"
2761
+ };
2762
+ var typeIconMap = {
2763
+ info: "mdi-information-outline",
2764
+ success: "mdi-check-circle-outline",
2765
+ warning: "mdi-alert-outline",
2766
+ error: "mdi-close-circle-outline"
2767
+ };
2768
+ var typeAccentMap = {
2769
+ info: "bg-sky-50 text-sky-600",
2770
+ success: "bg-emerald-50 text-emerald-600",
2771
+ warning: "bg-amber-50 text-amber-700",
2772
+ error: "bg-red-50 text-red-600"
2773
+ };
2774
+ var typeTone = {
2775
+ info: {
2776
+ bg: "bg-sky-50",
2777
+ text: "text-sky-900",
2778
+ border: "border-sky-200",
2779
+ iconBg: "bg-sky-100",
2780
+ iconText: "text-sky-600"
2781
+ },
2782
+ success: {
2783
+ bg: "bg-emerald-50",
2784
+ text: "text-emerald-900",
2785
+ border: "border-emerald-200",
2786
+ iconBg: "bg-emerald-100",
2787
+ iconText: "text-emerald-600"
2788
+ },
2789
+ warning: {
2790
+ bg: "bg-amber-50",
2791
+ text: "text-amber-900",
2792
+ border: "border-amber-200",
2793
+ iconBg: "bg-amber-100",
2794
+ iconText: "text-amber-700"
2795
+ },
2796
+ error: {
2797
+ bg: "bg-red-50",
2798
+ text: "text-red-900",
2799
+ border: "border-red-200",
2800
+ iconBg: "bg-red-100",
2801
+ iconText: "text-red-600"
2802
+ }
2803
+ };
2804
+ var resolveVariantClass3 = (variant, type) => {
2805
+ const tone = type ? typeTone[type] : void 0;
2806
+ switch (variant) {
2807
+ case "filled":
2808
+ return tailwindMerge.twMerge(
2809
+ tone?.bg ?? "bg-primary/10",
2810
+ tone?.text ?? "text-primary",
2811
+ "border border-transparent shadow-none"
2812
+ );
2813
+ case "outline":
2814
+ return tailwindMerge.twMerge(
2815
+ "bg-white/90",
2816
+ tone?.text ?? "text-gray-900",
2817
+ tone?.border ?? "border-primary/20",
2818
+ "border-[1.5px]"
2819
+ );
2820
+ case "ghost":
2821
+ return tailwindMerge.twMerge(
2822
+ "bg-transparent shadow-none border border-transparent",
2823
+ tone?.text ?? "text-gray-900"
2824
+ );
2825
+ case "solid":
2826
+ default:
2827
+ return "bg-white/95 text-gray-900 border border-gray-200";
2828
+ }
2829
+ };
2830
+ var resolveIconClassName4 = (icon) => {
2831
+ if (!icon) return void 0;
2832
+ if (typeof icon === "string") {
2833
+ const trimmed = icon.trim();
2834
+ if (!trimmed) return void 0;
2835
+ if (trimmed.includes(" ")) return trimmed;
2836
+ const normalized2 = trimmed.startsWith("mdi-") ? trimmed : `mdi-${trimmed}`;
2837
+ return `mdi ${normalized2}`;
2838
+ }
2839
+ const [library, iconName] = icon;
2840
+ const normalized = iconName?.startsWith("mdi-") ? iconName : `mdi-${iconName}`;
2841
+ return `mdi ${library} ${normalized}`.trim();
2842
+ };
2843
+ var resolveIconNode = (icon, fallbackClassName) => {
2844
+ if (React3__namespace.isValidElement(icon)) return icon;
2845
+ const iconClassName = resolveIconClassName4(icon) ?? fallbackClassName;
2846
+ if (!iconClassName) return null;
2847
+ const hasBase = iconClassName.split(" ").some((token) => token.trim() === "mdi");
2848
+ const hasGlyph = iconClassName.includes("mdi-");
2849
+ const finalClassName = hasBase && hasGlyph ? iconClassName : `mdi ${iconClassName}`.trim();
2850
+ return /* @__PURE__ */ jsxRuntime.jsx("i", { className: finalClassName, "aria-hidden": true });
2851
+ };
2852
+ var NotificationCard = ({ item }) => {
2853
+ const {
2854
+ key,
2855
+ message,
2856
+ description,
2857
+ icon,
2858
+ closeIcon,
2859
+ closable = true,
2860
+ btn,
2861
+ onClick,
2862
+ className,
2863
+ style,
2864
+ role = "status",
2865
+ type,
2866
+ variant = "solid",
2867
+ ...rest
2868
+ } = item;
2869
+ const hasMessage = message !== void 0 && message !== null;
2870
+ const hasDescription = description !== void 0 && description !== null;
2871
+ const hasContent = hasMessage || hasDescription;
2872
+ const accentClass = type ? typeAccentMap[type] : void 0;
2873
+ const iconNode = resolveIconNode(icon, type ? `mdi ${typeIconMap[type]}` : void 0);
2874
+ const closeIconNode = resolveIconNode(closeIcon, "mdi mdi-close");
2875
+ const variantClass = resolveVariantClass3(variant, type);
2876
+ const toneIconBg = type ? typeTone[type]?.iconBg : void 0;
2877
+ const toneIconText = type ? typeTone[type]?.iconText : void 0;
2878
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2879
+ "article",
2880
+ {
2881
+ ...rest,
2882
+ role,
2883
+ className: tailwindMerge.twMerge(
2884
+ "pointer-events-auto flex w-88 max-w-[calc(100vw-2.5rem)] gap-3 rounded-2xl p-4 shadow-xl ring-1 ring-black/5 backdrop-blur-sm transition hover:-translate-y-0.5 hover:shadow-2xl focus:outline-none",
2885
+ "dark:border-gray-800 dark:bg-gray-900/95 dark:text-gray-50 dark:ring-white/5",
2886
+ variantClass,
2887
+ className
2888
+ ),
2889
+ style,
2890
+ onClick,
2891
+ children: [
2892
+ iconNode ? /* @__PURE__ */ jsxRuntime.jsx(
2893
+ "div",
2894
+ {
2895
+ className: tailwindMerge.twMerge(
2896
+ "mt-0.5 flex h-10 w-10 shrink-0 items-center justify-center rounded-xl text-xl",
2897
+ toneIconBg ?? accentClass ?? "bg-primary/10",
2898
+ toneIconText ?? "text-primary"
2899
+ ),
2900
+ children: iconNode
2901
+ }
2902
+ ) : null,
2903
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
2904
+ hasContent ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
2905
+ hasMessage ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[15px] font-semibold leading-5 text-gray-900 dark:text-white", children: message }) : null,
2906
+ hasDescription ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm leading-6 text-gray-600 dark:text-gray-300", children: description }) : null
2907
+ ] }) : null,
2908
+ btn ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1 text-sm", children: btn }) : null
2909
+ ] }),
2910
+ closable ? /* @__PURE__ */ jsxRuntime.jsx(
2911
+ "button",
2912
+ {
2913
+ type: "button",
2914
+ "aria-label": "Zav\u0159\xEDt upozorn\u011Bn\xED",
2915
+ className: "-mr-1 -mt-1 h-8 w-8 shrink-0 rounded-full text-gray-500 transition hover:bg-gray-100 hover:text-gray-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-white",
2916
+ onClick: (event) => {
2917
+ event.stopPropagation();
2918
+ item.onClose?.();
2919
+ },
2920
+ children: closeIconNode
2921
+ }
2922
+ ) : null
2923
+ ]
2924
+ }
2925
+ );
2926
+ };
2927
+ var Notification = ({
2928
+ items = [],
2929
+ placement = "topRight",
2930
+ gap = 12,
2931
+ containerClassName,
2932
+ className,
2933
+ ...rest
2934
+ }) => {
2935
+ if (!items.length) return null;
2936
+ const grouped = /* @__PURE__ */ new Map();
2937
+ items.forEach((item) => {
2938
+ const resolvedKey = item.key ?? `notification-${item.message ?? Math.random()}`;
2939
+ const resolvedPlacement = item.placement ?? placement;
2940
+ const group = grouped.get(resolvedPlacement) ?? [];
2941
+ group.push({ ...item, key: resolvedKey });
2942
+ grouped.set(resolvedPlacement, group);
2943
+ });
2944
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from(grouped.entries()).map(([groupPlacement, groupItems]) => /* @__PURE__ */ jsxRuntime.jsx(
2945
+ "div",
2946
+ {
2947
+ className: tailwindMerge.twMerge(
2948
+ "pointer-events-none fixed z-70 flex w-full max-w-[24rem] flex-col",
2949
+ placementClasses3[groupPlacement],
2950
+ containerClassName,
2951
+ className
2952
+ ),
2953
+ style: { gap: `${gap}px` },
2954
+ ...rest,
2955
+ children: groupItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(NotificationCard, { item }, item.key))
2956
+ },
2957
+ groupPlacement
2958
+ )) });
2959
+ };
2960
+ var Notification_default = Notification;
2961
+ var clampPercent = (value) => {
2962
+ if (value === void 0 || value === null || Number.isNaN(value)) {
2963
+ return 0;
2964
+ }
2965
+ return Math.min(100, Math.max(0, value));
2966
+ };
2967
+ var statusIconMap = {
2968
+ success: "mdi mdi-check",
2969
+ exception: "mdi mdi-alert"
2970
+ };
2971
+ var strokeColorByStatus = {
2972
+ normal: "rgb(99 102 241)",
2973
+ active: "rgb(99 102 241)",
2974
+ success: "rgb(16 185 129)",
2975
+ exception: "rgb(239 68 68)"
2976
+ };
2977
+ var trailColorDefault = "rgb(229 231 235)";
2978
+ var resolveStroke = (status, strokeColor, gradientId) => {
2979
+ if (!strokeColor) {
2980
+ return { color: strokeColorByStatus[status] };
2981
+ }
2982
+ if (typeof strokeColor === "string") {
2983
+ return { color: strokeColor };
2984
+ }
2985
+ const id = gradientId ?? `progress-gradient-${Math.random().toString(16).slice(2)}`;
2986
+ return {
2987
+ color: `url(#${id})`,
2988
+ gradient: { id, from: strokeColor.from, to: strokeColor.to },
2989
+ cssGradient: `linear-gradient(90deg, ${strokeColor.from}, ${strokeColor.to})`
2990
+ };
2991
+ };
2992
+ var resolveRotation = (gapPosition) => {
2993
+ switch (gapPosition) {
2994
+ case "bottom":
2995
+ return 90;
2996
+ case "left":
2997
+ return 180;
2998
+ case "right":
2999
+ return 0;
3000
+ case "top":
3001
+ default:
3002
+ return -90;
3003
+ }
3004
+ };
3005
+ var buildGradientId = (strokeColor) => {
3006
+ if (strokeColor && typeof strokeColor !== "string") {
3007
+ const from = strokeColor.from.replace(/\W+/g, "");
3008
+ const to = strokeColor.to.replace(/\W+/g, "");
3009
+ return `progress-gradient-${from}-${to}`;
3010
+ }
3011
+ return void 0;
3012
+ };
3013
+ var InfoNode = ({ status, percent, successPercent, format }) => {
3014
+ const iconClass = status === "success" || status === "exception" ? statusIconMap[status] : void 0;
3015
+ const content = typeof format === "function" ? format(percent, successPercent) : iconClass ? /* @__PURE__ */ jsxRuntime.jsx("i", { className: iconClass, "aria-hidden": true }) : `${Math.round(percent)}%`;
3016
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-200", children: content });
3017
+ };
3018
+ var renderSteps = (percent, steps, status, strokeStyle, trailColor, height) => {
3019
+ const filled = Math.round(percent / 100 * steps);
3020
+ const stepStyle = height ? { height } : {};
3021
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full items-center gap-1", style: stepStyle, children: Array.from({ length: steps }).map((_, idx) => {
3022
+ const isFilled = idx < filled;
3023
+ const resolvedStyle = {
3024
+ ...isFilled ? strokeStyle : { backgroundColor: trailColor ?? trailColorDefault },
3025
+ height
3026
+ };
3027
+ return /* @__PURE__ */ jsxRuntime.jsx(
3028
+ "span",
3029
+ {
3030
+ className: tailwindMerge.twMerge(
3031
+ "flex-1 rounded-full",
3032
+ isFilled ? void 0 : "bg-gray-200 dark:bg-gray-800",
3033
+ status === "active" && isFilled ? "animate-pulse" : void 0
3034
+ ),
3035
+ style: resolvedStyle
3036
+ },
3037
+ idx
3038
+ );
3039
+ }) });
3040
+ };
3041
+ var LineProgress = ({
3042
+ percent,
3043
+ status,
3044
+ successPercent,
3045
+ format,
3046
+ showInfo = true,
3047
+ strokeWidth,
3048
+ trailColor,
3049
+ strokeColor,
3050
+ success,
3051
+ size = "default",
3052
+ steps,
3053
+ className,
3054
+ style,
3055
+ ...rest
3056
+ }) => {
3057
+ const height = strokeWidth ?? (size === "small" ? 6 : size === "large" ? 12 : 8);
3058
+ const gradientId = buildGradientId(strokeColor);
3059
+ const { color, gradient, cssGradient } = resolveStroke(status, strokeColor, gradientId);
3060
+ const stepStrokeStyle = gradient ? { backgroundImage: cssGradient } : { backgroundColor: color };
3061
+ const lineStyle = {
3062
+ height,
3063
+ backgroundColor: trailColor ?? trailColorDefault
3064
+ };
3065
+ const barStyle = {
3066
+ width: `${percent}%`,
3067
+ height,
3068
+ backgroundColor: color,
3069
+ background: gradient ? cssGradient : color
3070
+ };
3071
+ const successWidth = successPercent ? Math.min(successPercent, percent) : 0;
3072
+ const successColor = success?.strokeColor ?? "rgb(16 185 129)";
3073
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex w-full items-center gap-3", className), style, ...rest, children: [
3074
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full overflow-hidden rounded-full", style: lineStyle, children: typeof steps === "number" && steps > 1 ? renderSteps(percent, steps, status, stepStrokeStyle, trailColor, height) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3075
+ /* @__PURE__ */ jsxRuntime.jsx(
3076
+ "div",
3077
+ {
3078
+ className: tailwindMerge.twMerge(
3079
+ "h-full rounded-full transition-[width] duration-300 ease-out",
3080
+ status === "active" ? "animate-pulse" : void 0
3081
+ ),
3082
+ style: barStyle
3083
+ }
3084
+ ),
3085
+ successWidth > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3086
+ "div",
3087
+ {
3088
+ className: "absolute inset-y-0 left-0 rounded-full transition-[width] duration-300 ease-out",
3089
+ style: { width: `${successWidth}%`, height, backgroundColor: successColor }
3090
+ }
3091
+ ) : null
3092
+ ] }) }),
3093
+ showInfo ? /* @__PURE__ */ jsxRuntime.jsx(InfoNode, { status, percent, successPercent, format }) : null
3094
+ ] });
3095
+ };
3096
+ var CircleProgress = ({
3097
+ percent,
3098
+ status,
3099
+ successPercent,
3100
+ format,
3101
+ showInfo = true,
3102
+ strokeWidth,
3103
+ trailColor,
3104
+ strokeColor,
3105
+ success,
3106
+ width = 120,
3107
+ type,
3108
+ gapDegree,
3109
+ gapPosition = "top",
3110
+ className,
3111
+ style,
3112
+ ...rest
3113
+ }) => {
3114
+ const stroke = strokeWidth ?? 10;
3115
+ const radius = (width - stroke) / 2;
3116
+ const circumference = 2 * Math.PI * radius;
3117
+ const gap = type === "dashboard" ? gapDegree ?? 75 : gapDegree ?? 0;
3118
+ const perimeter = circumference - gap / 360 * circumference;
3119
+ const dashOffsetBase = gap / 360 * circumference / 2;
3120
+ const dashArray = `${perimeter} ${circumference}`;
3121
+ const gradientId = buildGradientId(strokeColor);
3122
+ const { color, gradient } = resolveStroke(status, strokeColor, gradientId);
3123
+ const rotation = resolveRotation(gapPosition);
3124
+ const successColor = success?.strokeColor ?? "rgb(16 185 129)";
3125
+ const progressDashOffset = (100 - percent) / 100 * perimeter + dashOffsetBase;
3126
+ const successDashOffset = (100 - successPercent) / 100 * perimeter + dashOffsetBase;
3127
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("inline-flex flex-col items-center justify-center", className), style, ...rest, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", style: { width, height: width }, children: [
3128
+ /* @__PURE__ */ jsxRuntime.jsxs(
3129
+ "svg",
3130
+ {
3131
+ width,
3132
+ height: width,
3133
+ viewBox: `0 0 ${width} ${width}`,
3134
+ className: "absolute inset-0 overflow-visible",
3135
+ style: { transform: `rotate(${rotation}deg)` },
3136
+ children: [
3137
+ gradient ? /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradient.id, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
3138
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: gradient.from }),
3139
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: gradient.to })
3140
+ ] }) }) : null,
3141
+ /* @__PURE__ */ jsxRuntime.jsx(
3142
+ "circle",
3143
+ {
3144
+ cx: width / 2,
3145
+ cy: width / 2,
3146
+ r: radius,
3147
+ strokeWidth: stroke,
3148
+ stroke: trailColor ?? trailColorDefault,
3149
+ fill: "none",
3150
+ strokeDasharray: dashArray,
3151
+ strokeDashoffset: dashOffsetBase,
3152
+ strokeLinecap: "round"
3153
+ }
3154
+ ),
3155
+ /* @__PURE__ */ jsxRuntime.jsx(
3156
+ "circle",
3157
+ {
3158
+ cx: width / 2,
3159
+ cy: width / 2,
3160
+ r: radius,
3161
+ strokeWidth: stroke,
3162
+ stroke: color,
3163
+ fill: "none",
3164
+ strokeDasharray: dashArray,
3165
+ strokeDashoffset: progressDashOffset,
3166
+ strokeLinecap: "round",
3167
+ className: tailwindMerge.twMerge(status === "active" ? "animate-[spin_3s_linear_infinite]" : void 0)
3168
+ }
3169
+ ),
3170
+ successPercent > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3171
+ "circle",
3172
+ {
3173
+ cx: width / 2,
3174
+ cy: width / 2,
3175
+ r: radius,
3176
+ strokeWidth: stroke,
3177
+ stroke: successColor,
3178
+ fill: "none",
3179
+ strokeDasharray: dashArray,
3180
+ strokeDashoffset: successDashOffset,
3181
+ strokeLinecap: "round"
3182
+ }
3183
+ ) : null
3184
+ ]
3185
+ }
3186
+ ),
3187
+ showInfo ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-gray-800 dark:text-gray-100", children: /* @__PURE__ */ jsxRuntime.jsx(InfoNode, { status, percent, successPercent, format }) }) }) : null
3188
+ ] }) });
3189
+ };
3190
+ var Progress = (props) => {
3191
+ const toNumber2 = (value) => {
3192
+ if (typeof value === "string") {
3193
+ const parsed = Number.parseFloat(value);
3194
+ return Number.isFinite(parsed) ? parsed : void 0;
3195
+ }
3196
+ return value;
3197
+ };
3198
+ const {
3199
+ percent: rawPercent = 0,
3200
+ success,
3201
+ status: providedStatus,
3202
+ type = "line",
3203
+ showInfo = true,
3204
+ format,
3205
+ strokeWidth,
3206
+ trailColor,
3207
+ strokeColor,
3208
+ width,
3209
+ size,
3210
+ steps,
3211
+ gapDegree,
3212
+ gapPosition,
3213
+ className,
3214
+ style,
3215
+ ...restProps
3216
+ } = props;
3217
+ const percent = clampPercent(toNumber2(rawPercent));
3218
+ const successPercent = clampPercent(toNumber2(success?.percent));
3219
+ const status = providedStatus ?? (percent >= 100 ? "success" : "normal");
3220
+ const resolvedClassName = tailwindMerge.twMerge("min-w-[200px]", className);
3221
+ if (type === "circle" || type === "dashboard") {
3222
+ return /* @__PURE__ */ jsxRuntime.jsx(
3223
+ CircleProgress,
3224
+ {
3225
+ ...restProps,
3226
+ type,
3227
+ percent,
3228
+ successPercent,
3229
+ success,
3230
+ status,
3231
+ showInfo,
3232
+ className: resolvedClassName,
3233
+ format,
3234
+ strokeWidth,
3235
+ trailColor,
3236
+ strokeColor,
3237
+ width,
3238
+ gapDegree,
3239
+ gapPosition,
3240
+ style
3241
+ }
3242
+ );
3243
+ }
3244
+ return /* @__PURE__ */ jsxRuntime.jsx(
3245
+ LineProgress,
3246
+ {
3247
+ percent,
3248
+ successPercent,
3249
+ success,
3250
+ status,
3251
+ showInfo,
3252
+ className: resolvedClassName,
3253
+ format,
3254
+ strokeWidth,
3255
+ trailColor,
3256
+ strokeColor,
3257
+ size,
3258
+ steps,
3259
+ style,
3260
+ ...restProps
3261
+ }
3262
+ );
3263
+ };
3264
+ var Progress_default = Progress;
2579
3265
 
3266
+ exports.AppBar = AppBar_default;
3267
+ exports.Block = Block_default;
2580
3268
  exports.Button = Button_default;
2581
3269
  exports.Card = Card_default;
2582
3270
  exports.Chip = Chip_default;
@@ -2590,7 +3278,9 @@ exports.List = List_default;
2590
3278
  exports.ListItem = Item_default;
2591
3279
  exports.Masonry = Masonry_default;
2592
3280
  exports.Menu = Menu_default;
3281
+ exports.Notification = Notification_default;
2593
3282
  exports.ProfileCard = ProfileCard_default;
3283
+ exports.Progress = Progress_default;
2594
3284
  exports.Select = Select_default;
2595
3285
  exports.Slider = Slider_default;
2596
3286
  exports.Switch = Switch_default;