@kjaniec-dev/ui 0.7.1 → 0.8.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 +528 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -21
- package/dist/index.d.ts +97 -21
- package/dist/index.js +517 -56
- package/dist/index.js.map +1 -1
- package/package.json +59 -20
package/dist/index.js
CHANGED
|
@@ -518,6 +518,7 @@ function useTabs() {
|
|
|
518
518
|
}
|
|
519
519
|
function Tabs({ value, defaultValue, onValueChange, className, children, ...props }) {
|
|
520
520
|
const [internal, setInternal] = React18.useState(defaultValue ?? "");
|
|
521
|
+
const uid = React18.useId();
|
|
521
522
|
const current = value ?? internal;
|
|
522
523
|
const setValue = React18.useCallback(
|
|
523
524
|
(v) => {
|
|
@@ -526,7 +527,7 @@ function Tabs({ value, defaultValue, onValueChange, className, children, ...prop
|
|
|
526
527
|
},
|
|
527
528
|
[value, onValueChange]
|
|
528
529
|
);
|
|
529
|
-
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value: current, setValue }, children: /* @__PURE__ */ jsx("div", { className, ...props, children }) });
|
|
530
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value: current, setValue, uid }, children: /* @__PURE__ */ jsx("div", { className, ...props, children }) });
|
|
530
531
|
}
|
|
531
532
|
var TabsList = React18.forwardRef(
|
|
532
533
|
({ className, onKeyDown, ...props }, ref) => {
|
|
@@ -577,7 +578,7 @@ var TabsList = React18.forwardRef(
|
|
|
577
578
|
TabsList.displayName = "TabsList";
|
|
578
579
|
var TabsTrigger = React18.forwardRef(
|
|
579
580
|
({ className, value, children, ...props }, ref) => {
|
|
580
|
-
const { value: current, setValue } = useTabs();
|
|
581
|
+
const { value: current, setValue, uid } = useTabs();
|
|
581
582
|
const active = current === value;
|
|
582
583
|
return /* @__PURE__ */ jsx(
|
|
583
584
|
"button",
|
|
@@ -585,8 +586,8 @@ var TabsTrigger = React18.forwardRef(
|
|
|
585
586
|
ref,
|
|
586
587
|
type: "button",
|
|
587
588
|
role: "tab",
|
|
588
|
-
id: `tabs-trigger-${value}`,
|
|
589
|
-
"aria-controls": `tabs-panel-${value}`,
|
|
589
|
+
id: `tabs-trigger-${uid}-${value}`,
|
|
590
|
+
"aria-controls": `tabs-panel-${uid}-${value}`,
|
|
590
591
|
"aria-selected": active,
|
|
591
592
|
tabIndex: active ? 0 : -1,
|
|
592
593
|
onClick: () => setValue(value),
|
|
@@ -606,7 +607,7 @@ var TabsTrigger = React18.forwardRef(
|
|
|
606
607
|
TabsTrigger.displayName = "TabsTrigger";
|
|
607
608
|
var TabsContent = React18.forwardRef(
|
|
608
609
|
({ className, value, ...props }, ref) => {
|
|
609
|
-
const { value: current } = useTabs();
|
|
610
|
+
const { value: current, uid } = useTabs();
|
|
610
611
|
const active = current === value;
|
|
611
612
|
if (!active) return null;
|
|
612
613
|
return /* @__PURE__ */ jsx(
|
|
@@ -614,8 +615,8 @@ var TabsContent = React18.forwardRef(
|
|
|
614
615
|
{
|
|
615
616
|
ref,
|
|
616
617
|
role: "tabpanel",
|
|
617
|
-
id: `tabs-panel-${value}`,
|
|
618
|
-
"aria-labelledby": `tabs-trigger-${value}`,
|
|
618
|
+
id: `tabs-panel-${uid}-${value}`,
|
|
619
|
+
"aria-labelledby": `tabs-trigger-${uid}-${value}`,
|
|
619
620
|
tabIndex: 0,
|
|
620
621
|
className: cn("pt-5 text-[0.9rem] text-muted-foreground outline-none", className),
|
|
621
622
|
...props
|
|
@@ -1344,23 +1345,39 @@ function DataTable({
|
|
|
1344
1345
|
}[col.align || "left"];
|
|
1345
1346
|
const isSortable = col.sortable && onSort && col.sortKey;
|
|
1346
1347
|
const isSortedActive = sortBy && col.sortKey === sortBy;
|
|
1348
|
+
const ariaSort = isSortable ? isSortedActive ? sortDirection === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
1347
1349
|
return /* @__PURE__ */ jsx(
|
|
1348
1350
|
TableHead,
|
|
1349
1351
|
{
|
|
1350
1352
|
className: cn(
|
|
1351
1353
|
alignClass,
|
|
1352
|
-
isSortable && "
|
|
1354
|
+
isSortable && "p-0 hover:bg-muted/30 transition-colors",
|
|
1353
1355
|
col.className
|
|
1354
1356
|
),
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1357
|
+
"aria-sort": ariaSort,
|
|
1358
|
+
children: isSortable ? /* @__PURE__ */ jsxs(
|
|
1359
|
+
"button",
|
|
1360
|
+
{
|
|
1361
|
+
type: "button",
|
|
1362
|
+
onClick: () => {
|
|
1363
|
+
if (!col.sortKey) return;
|
|
1364
|
+
const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
|
|
1365
|
+
onSort(col.sortKey, nextDirection);
|
|
1366
|
+
},
|
|
1367
|
+
className: cn(
|
|
1368
|
+
"w-full px-4 py-3 flex items-center gap-1.5 font-semibold text-[0.72rem] uppercase tracking-[0.05em] text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 transition-colors cursor-pointer",
|
|
1369
|
+
{
|
|
1370
|
+
"justify-start text-left": col.align === "left" || !col.align,
|
|
1371
|
+
"justify-center text-center": col.align === "center",
|
|
1372
|
+
"justify-end text-right": col.align === "right"
|
|
1373
|
+
}
|
|
1374
|
+
),
|
|
1375
|
+
children: [
|
|
1376
|
+
/* @__PURE__ */ jsx("span", { children: col.header }),
|
|
1377
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
|
|
1378
|
+
]
|
|
1379
|
+
}
|
|
1380
|
+
) : /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: col.header })
|
|
1364
1381
|
},
|
|
1365
1382
|
idx
|
|
1366
1383
|
);
|
|
@@ -1873,7 +1890,7 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
|
|
|
1873
1890
|
}, [open, filteredItems, activeIndex, onClose]);
|
|
1874
1891
|
React18.useEffect(() => {
|
|
1875
1892
|
if (listRef.current) {
|
|
1876
|
-
const activeEl = listRef.current.
|
|
1893
|
+
const activeEl = listRef.current.querySelector('[aria-selected="true"]');
|
|
1877
1894
|
if (activeEl) {
|
|
1878
1895
|
activeEl.scrollIntoView({ block: "nearest" });
|
|
1879
1896
|
}
|
|
@@ -1896,6 +1913,9 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
|
|
|
1896
1913
|
"div",
|
|
1897
1914
|
{
|
|
1898
1915
|
ref: containerRef,
|
|
1916
|
+
role: "dialog",
|
|
1917
|
+
"aria-modal": "true",
|
|
1918
|
+
"aria-label": "Command palette",
|
|
1899
1919
|
className: "w-[95vw] max-w-lg bg-surface border border-border rounded-kj-xl shadow-kj-lg flex flex-col overflow-hidden max-h-[500px]",
|
|
1900
1920
|
children: [
|
|
1901
1921
|
/* @__PURE__ */ jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
|
|
@@ -1904,6 +1924,11 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
|
|
|
1904
1924
|
"input",
|
|
1905
1925
|
{
|
|
1906
1926
|
type: "text",
|
|
1927
|
+
role: "combobox",
|
|
1928
|
+
"aria-expanded": open,
|
|
1929
|
+
"aria-autocomplete": "list",
|
|
1930
|
+
"aria-controls": "command-palette-listbox",
|
|
1931
|
+
"aria-activedescendant": filteredItems.length > 0 ? `cmd-item-${activeIndex}` : void 0,
|
|
1907
1932
|
placeholder,
|
|
1908
1933
|
value: search,
|
|
1909
1934
|
onChange: (e) => setSearch(e.target.value),
|
|
@@ -1916,44 +1941,64 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
|
|
|
1916
1941
|
'No results found for "',
|
|
1917
1942
|
search,
|
|
1918
1943
|
'"'
|
|
1919
|
-
] }) : /* @__PURE__ */ jsx(
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
"
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
"
|
|
1945
|
-
{
|
|
1946
|
-
|
|
1947
|
-
|
|
1944
|
+
] }) : /* @__PURE__ */ jsx(
|
|
1945
|
+
"div",
|
|
1946
|
+
{
|
|
1947
|
+
ref: listRef,
|
|
1948
|
+
id: "command-palette-listbox",
|
|
1949
|
+
role: "listbox",
|
|
1950
|
+
"aria-label": "Commands",
|
|
1951
|
+
className: "space-y-4",
|
|
1952
|
+
children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": `cmd-cat-${cat}`, className: "space-y-1", children: [
|
|
1953
|
+
/* @__PURE__ */ jsx(
|
|
1954
|
+
"div",
|
|
1955
|
+
{
|
|
1956
|
+
id: `cmd-cat-${cat}`,
|
|
1957
|
+
className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground",
|
|
1958
|
+
children: cat
|
|
1959
|
+
}
|
|
1960
|
+
),
|
|
1961
|
+
itemsInCat.map((item) => {
|
|
1962
|
+
const currentIdx = absoluteItemIndex++;
|
|
1963
|
+
const isActive = currentIdx === activeIndex;
|
|
1964
|
+
return /* @__PURE__ */ jsxs(
|
|
1965
|
+
"div",
|
|
1966
|
+
{
|
|
1967
|
+
id: `cmd-item-${currentIdx}`,
|
|
1968
|
+
role: "option",
|
|
1969
|
+
"aria-selected": isActive,
|
|
1970
|
+
onClick: () => {
|
|
1971
|
+
item.action();
|
|
1972
|
+
onClose();
|
|
1948
1973
|
},
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1974
|
+
className: cn(
|
|
1975
|
+
"flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
|
|
1976
|
+
isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1977
|
+
),
|
|
1978
|
+
children: [
|
|
1979
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
1980
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
|
|
1981
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex flex-col", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
|
|
1983
|
+
item.subtitle && /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
|
|
1984
|
+
] })
|
|
1985
|
+
] }),
|
|
1986
|
+
item.shortcut && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsx(
|
|
1987
|
+
"kbd",
|
|
1988
|
+
{
|
|
1989
|
+
className: "px-1.5 py-0.5 rounded border border-border bg-subtle text-[10px] font-mono leading-none shadow-kj-xs text-muted-foreground",
|
|
1990
|
+
children: sc
|
|
1991
|
+
},
|
|
1992
|
+
scIdx
|
|
1993
|
+
)) })
|
|
1994
|
+
]
|
|
1995
|
+
},
|
|
1996
|
+
item.id
|
|
1997
|
+
);
|
|
1998
|
+
})
|
|
1999
|
+
] }, cat))
|
|
2000
|
+
}
|
|
2001
|
+
) }),
|
|
1957
2002
|
/* @__PURE__ */ jsxs("div", { className: "px-4 py-2.5 border-t border-border bg-subtle flex items-center justify-between text-[11px] text-muted-foreground font-medium", children: [
|
|
1958
2003
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1959
2004
|
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
@@ -2013,7 +2058,423 @@ function SidebarNav({ className, groups, currentHref, ...props }) {
|
|
|
2013
2058
|
] }, groupIdx)) });
|
|
2014
2059
|
}
|
|
2015
2060
|
SidebarNav.displayName = "SidebarNav";
|
|
2061
|
+
var fabVariants = cva(
|
|
2062
|
+
[
|
|
2063
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap select-none",
|
|
2064
|
+
"font-sans font-semibold leading-none",
|
|
2065
|
+
"border border-transparent rounded-full cursor-pointer shadow-lg",
|
|
2066
|
+
"transition-[background-color,color,border-color,box-shadow,transform] duration-150",
|
|
2067
|
+
"active:translate-y-px active:shadow-md",
|
|
2068
|
+
"focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/45",
|
|
2069
|
+
"disabled:opacity-50 disabled:pointer-events-none"
|
|
2070
|
+
],
|
|
2071
|
+
{
|
|
2072
|
+
variants: {
|
|
2073
|
+
variant: {
|
|
2074
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary-hover",
|
|
2075
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-hover",
|
|
2076
|
+
outline: "bg-transparent text-foreground border-border hover:bg-muted hover:border-muted-foreground",
|
|
2077
|
+
danger: "bg-danger text-white hover:brightness-95"
|
|
2078
|
+
},
|
|
2079
|
+
size: {
|
|
2080
|
+
sm: "h-10 w-10 p-0 text-sm",
|
|
2081
|
+
md: "h-14 w-14 p-0 text-base",
|
|
2082
|
+
lg: "h-16 w-16 p-0 text-lg"
|
|
2083
|
+
},
|
|
2084
|
+
position: {
|
|
2085
|
+
"bottom-right": "fixed bottom-6 right-6 z-50",
|
|
2086
|
+
"bottom-left": "fixed bottom-6 left-6 z-50",
|
|
2087
|
+
"bottom-center": "fixed bottom-6 left-1/2 -translate-x-1/2 z-50",
|
|
2088
|
+
none: "relative"
|
|
2089
|
+
}
|
|
2090
|
+
},
|
|
2091
|
+
defaultVariants: { variant: "primary", size: "md", position: "bottom-right" }
|
|
2092
|
+
}
|
|
2093
|
+
);
|
|
2094
|
+
var Fab = React18.forwardRef(
|
|
2095
|
+
({ className, variant, size, position, mobileOnly, icon, label, loading, disabled, ...props }, ref) => {
|
|
2096
|
+
return /* @__PURE__ */ jsx(
|
|
2097
|
+
"button",
|
|
2098
|
+
{
|
|
2099
|
+
ref,
|
|
2100
|
+
className: cn(
|
|
2101
|
+
fabVariants({ variant, size, position }),
|
|
2102
|
+
mobileOnly && "md:hidden",
|
|
2103
|
+
className
|
|
2104
|
+
),
|
|
2105
|
+
...props,
|
|
2106
|
+
disabled: disabled || loading,
|
|
2107
|
+
"aria-label": label,
|
|
2108
|
+
"aria-busy": loading || void 0,
|
|
2109
|
+
children: loading ? /* @__PURE__ */ jsx(
|
|
2110
|
+
"span",
|
|
2111
|
+
{
|
|
2112
|
+
"aria-hidden": true,
|
|
2113
|
+
className: "h-[1.2em] w-[1.2em] rounded-full border-2 border-current border-t-transparent animate-spin"
|
|
2114
|
+
}
|
|
2115
|
+
) : /* @__PURE__ */ jsx("span", { className: "[&_svg]:h-[1.35em] [&_svg]:w-[1.35em] flex items-center justify-center", children: icon })
|
|
2116
|
+
}
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
);
|
|
2120
|
+
Fab.displayName = "Fab";
|
|
2121
|
+
var BottomSheetContext = React18.createContext(null);
|
|
2122
|
+
function BottomSheet({
|
|
2123
|
+
open,
|
|
2124
|
+
onClose,
|
|
2125
|
+
children,
|
|
2126
|
+
maxWidth = "max-w-lg",
|
|
2127
|
+
className,
|
|
2128
|
+
showClose = true
|
|
2129
|
+
}) {
|
|
2130
|
+
const titleId = React18.useId();
|
|
2131
|
+
const descId = React18.useId();
|
|
2132
|
+
const containerRef = React18.useRef(null);
|
|
2133
|
+
const lastActiveElement = React18.useRef(null);
|
|
2134
|
+
const [mounted, setMounted] = React18.useState(open);
|
|
2135
|
+
React18.useEffect(() => {
|
|
2136
|
+
if (open) {
|
|
2137
|
+
setMounted(true);
|
|
2138
|
+
} else {
|
|
2139
|
+
const timer = setTimeout(() => setMounted(false), 200);
|
|
2140
|
+
return () => clearTimeout(timer);
|
|
2141
|
+
}
|
|
2142
|
+
}, [open]);
|
|
2143
|
+
React18.useEffect(() => {
|
|
2144
|
+
if (!open) return;
|
|
2145
|
+
lastActiveElement.current = document.activeElement;
|
|
2146
|
+
const container = containerRef.current;
|
|
2147
|
+
if (container) {
|
|
2148
|
+
const focusables = container.querySelectorAll(
|
|
2149
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
2150
|
+
);
|
|
2151
|
+
if (focusables.length > 0) {
|
|
2152
|
+
focusables[0].focus();
|
|
2153
|
+
setTimeout(() => {
|
|
2154
|
+
if (container.contains(document.activeElement)) return;
|
|
2155
|
+
focusables[0].focus();
|
|
2156
|
+
}, 50);
|
|
2157
|
+
} else {
|
|
2158
|
+
container.focus();
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
const handleKeyDown = (e) => {
|
|
2162
|
+
if (e.key === "Escape") {
|
|
2163
|
+
onClose();
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
if (e.key === "Tab") {
|
|
2167
|
+
const container2 = containerRef.current;
|
|
2168
|
+
if (!container2) return;
|
|
2169
|
+
const focusables = Array.from(
|
|
2170
|
+
container2.querySelectorAll(
|
|
2171
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
2172
|
+
)
|
|
2173
|
+
);
|
|
2174
|
+
if (focusables.length === 0) {
|
|
2175
|
+
e.preventDefault();
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
const first = focusables[0];
|
|
2179
|
+
const last = focusables[focusables.length - 1];
|
|
2180
|
+
if (!container2.contains(document.activeElement)) {
|
|
2181
|
+
e.preventDefault();
|
|
2182
|
+
if (e.shiftKey) {
|
|
2183
|
+
last.focus();
|
|
2184
|
+
} else {
|
|
2185
|
+
first.focus();
|
|
2186
|
+
}
|
|
2187
|
+
return;
|
|
2188
|
+
}
|
|
2189
|
+
if (e.shiftKey) {
|
|
2190
|
+
if (document.activeElement === first || document.activeElement === container2) {
|
|
2191
|
+
last.focus();
|
|
2192
|
+
e.preventDefault();
|
|
2193
|
+
}
|
|
2194
|
+
} else {
|
|
2195
|
+
if (document.activeElement === last) {
|
|
2196
|
+
first.focus();
|
|
2197
|
+
e.preventDefault();
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2203
|
+
document.body.style.overflow = "hidden";
|
|
2204
|
+
return () => {
|
|
2205
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2206
|
+
document.body.style.overflow = "";
|
|
2207
|
+
if (lastActiveElement.current) {
|
|
2208
|
+
lastActiveElement.current.focus();
|
|
2209
|
+
lastActiveElement.current = null;
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
}, [open, onClose]);
|
|
2213
|
+
if (!open && !mounted) return null;
|
|
2214
|
+
return /* @__PURE__ */ jsx(BottomSheetContext.Provider, { value: { titleId, descId }, children: /* @__PURE__ */ jsx(
|
|
2215
|
+
"div",
|
|
2216
|
+
{
|
|
2217
|
+
role: "presentation",
|
|
2218
|
+
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
2219
|
+
className: cn(
|
|
2220
|
+
"fixed inset-0 z-[100] grid items-end sm:place-items-center p-0 sm:p-6 backdrop-blur-[3px] transition-all duration-200",
|
|
2221
|
+
"bg-[color-mix(in_oklch,#09090b_55%,transparent)]",
|
|
2222
|
+
open ? "opacity-100 pointer-events-auto visible" : "opacity-0 pointer-events-none invisible"
|
|
2223
|
+
),
|
|
2224
|
+
children: /* @__PURE__ */ jsxs(
|
|
2225
|
+
"div",
|
|
2226
|
+
{
|
|
2227
|
+
ref: containerRef,
|
|
2228
|
+
role: "dialog",
|
|
2229
|
+
"aria-modal": "true",
|
|
2230
|
+
"aria-labelledby": titleId,
|
|
2231
|
+
"aria-describedby": descId,
|
|
2232
|
+
tabIndex: -1,
|
|
2233
|
+
className: cn(
|
|
2234
|
+
"relative w-full bg-surface border-t sm:border border-border shadow-kj-lg transition-all duration-200 outline-none",
|
|
2235
|
+
"rounded-t-kj-2xl sm:rounded-kj-2xl flex flex-col max-h-[85vh] sm:max-h-[90vh]",
|
|
2236
|
+
// Mobile sliding & Desktop scale/opacity transitions
|
|
2237
|
+
open ? "translate-y-0 sm:scale-100 sm:opacity-100" : "translate-y-full sm:scale-95 sm:opacity-0",
|
|
2238
|
+
// Mobile styling vs Desktop styling
|
|
2239
|
+
"bottom-0 sm:bottom-auto",
|
|
2240
|
+
maxWidth,
|
|
2241
|
+
className
|
|
2242
|
+
),
|
|
2243
|
+
children: [
|
|
2244
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-center py-2 sm:hidden cursor-grab", children: /* @__PURE__ */ jsx("div", { className: "w-12 h-1.5 rounded-full bg-muted-foreground/20" }) }),
|
|
2245
|
+
showClose && /* @__PURE__ */ jsx(
|
|
2246
|
+
"button",
|
|
2247
|
+
{
|
|
2248
|
+
type: "button",
|
|
2249
|
+
onClick: onClose,
|
|
2250
|
+
"aria-label": "Close",
|
|
2251
|
+
className: "absolute top-4 right-4 p-1.5 rounded-kj-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors cursor-pointer z-10",
|
|
2252
|
+
children: /* @__PURE__ */ jsx("svg", { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
2253
|
+
}
|
|
2254
|
+
),
|
|
2255
|
+
children
|
|
2256
|
+
]
|
|
2257
|
+
}
|
|
2258
|
+
)
|
|
2259
|
+
}
|
|
2260
|
+
) });
|
|
2261
|
+
}
|
|
2262
|
+
function BottomSheetHeader({ className, ...props }) {
|
|
2263
|
+
return /* @__PURE__ */ jsx("div", { className: cn("p-6 flex flex-col gap-1.5 border-b border-border", className), ...props });
|
|
2264
|
+
}
|
|
2265
|
+
function BottomSheetTitle({ className, id, ...props }) {
|
|
2266
|
+
const ctx = React18.useContext(BottomSheetContext);
|
|
2267
|
+
return /* @__PURE__ */ jsx("h2", { id: id ?? ctx?.titleId, className: cn("m-0 text-[1.15rem] font-bold tracking-[-0.01em]", className), ...props });
|
|
2268
|
+
}
|
|
2269
|
+
function BottomSheetDescription({ className, id, ...props }) {
|
|
2270
|
+
const ctx = React18.useContext(BottomSheetContext);
|
|
2271
|
+
return /* @__PURE__ */ jsx("p", { id: id ?? ctx?.descId, className: cn("m-0 text-[0.9rem] text-muted-foreground", className), ...props });
|
|
2272
|
+
}
|
|
2273
|
+
function BottomSheetContent({ className, ...props }) {
|
|
2274
|
+
return /* @__PURE__ */ jsx("div", { className: cn("p-6 overflow-y-auto flex-1", className), ...props });
|
|
2275
|
+
}
|
|
2276
|
+
function BottomSheetFooter({ className, ...props }) {
|
|
2277
|
+
return /* @__PURE__ */ jsx("div", { className: cn("p-6 border-t border-border flex gap-2.5 justify-end mt-auto", className), ...props });
|
|
2278
|
+
}
|
|
2279
|
+
var kbdVariants = cva(
|
|
2280
|
+
"inline-flex items-center justify-center font-mono font-medium text-muted-foreground bg-muted border border-border border-b-2 rounded-kj-sm select-none",
|
|
2281
|
+
{
|
|
2282
|
+
variants: {
|
|
2283
|
+
size: {
|
|
2284
|
+
sm: "h-5 min-w-5 px-1 text-[0.68rem]",
|
|
2285
|
+
md: "h-6 min-w-6 px-1.5 text-[0.78rem]"
|
|
2286
|
+
}
|
|
2287
|
+
},
|
|
2288
|
+
defaultVariants: { size: "sm" }
|
|
2289
|
+
}
|
|
2290
|
+
);
|
|
2291
|
+
var Kbd = React18.forwardRef(
|
|
2292
|
+
({ className, size, keys, children, ...props }, ref) => {
|
|
2293
|
+
if (keys && keys.length > 0) {
|
|
2294
|
+
return /* @__PURE__ */ jsx(
|
|
2295
|
+
"span",
|
|
2296
|
+
{
|
|
2297
|
+
ref,
|
|
2298
|
+
className: cn("inline-flex items-center gap-1", className),
|
|
2299
|
+
...props,
|
|
2300
|
+
children: keys.map((k, i) => /* @__PURE__ */ jsx("kbd", { className: kbdVariants({ size }), children: k }, i))
|
|
2301
|
+
}
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
return /* @__PURE__ */ jsx("kbd", { ref, className: cn(kbdVariants({ size }), className), ...props, children });
|
|
2305
|
+
}
|
|
2306
|
+
);
|
|
2307
|
+
Kbd.displayName = "Kbd";
|
|
2308
|
+
var CodeBlock = React18.forwardRef(
|
|
2309
|
+
({ className, code, language, filename, copyable = true, maxHeight, ...props }, ref) => {
|
|
2310
|
+
const [copied, setCopied] = React18.useState(false);
|
|
2311
|
+
const canCopy = copyable && typeof navigator !== "undefined" && !!navigator.clipboard;
|
|
2312
|
+
const onCopy = () => {
|
|
2313
|
+
navigator.clipboard.writeText(code).then(
|
|
2314
|
+
() => {
|
|
2315
|
+
setCopied(true);
|
|
2316
|
+
window.setTimeout(() => setCopied(false), 1500);
|
|
2317
|
+
},
|
|
2318
|
+
() => {
|
|
2319
|
+
}
|
|
2320
|
+
);
|
|
2321
|
+
};
|
|
2322
|
+
const label = filename ?? language;
|
|
2323
|
+
return /* @__PURE__ */ jsxs(
|
|
2324
|
+
"div",
|
|
2325
|
+
{
|
|
2326
|
+
ref,
|
|
2327
|
+
className: cn("rounded-kj-md border border-border bg-muted/50 overflow-hidden", className),
|
|
2328
|
+
...props,
|
|
2329
|
+
children: [
|
|
2330
|
+
(label || canCopy) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3.5 py-2 border-b border-border", children: [
|
|
2331
|
+
/* @__PURE__ */ jsx("span", { className: "text-[0.72rem] font-mono text-muted-foreground", children: label }),
|
|
2332
|
+
canCopy && /* @__PURE__ */ jsx(
|
|
2333
|
+
"button",
|
|
2334
|
+
{
|
|
2335
|
+
type: "button",
|
|
2336
|
+
onClick: onCopy,
|
|
2337
|
+
className: "text-[0.72rem] font-medium text-muted-foreground hover:text-foreground transition-colors cursor-pointer bg-transparent border-0 p-0",
|
|
2338
|
+
children: copied ? "Copied" : "Copy"
|
|
2339
|
+
}
|
|
2340
|
+
)
|
|
2341
|
+
] }),
|
|
2342
|
+
/* @__PURE__ */ jsx(
|
|
2343
|
+
"pre",
|
|
2344
|
+
{
|
|
2345
|
+
className: "m-0 px-3.5 py-3 overflow-x-auto text-[0.8rem] leading-relaxed font-mono text-foreground",
|
|
2346
|
+
style: maxHeight ? { maxHeight, overflowY: "auto" } : void 0,
|
|
2347
|
+
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
2348
|
+
}
|
|
2349
|
+
)
|
|
2350
|
+
]
|
|
2351
|
+
}
|
|
2352
|
+
);
|
|
2353
|
+
}
|
|
2354
|
+
);
|
|
2355
|
+
CodeBlock.displayName = "CodeBlock";
|
|
2356
|
+
var PopoverContext = React18.createContext(null);
|
|
2357
|
+
function usePopoverContext(part) {
|
|
2358
|
+
const ctx = React18.useContext(PopoverContext);
|
|
2359
|
+
if (!ctx) throw new Error(`${part} must be used inside <Popover>`);
|
|
2360
|
+
return ctx;
|
|
2361
|
+
}
|
|
2362
|
+
function Popover({ children, className, open: openProp, onOpenChange }) {
|
|
2363
|
+
const [openState, setOpenState] = React18.useState(false);
|
|
2364
|
+
const controlled = openProp !== void 0;
|
|
2365
|
+
const open = controlled ? openProp : openState;
|
|
2366
|
+
const triggerRef = React18.useRef(null);
|
|
2367
|
+
const ref = React18.useRef(null);
|
|
2368
|
+
const setOpen = React18.useCallback(
|
|
2369
|
+
(v) => {
|
|
2370
|
+
if (!controlled) setOpenState(v);
|
|
2371
|
+
onOpenChange?.(v);
|
|
2372
|
+
},
|
|
2373
|
+
[controlled, onOpenChange]
|
|
2374
|
+
);
|
|
2375
|
+
React18.useEffect(() => {
|
|
2376
|
+
if (!open) return;
|
|
2377
|
+
const onDoc = (e) => {
|
|
2378
|
+
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
2379
|
+
};
|
|
2380
|
+
const onEsc = (e) => {
|
|
2381
|
+
if (e.key === "Escape") {
|
|
2382
|
+
setOpen(false);
|
|
2383
|
+
triggerRef.current?.focus();
|
|
2384
|
+
}
|
|
2385
|
+
};
|
|
2386
|
+
document.addEventListener("mousedown", onDoc);
|
|
2387
|
+
document.addEventListener("keydown", onEsc);
|
|
2388
|
+
return () => {
|
|
2389
|
+
document.removeEventListener("mousedown", onDoc);
|
|
2390
|
+
document.removeEventListener("keydown", onEsc);
|
|
2391
|
+
};
|
|
2392
|
+
}, [open, setOpen]);
|
|
2393
|
+
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef }, children: /* @__PURE__ */ jsx("div", { ref, className: cn("relative inline-block", className), children }) });
|
|
2394
|
+
}
|
|
2395
|
+
var PopoverTrigger = React18.forwardRef(({ onClick, asChild, ...props }, ref) => {
|
|
2396
|
+
const ctx = usePopoverContext("PopoverTrigger");
|
|
2397
|
+
const setRefs = (node) => {
|
|
2398
|
+
ctx.triggerRef.current = node;
|
|
2399
|
+
if (typeof ref === "function") ref(node);
|
|
2400
|
+
else if (ref) ref.current = node;
|
|
2401
|
+
};
|
|
2402
|
+
if (asChild) {
|
|
2403
|
+
const child = React18.Children.only(props.children);
|
|
2404
|
+
return React18.cloneElement(child, {
|
|
2405
|
+
ref: setRefs,
|
|
2406
|
+
...props,
|
|
2407
|
+
...child.props,
|
|
2408
|
+
onClick: (e) => {
|
|
2409
|
+
ctx.setOpen(!ctx.open);
|
|
2410
|
+
onClick?.(e);
|
|
2411
|
+
child.props.onClick?.(e);
|
|
2412
|
+
},
|
|
2413
|
+
"aria-haspopup": "dialog",
|
|
2414
|
+
"aria-expanded": ctx.open
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
return /* @__PURE__ */ jsx(
|
|
2418
|
+
"button",
|
|
2419
|
+
{
|
|
2420
|
+
ref: setRefs,
|
|
2421
|
+
...props,
|
|
2422
|
+
type: "button",
|
|
2423
|
+
"aria-haspopup": "dialog",
|
|
2424
|
+
"aria-expanded": ctx.open,
|
|
2425
|
+
onClick: (e) => {
|
|
2426
|
+
ctx.setOpen(!ctx.open);
|
|
2427
|
+
onClick?.(e);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
);
|
|
2431
|
+
});
|
|
2432
|
+
PopoverTrigger.displayName = "PopoverTrigger";
|
|
2433
|
+
var sideAlignClasses = {
|
|
2434
|
+
"bottom-start": "top-[calc(100%+6px)] left-0",
|
|
2435
|
+
"bottom-center": "top-[calc(100%+6px)] left-1/2 -translate-x-1/2",
|
|
2436
|
+
"bottom-end": "top-[calc(100%+6px)] right-0",
|
|
2437
|
+
"top-start": "bottom-[calc(100%+6px)] left-0",
|
|
2438
|
+
"top-center": "bottom-[calc(100%+6px)] left-1/2 -translate-x-1/2",
|
|
2439
|
+
"top-end": "bottom-[calc(100%+6px)] right-0",
|
|
2440
|
+
"left-start": "right-[calc(100%+6px)] top-0",
|
|
2441
|
+
"left-center": "right-[calc(100%+6px)] top-1/2 -translate-y-1/2",
|
|
2442
|
+
"left-end": "right-[calc(100%+6px)] bottom-0",
|
|
2443
|
+
"right-start": "left-[calc(100%+6px)] top-0",
|
|
2444
|
+
"right-center": "left-[calc(100%+6px)] top-1/2 -translate-y-1/2",
|
|
2445
|
+
"right-end": "left-[calc(100%+6px)] bottom-0"
|
|
2446
|
+
};
|
|
2447
|
+
function PopoverContent({
|
|
2448
|
+
className,
|
|
2449
|
+
side = "bottom",
|
|
2450
|
+
align = "center",
|
|
2451
|
+
children,
|
|
2452
|
+
...props
|
|
2453
|
+
}) {
|
|
2454
|
+
const ctx = usePopoverContext("PopoverContent");
|
|
2455
|
+
const ref = React18.useRef(null);
|
|
2456
|
+
React18.useEffect(() => {
|
|
2457
|
+
if (ctx.open) ref.current?.focus();
|
|
2458
|
+
}, [ctx.open]);
|
|
2459
|
+
if (!ctx.open) return null;
|
|
2460
|
+
return /* @__PURE__ */ jsx(
|
|
2461
|
+
"div",
|
|
2462
|
+
{
|
|
2463
|
+
ref,
|
|
2464
|
+
role: "dialog",
|
|
2465
|
+
tabIndex: -1,
|
|
2466
|
+
className: cn(
|
|
2467
|
+
"absolute z-40 min-w-[200px] p-4 rounded-kj-md bg-surface border border-border shadow-kj-lg outline-none",
|
|
2468
|
+
"animate-[kjpop_.12s_ease]",
|
|
2469
|
+
sideAlignClasses[`${side}-${align}`],
|
|
2470
|
+
className
|
|
2471
|
+
),
|
|
2472
|
+
...props,
|
|
2473
|
+
children
|
|
2474
|
+
}
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
2016
2477
|
|
|
2017
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, Avatar, AvatarGroup, Badge, BottomNavigation, Breadcrumb, BreadcrumbItem, BreadcrumbSeparator, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxField, CommandPalette, ConfirmDialog, DashboardShell, DataTable, DetailPageLayout, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptyState, ErrorState, Field, FormField, Hint, Input, Label, MetricCard, Modal, ModalActions, ModalDescription, ModalTitle, PageHeader, Pagination, Progress, Radio, Segmented, Select, SelectField, SettingsLayout, SidebarNav, Skeleton, Slider, Spinner, Stat, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, TableToolbar, TableWrap, Tabs, TabsContent, TabsList, TabsTrigger, TextField, Textarea, ToastProvider, Tooltip, badgeVariants, buttonVariants, cn, sliderThumbCSS, useToast };
|
|
2478
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, Avatar, AvatarGroup, Badge, BottomNavigation, BottomSheet, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHeader, BottomSheetTitle, Breadcrumb, BreadcrumbItem, BreadcrumbSeparator, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxField, CodeBlock, CommandPalette, ConfirmDialog, DashboardShell, DataTable, DetailPageLayout, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptyState, ErrorState, Fab, Field, FormField, Hint, Input, Kbd, Label, MetricCard, Modal, ModalActions, ModalDescription, ModalTitle, PageHeader, Pagination, Popover, PopoverContent, PopoverTrigger, Progress, Radio, Segmented, Select, SelectField, SettingsLayout, SidebarNav, Skeleton, Slider, Spinner, Stat, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, TableToolbar, TableWrap, Tabs, TabsContent, TabsList, TabsTrigger, TextField, Textarea, ToastProvider, Tooltip, badgeVariants, buttonVariants, cn, sliderThumbCSS, useToast };
|
|
2018
2479
|
//# sourceMappingURL=index.js.map
|
|
2019
2480
|
//# sourceMappingURL=index.js.map
|