@mohasinac/ui 0.1.0 → 1.1.0

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
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ "use client";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __defProps = Object.defineProperties;
@@ -69,6 +70,7 @@ __export(index_exports, {
69
70
  Button: () => Button,
70
71
  Caption: () => Caption,
71
72
  Container: () => Container,
73
+ CountdownDisplay: () => CountdownDisplay,
72
74
  DEFAULT_PAGINATION_CONFIG: () => import_contracts3.DEFAULT_PAGINATION_CONFIG,
73
75
  DEFAULT_STICKY_CONFIG: () => import_contracts3.DEFAULT_STICKY_CONFIG,
74
76
  DEFAULT_TABLE_CONFIG: () => import_contracts3.DEFAULT_TABLE_CONFIG,
@@ -80,6 +82,7 @@ __export(index_exports, {
80
82
  Heading: () => Heading,
81
83
  ImageLightbox: () => ImageLightbox,
82
84
  IndeterminateProgress: () => IndeterminateProgress,
85
+ ItemRow: () => ItemRow,
83
86
  Label: () => Label,
84
87
  Li: () => Li,
85
88
  Main: () => Main,
@@ -87,7 +90,9 @@ __export(index_exports, {
87
90
  Nav: () => Nav,
88
91
  Ol: () => Ol,
89
92
  Pagination: () => Pagination,
93
+ PriceDisplay: () => PriceDisplay,
90
94
  Progress: () => Progress,
95
+ RatingDisplay: () => RatingDisplay,
91
96
  Row: () => Row,
92
97
  Section: () => Section,
93
98
  Select: () => Select,
@@ -96,10 +101,21 @@ __export(index_exports, {
96
101
  Spinner: () => Spinner,
97
102
  Stack: () => Stack,
98
103
  StarRating: () => StarRating,
104
+ StatsGrid: () => StatsGrid,
99
105
  StatusBadge: () => StatusBadge,
106
+ StepperNav: () => StepperNav,
107
+ SummaryCard: () => SummaryCard,
108
+ TagInput: () => TagInput,
100
109
  Text: () => Text,
101
110
  Ul: () => Ul,
102
- mergeTableConfig: () => import_contracts3.mergeTableConfig
111
+ ViewToggle: () => ViewToggle,
112
+ classNames: () => classNames,
113
+ easings: () => easings,
114
+ getContrastColor: () => getContrastColor,
115
+ hexToRgb: () => hexToRgb,
116
+ mergeTableConfig: () => import_contracts3.mergeTableConfig,
117
+ mergeTailwindClasses: () => mergeTailwindClasses,
118
+ rgbToHex: () => rgbToHex
103
119
  });
104
120
  module.exports = __toCommonJS(index_exports);
105
121
 
@@ -1759,11 +1775,502 @@ function ImageLightbox({
1759
1775
  );
1760
1776
  }
1761
1777
 
1762
- // src/DataTable.tsx
1778
+ // src/components/TagInput.tsx
1763
1779
  var import_react7 = require("react");
1780
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1781
+ function TagInput({
1782
+ value,
1783
+ onChange,
1784
+ disabled = false,
1785
+ label,
1786
+ placeholder = "Add a tag...",
1787
+ className = "",
1788
+ helperText = "Press Enter or comma to add a tag"
1789
+ }) {
1790
+ const [draft, setDraft] = (0, import_react7.useState)("");
1791
+ const inputRef = (0, import_react7.useRef)(null);
1792
+ const addTag = (raw) => {
1793
+ const tag = raw.trim().replace(/,+$/, "").trim();
1794
+ if (!tag || value.includes(tag)) {
1795
+ setDraft("");
1796
+ return;
1797
+ }
1798
+ onChange([...value, tag]);
1799
+ setDraft("");
1800
+ };
1801
+ const removeTag = (tag) => {
1802
+ onChange(value.filter((t) => t !== tag));
1803
+ };
1804
+ const handleKeyDown = (e) => {
1805
+ if (e.key === "Enter" || e.key === ",") {
1806
+ e.preventDefault();
1807
+ addTag(draft);
1808
+ return;
1809
+ }
1810
+ if (e.key === "Backspace" && draft === "" && value.length > 0) {
1811
+ onChange(value.slice(0, -1));
1812
+ }
1813
+ };
1814
+ const handleChange = (e) => {
1815
+ var _a;
1816
+ const inputValue = e.target.value;
1817
+ if (inputValue.includes(",")) {
1818
+ const parts = inputValue.split(",");
1819
+ const last = (_a = parts.pop()) != null ? _a : "";
1820
+ parts.forEach((part) => addTag(part));
1821
+ setDraft(last);
1822
+ return;
1823
+ }
1824
+ setDraft(inputValue);
1825
+ };
1826
+ const handleBlur = () => {
1827
+ if (draft.trim()) {
1828
+ addTag(draft);
1829
+ }
1830
+ };
1831
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className, children: [
1832
+ label && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { className: "mb-1.5 block text-sm font-medium", children: label }),
1833
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1834
+ "div",
1835
+ {
1836
+ onClick: () => {
1837
+ var _a;
1838
+ return !disabled && ((_a = inputRef.current) == null ? void 0 : _a.focus());
1839
+ },
1840
+ className: [
1841
+ "flex min-h-[42px] w-full cursor-text flex-wrap items-center gap-1.5 rounded-lg border px-3 py-2",
1842
+ "border-zinc-300 bg-white dark:border-slate-700 dark:bg-slate-900",
1843
+ disabled ? "cursor-not-allowed opacity-50" : "transition-colors focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/30"
1844
+ ].join(" "),
1845
+ children: [
1846
+ value.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1847
+ "span",
1848
+ {
1849
+ className: "inline-flex items-center gap-1 rounded-full bg-primary-500/10 px-2 py-0.5 text-xs font-medium text-primary-700 dark:text-primary-300",
1850
+ children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Span, { size: "xs", children: tag }),
1852
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1853
+ "button",
1854
+ {
1855
+ type: "button",
1856
+ onClick: (e) => {
1857
+ e.stopPropagation();
1858
+ removeTag(tag);
1859
+ },
1860
+ className: "ml-0.5 text-primary-700/70 hover:text-primary-700 dark:text-primary-300/70 dark:hover:text-primary-300",
1861
+ "aria-label": `Remove tag ${tag}`,
1862
+ children: "x"
1863
+ }
1864
+ )
1865
+ ]
1866
+ },
1867
+ tag
1868
+ )),
1869
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1870
+ "input",
1871
+ {
1872
+ ref: inputRef,
1873
+ value: draft,
1874
+ onChange: handleChange,
1875
+ onKeyDown: handleKeyDown,
1876
+ onBlur: handleBlur,
1877
+ disabled,
1878
+ placeholder: value.length === 0 ? placeholder : "",
1879
+ className: [
1880
+ "min-w-[100px] flex-1 bg-transparent text-sm outline-none",
1881
+ "text-zinc-900 placeholder:text-zinc-400 dark:text-zinc-100 dark:placeholder:text-zinc-500",
1882
+ disabled ? "cursor-not-allowed" : ""
1883
+ ].join(" "),
1884
+ "aria-label": label != null ? label : "Tag input"
1885
+ }
1886
+ )
1887
+ ]
1888
+ }
1889
+ ),
1890
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Span, { size: "xs", className: "mt-1 text-zinc-500 dark:text-zinc-400", children: helperText })
1891
+ ] });
1892
+ }
1893
+
1894
+ // src/style.helper.ts
1895
+ function classNames(...classes) {
1896
+ return classes.filter(Boolean).join(" ");
1897
+ }
1898
+ function mergeTailwindClasses(...classes) {
1899
+ const classArray = classes.filter(Boolean).join(" ").split(" ");
1900
+ return Array.from(new Set(classArray)).join(" ");
1901
+ }
1902
+
1903
+ // src/components/StepperNav.tsx
1904
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1905
+ function StepperNav({ steps, currentStep, className }) {
1906
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Nav, { "aria-label": "Steps", className: classNames("mb-8", className), children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Ol, { className: "flex items-center gap-0", children: steps.map((step, i) => {
1907
+ const isComplete = step.number < currentStep;
1908
+ const isActive = step.number === currentStep;
1909
+ const isLast = i === steps.length - 1;
1910
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Li, { className: "flex flex-1 items-center", children: [
1911
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-shrink-0 items-center gap-2", children: [
1912
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1913
+ "div",
1914
+ {
1915
+ className: classNames(
1916
+ "flex h-8 w-8 items-center justify-center rounded-full border-2 text-sm font-semibold transition-colors",
1917
+ isComplete ? "border-primary bg-primary text-white" : isActive ? "border-primary bg-transparent text-primary" : "border-zinc-300 text-zinc-500 dark:border-slate-700 dark:text-zinc-400"
1918
+ ),
1919
+ children: isComplete ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1920
+ "svg",
1921
+ {
1922
+ className: "h-4 w-4",
1923
+ fill: "none",
1924
+ viewBox: "0 0 24 24",
1925
+ stroke: "currentColor",
1926
+ "aria-hidden": "true",
1927
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1928
+ "path",
1929
+ {
1930
+ strokeLinecap: "round",
1931
+ strokeLinejoin: "round",
1932
+ strokeWidth: 2.5,
1933
+ d: "M5 13l4 4L19 7"
1934
+ }
1935
+ )
1936
+ }
1937
+ ) : step.number
1938
+ }
1939
+ ),
1940
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1941
+ Span,
1942
+ {
1943
+ className: classNames(
1944
+ "hidden text-sm font-medium sm:block",
1945
+ isActive ? "text-primary" : isComplete ? "text-zinc-900 dark:text-zinc-100" : "text-zinc-500 dark:text-zinc-400"
1946
+ ),
1947
+ children: step.label
1948
+ }
1949
+ )
1950
+ ] }),
1951
+ !isLast && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1952
+ "div",
1953
+ {
1954
+ className: classNames(
1955
+ "mx-3 h-0.5 flex-1 transition-colors",
1956
+ isComplete ? "bg-primary" : "bg-zinc-200 dark:bg-slate-700"
1957
+ )
1958
+ }
1959
+ )
1960
+ ] }, step.number);
1961
+ }) }) });
1962
+ }
1963
+
1964
+ // src/components/ViewToggle.tsx
1965
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1966
+ var ACTIVE = "bg-primary/5 text-primary ring-primary/30 dark:bg-primary/10";
1967
+ var INACTIVE = "text-zinc-500 ring-zinc-200 hover:bg-zinc-100 dark:text-zinc-400 dark:ring-slate-700 dark:hover:bg-slate-800";
1968
+ var DEFAULT_LABELS = {
1969
+ grid: "Grid view",
1970
+ list: "List view",
1971
+ toolbar: "View mode"
1972
+ };
1973
+ function ViewToggle({
1974
+ value,
1975
+ onChange,
1976
+ labels,
1977
+ className
1978
+ }) {
1979
+ const mergedLabels = __spreadValues(__spreadValues({}, DEFAULT_LABELS), labels);
1980
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1981
+ "div",
1982
+ {
1983
+ className: ["flex gap-1", className != null ? className : ""].join(" ").trim(),
1984
+ role: "toolbar",
1985
+ "aria-label": mergedLabels.toolbar,
1986
+ children: [
1987
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1988
+ Button,
1989
+ {
1990
+ type: "button",
1991
+ variant: "ghost",
1992
+ size: "sm",
1993
+ onClick: () => onChange("grid"),
1994
+ "aria-label": mergedLabels.grid,
1995
+ "aria-pressed": value === "grid",
1996
+ className: `flex items-center justify-center rounded-lg p-2 ring-1 transition-colors ${value === "grid" ? ACTIVE : INACTIVE}`,
1997
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1998
+ "svg",
1999
+ {
2000
+ className: "h-5 w-5",
2001
+ fill: "none",
2002
+ viewBox: "0 0 24 24",
2003
+ stroke: "currentColor",
2004
+ strokeWidth: 1.5,
2005
+ "aria-hidden": "true",
2006
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2007
+ "path",
2008
+ {
2009
+ strokeLinecap: "round",
2010
+ strokeLinejoin: "round",
2011
+ d: "M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z"
2012
+ }
2013
+ )
2014
+ }
2015
+ )
2016
+ }
2017
+ ),
2018
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2019
+ Button,
2020
+ {
2021
+ type: "button",
2022
+ variant: "ghost",
2023
+ size: "sm",
2024
+ onClick: () => onChange("list"),
2025
+ "aria-label": mergedLabels.list,
2026
+ "aria-pressed": value === "list",
2027
+ className: `flex items-center justify-center rounded-lg p-2 ring-1 transition-colors ${value === "list" ? ACTIVE : INACTIVE}`,
2028
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2029
+ "svg",
2030
+ {
2031
+ className: "h-5 w-5",
2032
+ fill: "none",
2033
+ viewBox: "0 0 24 24",
2034
+ stroke: "currentColor",
2035
+ strokeWidth: 1.5,
2036
+ "aria-hidden": "true",
2037
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2038
+ "path",
2039
+ {
2040
+ strokeLinecap: "round",
2041
+ strokeLinejoin: "round",
2042
+ d: "M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z"
2043
+ }
2044
+ )
2045
+ }
2046
+ )
2047
+ }
2048
+ )
2049
+ ]
2050
+ }
2051
+ );
2052
+ }
2053
+
2054
+ // src/components/RatingDisplay.tsx
2055
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2056
+ var sizeClass = {
2057
+ sm: "h-4 w-4",
2058
+ md: "h-5 w-5",
2059
+ lg: "h-6 w-6"
2060
+ };
2061
+ function RatingDisplay({
2062
+ rating,
2063
+ maxRating = 5,
2064
+ size = "sm",
2065
+ showValue = false,
2066
+ className
2067
+ }) {
2068
+ const starSize = sizeClass[size];
2069
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: classNames("flex items-center gap-1", className), children: [
2070
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex", children: Array.from({ length: maxRating }, (_, i) => i + 1).map((star) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2071
+ "svg",
2072
+ {
2073
+ className: classNames(
2074
+ starSize,
2075
+ star <= rating ? "text-amber-400 dark:text-secondary-500" : "text-zinc-300 dark:text-zinc-700"
2076
+ ),
2077
+ fill: "currentColor",
2078
+ viewBox: "0 0 20 20",
2079
+ "aria-hidden": "true",
2080
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" })
2081
+ },
2082
+ star
2083
+ )) }),
2084
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Span, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: rating.toFixed(1) })
2085
+ ] });
2086
+ }
2087
+
2088
+ // src/components/PriceDisplay.tsx
2089
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2090
+ function formatCurrency(amount, currency) {
2091
+ return new Intl.NumberFormat("en-IN", {
2092
+ style: "currency",
2093
+ currency,
2094
+ maximumFractionDigits: 2
2095
+ }).format(amount);
2096
+ }
2097
+ function formatPercent(value) {
2098
+ return `${Math.round(value * 100)}%`;
2099
+ }
2100
+ function PriceDisplay({
2101
+ amount,
2102
+ currency = "INR",
2103
+ originalAmount,
2104
+ variant = "compact",
2105
+ className
2106
+ }) {
2107
+ const hasDiscount = originalAmount !== void 0 && originalAmount > amount;
2108
+ const discountPct = hasDiscount ? (originalAmount - amount) / originalAmount : 0;
2109
+ const priceClass = variant === "detail" ? "text-xl font-bold text-primary" : "text-base font-bold text-primary";
2110
+ const originalClass = variant === "detail" ? "text-sm text-zinc-400 line-through dark:text-zinc-500" : "text-xs text-zinc-400 line-through dark:text-zinc-500";
2111
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: classNames("flex flex-wrap items-baseline gap-1.5", className), children: [
2112
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Span, { className: priceClass, children: formatCurrency(amount, currency) }),
2113
+ hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
2114
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Span, { className: originalClass, children: formatCurrency(originalAmount, currency) }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Span, { className: "rounded bg-emerald-100 px-1 py-0.5 text-xs font-semibold text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400", children: [
2116
+ "-",
2117
+ formatPercent(discountPct)
2118
+ ] })
2119
+ ] })
2120
+ ] });
2121
+ }
2122
+
2123
+ // src/components/StatsGrid.tsx
2124
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2125
+ var columnsClass = {
2126
+ 2: "grid grid-cols-1 gap-4 sm:grid-cols-2",
2127
+ 3: "grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3",
2128
+ 4: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"
2129
+ };
2130
+ function StatsGrid({ stats, columns = 3, className }) {
2131
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: classNames(columnsClass[columns], className), children: stats.map((stat, i) => {
2132
+ var _a;
2133
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2134
+ "div",
2135
+ {
2136
+ className: "rounded-xl border border-zinc-200 bg-white p-4 dark:border-slate-700 dark:bg-slate-900",
2137
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between", children: [
2138
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
2139
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Text, { className: "text-sm font-medium text-zinc-500 dark:text-zinc-400", children: stat.label }),
2140
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Text, { className: "mt-1 text-3xl font-bold", children: stat.value })
2141
+ ] }),
2142
+ stat.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2143
+ "div",
2144
+ {
2145
+ className: classNames(
2146
+ (_a = stat.colorClass) != null ? _a : "text-zinc-400 dark:text-zinc-500"
2147
+ ),
2148
+ children: stat.icon
2149
+ }
2150
+ )
2151
+ ] })
2152
+ },
2153
+ `${stat.label}-${i}`
2154
+ );
2155
+ }) });
2156
+ }
2157
+
2158
+ // src/components/SummaryCard.tsx
2159
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2160
+ function SummaryCard({
2161
+ lines,
2162
+ total,
2163
+ action,
2164
+ className
2165
+ }) {
2166
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2167
+ "div",
2168
+ {
2169
+ className: classNames(
2170
+ "space-y-4 rounded-xl border border-zinc-200 bg-white p-5 dark:border-slate-700 dark:bg-slate-900",
2171
+ className
2172
+ ),
2173
+ children: [
2174
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-2", children: lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between text-sm", children: [
2175
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Span, { className: "text-zinc-500 dark:text-zinc-400", children: line.label }),
2176
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2177
+ Span,
2178
+ {
2179
+ className: line.muted ? "text-zinc-500 dark:text-zinc-400" : "text-zinc-900 dark:text-zinc-100",
2180
+ children: line.value
2181
+ }
2182
+ )
2183
+ ] }, i)) }),
2184
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Divider, {}),
2185
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between", children: [
2186
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Span, { className: "font-bold text-zinc-900 dark:text-zinc-100", children: total.label }),
2187
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Span, { className: "text-lg font-bold text-primary", children: total.value })
2188
+ ] }),
2189
+ action && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: action })
2190
+ ]
2191
+ }
2192
+ );
2193
+ }
2194
+
2195
+ // src/components/CountdownDisplay.tsx
2196
+ var import_react8 = require("react");
2197
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2198
+ function getRemaining(targetDate) {
2199
+ const now = Date.now();
2200
+ const distance = targetDate.getTime() - now;
2201
+ if (distance <= 0) {
2202
+ return null;
2203
+ }
2204
+ const totalSeconds = Math.floor(distance / 1e3);
2205
+ const days = Math.floor(totalSeconds / 86400);
2206
+ const hours = Math.floor(totalSeconds % 86400 / 3600);
2207
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
2208
+ const seconds = totalSeconds % 60;
2209
+ return { days, hours, minutes, seconds };
2210
+ }
2211
+ function formatLabel(remaining, format) {
2212
+ const { days, hours, minutes, seconds } = remaining;
2213
+ if (format === "hms") {
2214
+ const totalHours = days * 24 + hours;
2215
+ return `${totalHours}h ${minutes}m ${seconds}s`;
2216
+ }
2217
+ if (format === "dhms") {
2218
+ return `${days}d ${hours}h ${minutes}m ${seconds}s`;
2219
+ }
2220
+ if (days > 0) {
2221
+ return `${days}d ${hours}h ${minutes}m`;
2222
+ }
2223
+ if (hours > 0) {
2224
+ return `${hours}h ${minutes}m ${seconds}s`;
2225
+ }
2226
+ return `${minutes}m ${seconds}s`;
2227
+ }
2228
+ function CountdownDisplay({
2229
+ targetDate,
2230
+ format = "auto",
2231
+ expiredLabel = "Ended",
2232
+ className
2233
+ }) {
2234
+ const [tick, setTick] = (0, import_react8.useState)(0);
2235
+ (0, import_react8.useEffect)(() => {
2236
+ const id = window.setInterval(() => {
2237
+ setTick((value) => value + 1);
2238
+ }, 1e3);
2239
+ return () => {
2240
+ window.clearInterval(id);
2241
+ };
2242
+ }, []);
2243
+ const remaining = (0, import_react8.useMemo)(() => getRemaining(targetDate), [targetDate, tick]);
2244
+ const label = remaining ? formatLabel(remaining, format) : expiredLabel;
2245
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Span, { variant: "inherit", className: classNames("tabular-nums", className), children: label });
2246
+ }
2247
+
2248
+ // src/components/ItemRow.tsx
2249
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2250
+ function ItemRow({
2251
+ thumbnail,
2252
+ title,
2253
+ subtitle,
2254
+ rightSlot,
2255
+ actions,
2256
+ className
2257
+ }) {
2258
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: classNames("flex items-start gap-4", className), children: [
2259
+ thumbnail && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-shrink-0", children: thumbnail }),
2260
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0 flex-1", children: [
2261
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Text, { size: "sm", weight: "medium", className: "line-clamp-2", children: title }),
2262
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Caption, { className: "mt-0.5", children: subtitle }),
2263
+ actions && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "mt-2", children: actions })
2264
+ ] }),
2265
+ rightSlot && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-shrink-0", children: rightSlot })
2266
+ ] });
2267
+ }
2268
+
2269
+ // src/DataTable.tsx
2270
+ var import_react9 = require("react");
1764
2271
 
1765
2272
  // src/components/Layout.tsx
1766
- var import_jsx_runtime18 = require("react/jsx-runtime");
2273
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1767
2274
  var GAP_MAP = {
1768
2275
  none: "",
1769
2276
  px: "gap-px",
@@ -1848,7 +2355,7 @@ function Container(_a) {
1848
2355
  "children"
1849
2356
  ]);
1850
2357
  const Tag = as != null ? as : "div";
1851
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2358
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1852
2359
  Tag,
1853
2360
  __spreadProps(__spreadValues({
1854
2361
  className: [CONTAINER_MAP[size], className].filter(Boolean).join(" ")
@@ -1878,7 +2385,7 @@ function Stack(_a) {
1878
2385
  align !== "stretch" ? ITEMS_MAP[align] : "",
1879
2386
  className
1880
2387
  ].filter(Boolean).join(" ");
1881
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
2388
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
1882
2389
  }
1883
2390
  function Row(_a) {
1884
2391
  var _b = _a, {
@@ -1907,7 +2414,7 @@ function Row(_a) {
1907
2414
  wrap ? "flex-wrap" : "",
1908
2415
  className
1909
2416
  ].filter(Boolean).join(" ");
1910
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
2417
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
1911
2418
  }
1912
2419
  function Grid(_a) {
1913
2420
  var _b = _a, {
@@ -1926,12 +2433,12 @@ function Grid(_a) {
1926
2433
  const Tag = as != null ? as : "div";
1927
2434
  const baseClass = cols !== void 0 ? GRID_MAP[cols] : "grid";
1928
2435
  const classes = [baseClass, GAP_MAP[gap], className].filter(Boolean).join(" ");
1929
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
2436
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Tag, __spreadProps(__spreadValues({ className: classes }, props), { children }));
1930
2437
  }
1931
2438
 
1932
2439
  // src/DataTable.tsx
1933
2440
  var import_contracts2 = require("@mohasinac/contracts");
1934
- var import_jsx_runtime19 = require("react/jsx-runtime");
2441
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1935
2442
  function DataTable({
1936
2443
  data,
1937
2444
  columns,
@@ -1970,10 +2477,10 @@ function DataTable({
1970
2477
  const showViewToggle = showViewToggleProp != null ? showViewToggleProp : resolvedTable.showViewToggle;
1971
2478
  const selectable = selectableProp != null ? selectableProp : resolvedTable.selectable;
1972
2479
  const defaultViewMode = defaultViewModeProp != null ? defaultViewModeProp : resolvedTable.defaultViewMode;
1973
- const [sortKey, setSortKey] = (0, import_react7.useState)(null);
1974
- const [sortDirection, setSortDirection] = (0, import_react7.useState)(null);
1975
- const [currentPage, setCurrentPage] = (0, import_react7.useState)(1);
1976
- const [internalViewMode, setInternalViewMode] = (0, import_react7.useState)(defaultViewMode);
2480
+ const [sortKey, setSortKey] = (0, import_react9.useState)(null);
2481
+ const [sortDirection, setSortDirection] = (0, import_react9.useState)(null);
2482
+ const [currentPage, setCurrentPage] = (0, import_react9.useState)(1);
2483
+ const [internalViewMode, setInternalViewMode] = (0, import_react9.useState)(defaultViewMode);
1977
2484
  const activeViewMode = controlledViewMode != null ? controlledViewMode : internalViewMode;
1978
2485
  const {
1979
2486
  loading: labelLoading = "Loading\u2026",
@@ -2002,7 +2509,7 @@ function DataTable({
2002
2509
  setSortDirection("asc");
2003
2510
  }
2004
2511
  };
2005
- const sortedData = (0, import_react7.useMemo)(() => {
2512
+ const sortedData = (0, import_react9.useMemo)(() => {
2006
2513
  const sorted = [...data];
2007
2514
  if (sortKey && sortDirection) {
2008
2515
  sorted.sort((a, b) => {
@@ -2020,19 +2527,19 @@ function DataTable({
2020
2527
  }
2021
2528
  return sorted;
2022
2529
  }, [data, sortKey, sortDirection]);
2023
- const paginatedData = (0, import_react7.useMemo)(() => {
2530
+ const paginatedData = (0, import_react9.useMemo)(() => {
2024
2531
  if (externalPagination) return sortedData;
2025
2532
  const start = (currentPage - 1) * pageSize;
2026
2533
  return sortedData.slice(start, start + pageSize);
2027
2534
  }, [sortedData, currentPage, externalPagination, pageSize]);
2028
2535
  const totalPages = Math.ceil(sortedData.length / pageSize);
2029
2536
  if (loading) {
2030
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Spinner, { size: "lg", label: labelLoading }) }) });
2537
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Spinner, { size: "lg", label: labelLoading }) }) });
2031
2538
  }
2032
2539
  if (data.length === 0) {
2033
- if (emptyState) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: emptyState });
2034
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "text-center px-4", children: [
2035
- emptyIcon != null ? emptyIcon : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2540
+ if (emptyState) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: emptyState });
2541
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "text-center px-4", children: [
2542
+ emptyIcon != null ? emptyIcon : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2036
2543
  "svg",
2037
2544
  {
2038
2545
  className: "mx-auto h-12 w-12 text-zinc-400",
@@ -2040,7 +2547,7 @@ function DataTable({
2040
2547
  viewBox: "0 0 24 24",
2041
2548
  stroke: "currentColor",
2042
2549
  "aria-hidden": "true",
2043
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2550
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2044
2551
  "path",
2045
2552
  {
2046
2553
  strokeLinecap: "round",
@@ -2051,20 +2558,20 @@ function DataTable({
2051
2558
  )
2052
2559
  }
2053
2560
  ),
2054
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { size: "sm", weight: "semibold", className: "mt-4", children: emptyTitle != null ? emptyTitle : noDataTitle }),
2055
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { size: "sm", variant: "secondary", className: "mt-1", children: emptyMessage != null ? emptyMessage : noDataDescription })
2561
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { size: "sm", weight: "semibold", className: "mt-4", children: emptyTitle != null ? emptyTitle : noDataTitle }),
2562
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text, { size: "sm", variant: "secondary", className: "mt-1", children: emptyMessage != null ? emptyMessage : noDataDescription })
2056
2563
  ] }) }) });
2057
2564
  }
2058
2565
  const renderViewToggle = () => {
2059
2566
  if (!showViewToggle) return null;
2060
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2567
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
2061
2568
  "div",
2062
2569
  {
2063
2570
  className: "flex justify-end gap-1",
2064
2571
  role: "toolbar",
2065
2572
  "aria-label": "View mode",
2066
2573
  children: [
2067
- showTableView && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2574
+ showTableView && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2068
2575
  Button,
2069
2576
  {
2070
2577
  type: "button",
@@ -2074,7 +2581,7 @@ function DataTable({
2074
2581
  "aria-label": tableView,
2075
2582
  "aria-pressed": activeViewMode === "table",
2076
2583
  className: `hidden sm:flex items-center justify-center p-2 rounded-lg ring-1 transition-colors ${activeViewMode === "table" ? "bg-primary/5 text-primary dark:bg-primary/10 ring-primary/30" : "text-zinc-500 dark:text-zinc-400 ring-zinc-200 dark:ring-slate-700 hover:bg-zinc-100 dark:hover:bg-slate-800"}`,
2077
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2584
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2078
2585
  "svg",
2079
2586
  {
2080
2587
  className: "w-4 h-4",
@@ -2083,7 +2590,7 @@ function DataTable({
2083
2590
  stroke: "currentColor",
2084
2591
  strokeWidth: 1.5,
2085
2592
  "aria-hidden": "true",
2086
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2593
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2087
2594
  "path",
2088
2595
  {
2089
2596
  strokeLinecap: "round",
@@ -2095,7 +2602,7 @@ function DataTable({
2095
2602
  )
2096
2603
  }
2097
2604
  ),
2098
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2605
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2099
2606
  Button,
2100
2607
  {
2101
2608
  type: "button",
@@ -2105,7 +2612,7 @@ function DataTable({
2105
2612
  "aria-label": gridView,
2106
2613
  "aria-pressed": activeViewMode === "grid",
2107
2614
  className: `flex items-center justify-center p-2 rounded-lg ring-1 transition-colors ${activeViewMode === "grid" ? "bg-primary/5 text-primary dark:bg-primary/10 ring-primary/30" : "text-zinc-500 dark:text-zinc-400 ring-zinc-200 dark:ring-slate-700 hover:bg-zinc-100 dark:hover:bg-slate-800"}`,
2108
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2615
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2109
2616
  "svg",
2110
2617
  {
2111
2618
  className: "w-4 h-4",
@@ -2114,7 +2621,7 @@ function DataTable({
2114
2621
  stroke: "currentColor",
2115
2622
  strokeWidth: 1.5,
2116
2623
  "aria-hidden": "true",
2117
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2624
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2118
2625
  "path",
2119
2626
  {
2120
2627
  strokeLinecap: "round",
@@ -2126,7 +2633,7 @@ function DataTable({
2126
2633
  )
2127
2634
  }
2128
2635
  ),
2129
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2636
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2130
2637
  Button,
2131
2638
  {
2132
2639
  type: "button",
@@ -2136,7 +2643,7 @@ function DataTable({
2136
2643
  "aria-label": listView,
2137
2644
  "aria-pressed": activeViewMode === "list",
2138
2645
  className: `flex items-center justify-center p-2 rounded-lg ring-1 transition-colors ${activeViewMode === "list" ? "bg-primary/5 text-primary dark:bg-primary/10 ring-primary/30" : "text-zinc-500 dark:text-zinc-400 ring-zinc-200 dark:ring-slate-700 hover:bg-zinc-100 dark:hover:bg-slate-800"}`,
2139
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2646
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2140
2647
  "svg",
2141
2648
  {
2142
2649
  className: "w-4 h-4",
@@ -2145,7 +2652,7 @@ function DataTable({
2145
2652
  stroke: "currentColor",
2146
2653
  strokeWidth: 1.5,
2147
2654
  "aria-hidden": "true",
2148
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2655
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2149
2656
  "path",
2150
2657
  {
2151
2658
  strokeLinecap: "round",
@@ -2163,11 +2670,11 @@ function DataTable({
2163
2670
  };
2164
2671
  const renderCardGrid = (mode) => {
2165
2672
  if (!mobileCardRender) return null;
2166
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2673
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2167
2674
  "div",
2168
2675
  {
2169
2676
  className: mode === "grid" ? `${GRID_MAP[gridCols]} gap-6` : "flex flex-col gap-4",
2170
- children: paginatedData.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2677
+ children: paginatedData.map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2171
2678
  SelectableCard,
2172
2679
  {
2173
2680
  id: keyExtractor(item),
@@ -2184,10 +2691,10 @@ function DataTable({
2184
2691
  }
2185
2692
  );
2186
2693
  };
2187
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-4", children: [
2694
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "space-y-4", children: [
2188
2695
  renderViewToggle(),
2189
2696
  activeViewMode !== "table" && mobileCardRender && renderCardGrid(activeViewMode),
2190
- activeViewMode === "table" && mobileCardRender && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "md:hidden space-y-6", children: paginatedData.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2697
+ activeViewMode === "table" && mobileCardRender && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "md:hidden space-y-6", children: paginatedData.map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2191
2698
  SelectableCard,
2192
2699
  {
2193
2700
  id: keyExtractor(item),
@@ -2200,17 +2707,17 @@ function DataTable({
2200
2707
  },
2201
2708
  keyExtractor(item)
2202
2709
  )) }),
2203
- activeViewMode === "table" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2710
+ activeViewMode === "table" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "rounded-2xl border border-zinc-200 dark:border-slate-700 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2204
2711
  "div",
2205
2712
  {
2206
2713
  className: `overflow-x-auto ${stickyHeader ? "max-h-[600px] overflow-y-auto" : ""}`,
2207
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("table", { className: "min-w-full divide-y divide-zinc-200 dark:divide-slate-700", children: [
2208
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2714
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("table", { className: "min-w-full divide-y divide-zinc-200 dark:divide-slate-700", children: [
2715
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2209
2716
  "thead",
2210
2717
  {
2211
2718
  className: `bg-zinc-50 dark:bg-slate-800 ${stickyHeader ? "sticky top-0 z-10" : ""}`,
2212
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("tr", { children: [
2213
- selectable && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("th", { scope: "col", className: "px-4 py-3 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2719
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("tr", { children: [
2720
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "col", className: "px-4 py-3 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2214
2721
  "input",
2215
2722
  {
2216
2723
  type: "checkbox",
@@ -2229,7 +2736,7 @@ function DataTable({
2229
2736
  }
2230
2737
  }
2231
2738
  ) }),
2232
- columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2739
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2233
2740
  "th",
2234
2741
  {
2235
2742
  scope: "col",
@@ -2237,14 +2744,14 @@ function DataTable({
2237
2744
  className: `px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider ${col.sortable ? "cursor-pointer select-none hover:bg-zinc-100 dark:hover:bg-slate-700" : ""}`,
2238
2745
  style: { width: col.width },
2239
2746
  onClick: () => col.sortable && handleSort(col.key),
2240
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
2747
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-2", children: [
2241
2748
  col.header,
2242
- col.sortable && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-zinc-400", "aria-hidden": "true", children: sortKey === col.key ? sortDirection === "asc" ? "\u2191" : "\u2193" : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "opacity-30", children: "\u2195" }) })
2749
+ col.sortable && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-zinc-400", "aria-hidden": "true", children: sortKey === col.key ? sortDirection === "asc" ? "\u2191" : "\u2193" : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "opacity-30", children: "\u2195" }) })
2243
2750
  ] })
2244
2751
  },
2245
2752
  col.key
2246
2753
  )),
2247
- actions && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2754
+ actions && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2248
2755
  "th",
2249
2756
  {
2250
2757
  scope: "col",
@@ -2255,7 +2762,7 @@ function DataTable({
2255
2762
  ] })
2256
2763
  }
2257
2764
  ),
2258
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tbody", { className: "bg-white dark:bg-slate-900 divide-y divide-zinc-200 dark:divide-slate-700", children: paginatedData.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2765
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tbody", { className: "bg-white dark:bg-slate-900 divide-y divide-zinc-200 dark:divide-slate-700", children: paginatedData.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
2259
2766
  "tr",
2260
2767
  {
2261
2768
  className: [
@@ -2265,12 +2772,12 @@ function DataTable({
2265
2772
  ].join(" "),
2266
2773
  onClick: () => onRowClick == null ? void 0 : onRowClick(item),
2267
2774
  children: [
2268
- selectable && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2775
+ selectable && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2269
2776
  "td",
2270
2777
  {
2271
2778
  className: "px-4 py-4 w-8",
2272
2779
  onClick: (e) => e.stopPropagation(),
2273
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2780
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2274
2781
  "input",
2275
2782
  {
2276
2783
  type: "checkbox",
@@ -2289,7 +2796,7 @@ function DataTable({
2289
2796
  ),
2290
2797
  columns.map((col) => {
2291
2798
  var _a;
2292
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2799
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2293
2800
  "td",
2294
2801
  {
2295
2802
  className: "px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100",
@@ -2298,7 +2805,7 @@ function DataTable({
2298
2805
  col.key
2299
2806
  );
2300
2807
  }),
2301
- actions && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2808
+ actions && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2302
2809
  "td",
2303
2810
  {
2304
2811
  className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium",
@@ -2313,7 +2820,7 @@ function DataTable({
2313
2820
  ] })
2314
2821
  }
2315
2822
  ) }),
2316
- !externalPagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2823
+ !externalPagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2317
2824
  Pagination,
2318
2825
  {
2319
2826
  currentPage,
@@ -2335,9 +2842,9 @@ function SelectableCard({
2335
2842
  children,
2336
2843
  listMode = false
2337
2844
  }) {
2338
- if (!selectable) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-full", children });
2339
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "relative group h-full", children: [
2340
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2845
+ if (!selectable) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-full", children });
2846
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative group h-full", children: [
2847
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2341
2848
  "div",
2342
2849
  {
2343
2850
  className: [
@@ -2345,8 +2852,8 @@ function SelectableCard({
2345
2852
  listMode ? "left-2 top-1/2 -translate-y-1/2" : "top-2 left-2"
2346
2853
  ].join(" "),
2347
2854
  onClick: (e) => e.stopPropagation(),
2348
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "w-6 h-6 rounded-md bg-white/95 dark:bg-slate-800/95 shadow-md flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "relative flex items-center justify-center", children: [
2349
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2855
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-6 h-6 rounded-md bg-white/95 dark:bg-slate-800/95 shadow-md flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative flex items-center justify-center", children: [
2856
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2350
2857
  "input",
2351
2858
  {
2352
2859
  type: "checkbox",
@@ -2359,7 +2866,7 @@ function SelectableCard({
2359
2866
  "aria-label": "Select item"
2360
2867
  }
2361
2868
  ),
2362
- selected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2869
+ selected && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2363
2870
  "svg",
2364
2871
  {
2365
2872
  className: "absolute inset-0 m-auto w-2.5 h-2.5 text-white pointer-events-none",
@@ -2367,7 +2874,7 @@ function SelectableCard({
2367
2874
  stroke: "currentColor",
2368
2875
  viewBox: "0 0 24 24",
2369
2876
  "aria-hidden": "true",
2370
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2877
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2371
2878
  "path",
2372
2879
  {
2373
2880
  strokeLinecap: "round",
@@ -2381,7 +2888,7 @@ function SelectableCard({
2381
2888
  ] }) })
2382
2889
  }
2383
2890
  ),
2384
- selected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2891
+ selected && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2385
2892
  "div",
2386
2893
  {
2387
2894
  className: "absolute inset-0 z-[5] rounded-xl ring-2 ring-primary ring-offset-0 pointer-events-none",
@@ -2394,6 +2901,42 @@ function SelectableCard({
2394
2901
 
2395
2902
  // src/index.ts
2396
2903
  var import_contracts3 = require("@mohasinac/contracts");
2904
+
2905
+ // src/animation.helper.ts
2906
+ var easings = {
2907
+ linear: (t) => t,
2908
+ easeInQuad: (t) => t * t,
2909
+ easeOutQuad: (t) => t * (2 - t),
2910
+ easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
2911
+ easeInCubic: (t) => t * t * t,
2912
+ easeOutCubic: (t) => --t * t * t + 1,
2913
+ easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
2914
+ easeInQuart: (t) => t * t * t * t,
2915
+ easeOutQuart: (t) => 1 - --t * t * t * t,
2916
+ easeInOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t
2917
+ };
2918
+
2919
+ // src/color.helper.ts
2920
+ function hexToRgb(hex) {
2921
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
2922
+ return result ? {
2923
+ r: parseInt(result[1], 16),
2924
+ g: parseInt(result[2], 16),
2925
+ b: parseInt(result[3], 16)
2926
+ } : null;
2927
+ }
2928
+ function rgbToHex(r, g, b) {
2929
+ return "#" + [r, g, b].map((x) => {
2930
+ const hex = x.toString(16);
2931
+ return hex.length === 1 ? "0" + hex : hex;
2932
+ }).join("");
2933
+ }
2934
+ function getContrastColor(hex) {
2935
+ const rgb = hexToRgb(hex);
2936
+ if (!rgb) return "#000000";
2937
+ const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
2938
+ return luminance > 0.5 ? "#000000" : "#ffffff";
2939
+ }
2397
2940
  // Annotate the CommonJS export names for ESM import in node:
2398
2941
  0 && (module.exports = {
2399
2942
  Alert,
@@ -2406,6 +2949,7 @@ var import_contracts3 = require("@mohasinac/contracts");
2406
2949
  Button,
2407
2950
  Caption,
2408
2951
  Container,
2952
+ CountdownDisplay,
2409
2953
  DEFAULT_PAGINATION_CONFIG,
2410
2954
  DEFAULT_STICKY_CONFIG,
2411
2955
  DEFAULT_TABLE_CONFIG,
@@ -2417,6 +2961,7 @@ var import_contracts3 = require("@mohasinac/contracts");
2417
2961
  Heading,
2418
2962
  ImageLightbox,
2419
2963
  IndeterminateProgress,
2964
+ ItemRow,
2420
2965
  Label,
2421
2966
  Li,
2422
2967
  Main,
@@ -2424,7 +2969,9 @@ var import_contracts3 = require("@mohasinac/contracts");
2424
2969
  Nav,
2425
2970
  Ol,
2426
2971
  Pagination,
2972
+ PriceDisplay,
2427
2973
  Progress,
2974
+ RatingDisplay,
2428
2975
  Row,
2429
2976
  Section,
2430
2977
  Select,
@@ -2433,8 +2980,19 @@ var import_contracts3 = require("@mohasinac/contracts");
2433
2980
  Spinner,
2434
2981
  Stack,
2435
2982
  StarRating,
2983
+ StatsGrid,
2436
2984
  StatusBadge,
2985
+ StepperNav,
2986
+ SummaryCard,
2987
+ TagInput,
2437
2988
  Text,
2438
2989
  Ul,
2439
- mergeTableConfig
2990
+ ViewToggle,
2991
+ classNames,
2992
+ easings,
2993
+ getContrastColor,
2994
+ hexToRgb,
2995
+ mergeTableConfig,
2996
+ mergeTailwindClasses,
2997
+ rgbToHex
2440
2998
  });