@hyddenlabs/hydn-ui 0.3.0-alpha.1 → 0.3.0-fix-animation-drawer.1
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 +317 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +242 -66
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -264,8 +264,11 @@ type NavProps = {
|
|
|
264
264
|
children: React__default.ReactNode;
|
|
265
265
|
className?: string;
|
|
266
266
|
ariaLabel?: string;
|
|
267
|
+
direction?: 'horizontal' | 'vertical';
|
|
268
|
+
spacing?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
269
|
+
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
267
270
|
};
|
|
268
|
-
declare function Nav({ children, className, ariaLabel }: Readonly<NavProps>): react_jsx_runtime.JSX.Element;
|
|
271
|
+
declare function Nav({ children, className, ariaLabel, direction, spacing, align }: Readonly<NavProps>): react_jsx_runtime.JSX.Element;
|
|
269
272
|
declare namespace Nav {
|
|
270
273
|
var displayName: string;
|
|
271
274
|
}
|
|
@@ -433,8 +436,9 @@ type ModalProps = {
|
|
|
433
436
|
className?: string;
|
|
434
437
|
ariaLabel?: string;
|
|
435
438
|
align?: 'center' | 'top';
|
|
439
|
+
portalRoot?: HTMLElement | null;
|
|
436
440
|
};
|
|
437
|
-
declare function Modal({ isOpen, onClose, children, title, description, content, actions, className, ariaLabel, align }: Readonly<ModalProps>): react_jsx_runtime.JSX.Element | null;
|
|
441
|
+
declare function Modal({ isOpen, onClose, children, title, description, content, actions, className, ariaLabel, align, portalRoot }: Readonly<ModalProps>): react_jsx_runtime.JSX.Element | null;
|
|
438
442
|
declare namespace Modal {
|
|
439
443
|
var displayName: string;
|
|
440
444
|
}
|
|
@@ -487,8 +491,10 @@ type AlertProps = {
|
|
|
487
491
|
dismissible?: boolean;
|
|
488
492
|
onClose?: () => void;
|
|
489
493
|
className?: string;
|
|
494
|
+
position?: 'top' | 'bottom' | 'relative';
|
|
495
|
+
duration?: number;
|
|
490
496
|
};
|
|
491
|
-
declare function Alert({ children, type, dismissible, onClose, className }: Readonly<AlertProps>): react_jsx_runtime.JSX.Element;
|
|
497
|
+
declare function Alert({ children, type, dismissible, onClose, className, position, duration }: Readonly<AlertProps>): react_jsx_runtime.JSX.Element;
|
|
492
498
|
declare namespace Alert {
|
|
493
499
|
var displayName: string;
|
|
494
500
|
}
|
|
@@ -883,8 +889,10 @@ type ContainerProps = {
|
|
|
883
889
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
884
890
|
padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
885
891
|
align?: 'start' | 'center' | 'end';
|
|
892
|
+
minWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' | string;
|
|
893
|
+
minHeight?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'screen' | string;
|
|
886
894
|
};
|
|
887
|
-
declare function Container({ children, className, size, padding, align }: Readonly<ContainerProps>): react_jsx_runtime.JSX.Element;
|
|
895
|
+
declare function Container({ children, className, size, padding, align, minWidth, minHeight }: Readonly<ContainerProps>): react_jsx_runtime.JSX.Element;
|
|
888
896
|
declare namespace Container {
|
|
889
897
|
var displayName: string;
|
|
890
898
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -264,8 +264,11 @@ type NavProps = {
|
|
|
264
264
|
children: React__default.ReactNode;
|
|
265
265
|
className?: string;
|
|
266
266
|
ariaLabel?: string;
|
|
267
|
+
direction?: 'horizontal' | 'vertical';
|
|
268
|
+
spacing?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
269
|
+
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
267
270
|
};
|
|
268
|
-
declare function Nav({ children, className, ariaLabel }: Readonly<NavProps>): react_jsx_runtime.JSX.Element;
|
|
271
|
+
declare function Nav({ children, className, ariaLabel, direction, spacing, align }: Readonly<NavProps>): react_jsx_runtime.JSX.Element;
|
|
269
272
|
declare namespace Nav {
|
|
270
273
|
var displayName: string;
|
|
271
274
|
}
|
|
@@ -433,8 +436,9 @@ type ModalProps = {
|
|
|
433
436
|
className?: string;
|
|
434
437
|
ariaLabel?: string;
|
|
435
438
|
align?: 'center' | 'top';
|
|
439
|
+
portalRoot?: HTMLElement | null;
|
|
436
440
|
};
|
|
437
|
-
declare function Modal({ isOpen, onClose, children, title, description, content, actions, className, ariaLabel, align }: Readonly<ModalProps>): react_jsx_runtime.JSX.Element | null;
|
|
441
|
+
declare function Modal({ isOpen, onClose, children, title, description, content, actions, className, ariaLabel, align, portalRoot }: Readonly<ModalProps>): react_jsx_runtime.JSX.Element | null;
|
|
438
442
|
declare namespace Modal {
|
|
439
443
|
var displayName: string;
|
|
440
444
|
}
|
|
@@ -487,8 +491,10 @@ type AlertProps = {
|
|
|
487
491
|
dismissible?: boolean;
|
|
488
492
|
onClose?: () => void;
|
|
489
493
|
className?: string;
|
|
494
|
+
position?: 'top' | 'bottom' | 'relative';
|
|
495
|
+
duration?: number;
|
|
490
496
|
};
|
|
491
|
-
declare function Alert({ children, type, dismissible, onClose, className }: Readonly<AlertProps>): react_jsx_runtime.JSX.Element;
|
|
497
|
+
declare function Alert({ children, type, dismissible, onClose, className, position, duration }: Readonly<AlertProps>): react_jsx_runtime.JSX.Element;
|
|
492
498
|
declare namespace Alert {
|
|
493
499
|
var displayName: string;
|
|
494
500
|
}
|
|
@@ -883,8 +889,10 @@ type ContainerProps = {
|
|
|
883
889
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
884
890
|
padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
885
891
|
align?: 'start' | 'center' | 'end';
|
|
892
|
+
minWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' | string;
|
|
893
|
+
minHeight?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'screen' | string;
|
|
886
894
|
};
|
|
887
|
-
declare function Container({ children, className, size, padding, align }: Readonly<ContainerProps>): react_jsx_runtime.JSX.Element;
|
|
895
|
+
declare function Container({ children, className, size, padding, align, minWidth, minHeight }: Readonly<ContainerProps>): react_jsx_runtime.JSX.Element;
|
|
888
896
|
declare namespace Container {
|
|
889
897
|
var displayName: string;
|
|
890
898
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import React5, { createContext, useId, useState, useRef, useEffect, isValidElement, cloneElement, useCallback, useLayoutEffect, useMemo, createElement, useContext } from 'react';
|
|
3
3
|
import { IconX, IconChevronDown, IconCheck, IconCalendar, IconMenu2, IconTrash, IconChevronRight, IconChevronLeft, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
4
4
|
import { Link, NavLink } from 'react-router-dom';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
@@ -263,7 +263,8 @@ function Radio({
|
|
|
263
263
|
success: "border-success focus:ring-success",
|
|
264
264
|
warning: "border-warning focus:ring-warning"
|
|
265
265
|
};
|
|
266
|
-
const
|
|
266
|
+
const generatedId = useId();
|
|
267
|
+
const inputId = id || `radio-${value || generatedId}`;
|
|
267
268
|
return /* @__PURE__ */ jsxs(
|
|
268
269
|
"div",
|
|
269
270
|
{
|
|
@@ -277,7 +278,7 @@ function Radio({
|
|
|
277
278
|
onChange: handleChange,
|
|
278
279
|
disabled,
|
|
279
280
|
"aria-label": ariaLabel,
|
|
280
|
-
"aria-invalid": validationState === "error",
|
|
281
|
+
"aria-invalid": validationState === "error" ? "true" : void 0,
|
|
281
282
|
id: inputId,
|
|
282
283
|
name,
|
|
283
284
|
value,
|
|
@@ -1176,8 +1177,31 @@ function DatePicker({
|
|
|
1176
1177
|
}
|
|
1177
1178
|
DatePicker.displayName = "DatePicker";
|
|
1178
1179
|
var date_picker_default = DatePicker;
|
|
1179
|
-
function Nav({
|
|
1180
|
-
|
|
1180
|
+
function Nav({
|
|
1181
|
+
children,
|
|
1182
|
+
className = "",
|
|
1183
|
+
ariaLabel = "Main navigation",
|
|
1184
|
+
direction = "horizontal",
|
|
1185
|
+
spacing = "md",
|
|
1186
|
+
align = "center"
|
|
1187
|
+
}) {
|
|
1188
|
+
const spacingClasses = {
|
|
1189
|
+
none: "gap-0",
|
|
1190
|
+
sm: "gap-2",
|
|
1191
|
+
md: "gap-4",
|
|
1192
|
+
lg: "gap-6",
|
|
1193
|
+
xl: "gap-8"
|
|
1194
|
+
};
|
|
1195
|
+
const alignClasses = {
|
|
1196
|
+
start: "items-start",
|
|
1197
|
+
center: "items-center",
|
|
1198
|
+
end: "items-end",
|
|
1199
|
+
stretch: "items-stretch"
|
|
1200
|
+
};
|
|
1201
|
+
const directionClass = direction === "horizontal" ? "flex-row" : "flex-col";
|
|
1202
|
+
const spacingClass = spacingClasses[spacing];
|
|
1203
|
+
const alignClass = alignClasses[align];
|
|
1204
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, className: `flex ${directionClass} ${spacingClass} ${alignClass} ${className}`, children });
|
|
1181
1205
|
}
|
|
1182
1206
|
Nav.displayName = "Nav";
|
|
1183
1207
|
var nav_default = Nav;
|
|
@@ -1186,7 +1210,9 @@ function Container({
|
|
|
1186
1210
|
className = "",
|
|
1187
1211
|
size = "lg",
|
|
1188
1212
|
padding = "lg",
|
|
1189
|
-
align = "center"
|
|
1213
|
+
align = "center",
|
|
1214
|
+
minWidth,
|
|
1215
|
+
minHeight
|
|
1190
1216
|
}) {
|
|
1191
1217
|
const sizeClasses = {
|
|
1192
1218
|
sm: "max-w-screen-sm",
|
|
@@ -1207,7 +1233,54 @@ function Container({
|
|
|
1207
1233
|
center: "mx-auto",
|
|
1208
1234
|
end: "ml-auto"
|
|
1209
1235
|
};
|
|
1210
|
-
|
|
1236
|
+
const minWidthClasses = {
|
|
1237
|
+
xs: "min-w-[20rem]",
|
|
1238
|
+
// 320px
|
|
1239
|
+
sm: "min-w-[24rem]",
|
|
1240
|
+
// 384px
|
|
1241
|
+
md: "min-w-[28rem]",
|
|
1242
|
+
// 448px
|
|
1243
|
+
lg: "min-w-[32rem]",
|
|
1244
|
+
// 512px
|
|
1245
|
+
xl: "min-w-[36rem]",
|
|
1246
|
+
// 576px
|
|
1247
|
+
"2xl": "min-w-[42rem]",
|
|
1248
|
+
// 672px
|
|
1249
|
+
"3xl": "min-w-[48rem]",
|
|
1250
|
+
// 768px
|
|
1251
|
+
full: "min-w-full"
|
|
1252
|
+
};
|
|
1253
|
+
const minHeightClasses = {
|
|
1254
|
+
xs: "min-h-[10rem]",
|
|
1255
|
+
// 160px
|
|
1256
|
+
sm: "min-h-[15rem]",
|
|
1257
|
+
// 240px
|
|
1258
|
+
md: "min-h-[20rem]",
|
|
1259
|
+
// 320px
|
|
1260
|
+
lg: "min-h-[25rem]",
|
|
1261
|
+
// 400px
|
|
1262
|
+
xl: "min-h-[30rem]",
|
|
1263
|
+
// 480px
|
|
1264
|
+
"2xl": "min-h-[35rem]",
|
|
1265
|
+
// 560px
|
|
1266
|
+
"3xl": "min-h-[40rem]",
|
|
1267
|
+
// 640px
|
|
1268
|
+
screen: "min-h-screen"
|
|
1269
|
+
};
|
|
1270
|
+
const minWidthClass = minWidth && minWidthClasses[minWidth] ? minWidthClasses[minWidth] : "";
|
|
1271
|
+
const minHeightClass = minHeight && minHeightClasses[minHeight] ? minHeightClasses[minHeight] : "";
|
|
1272
|
+
const inlineStyles = {
|
|
1273
|
+
...minWidth && !minWidthClasses[minWidth] && { minWidth },
|
|
1274
|
+
...minHeight && !minHeightClasses[minHeight] && { minHeight }
|
|
1275
|
+
};
|
|
1276
|
+
return /* @__PURE__ */ jsx(
|
|
1277
|
+
"div",
|
|
1278
|
+
{
|
|
1279
|
+
className: `px-4 ${sizeClasses[size]} ${paddingClasses[padding]} ${alignClasses[align]} ${minWidthClass} ${minHeightClass} ${className}`,
|
|
1280
|
+
style: Object.keys(inlineStyles).length > 0 ? inlineStyles : void 0,
|
|
1281
|
+
children
|
|
1282
|
+
}
|
|
1283
|
+
);
|
|
1211
1284
|
}
|
|
1212
1285
|
Container.displayName = "Container";
|
|
1213
1286
|
var container_default = Container;
|
|
@@ -1317,8 +1390,8 @@ var PageTransition = ({
|
|
|
1317
1390
|
type = "fade",
|
|
1318
1391
|
className = ""
|
|
1319
1392
|
}) => {
|
|
1320
|
-
const [isVisible, setIsVisible] =
|
|
1321
|
-
|
|
1393
|
+
const [isVisible, setIsVisible] = React5.useState(false);
|
|
1394
|
+
React5.useEffect(() => {
|
|
1322
1395
|
requestAnimationFrame(() => {
|
|
1323
1396
|
requestAnimationFrame(() => {
|
|
1324
1397
|
setIsVisible(true);
|
|
@@ -1440,20 +1513,34 @@ function Dropdown({
|
|
|
1440
1513
|
document.addEventListener("mousedown", handleClickOutside);
|
|
1441
1514
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1442
1515
|
}, [isOpen, close]);
|
|
1443
|
-
|
|
1516
|
+
useLayoutEffect(() => {
|
|
1517
|
+
let raf;
|
|
1444
1518
|
if (isOpen) {
|
|
1445
1519
|
const itemEls = itemsRef.current.filter(Boolean);
|
|
1446
1520
|
if (itemEls.length) {
|
|
1447
|
-
|
|
1448
|
-
|
|
1521
|
+
raf = requestAnimationFrame(() => {
|
|
1522
|
+
setActiveIndex(0);
|
|
1523
|
+
itemEls[0]?.focus();
|
|
1524
|
+
});
|
|
1449
1525
|
}
|
|
1450
1526
|
} else {
|
|
1451
|
-
setActiveIndex(-1);
|
|
1527
|
+
raf = requestAnimationFrame(() => setActiveIndex(-1));
|
|
1452
1528
|
}
|
|
1529
|
+
return () => {
|
|
1530
|
+
if (raf) cancelAnimationFrame(raf);
|
|
1531
|
+
};
|
|
1453
1532
|
}, [isOpen]);
|
|
1454
|
-
const registerItem = (el, index) => {
|
|
1455
|
-
|
|
1456
|
-
|
|
1533
|
+
const registerItem = useCallback((el, index) => {
|
|
1534
|
+
if (typeof index === "number" && index >= 0) {
|
|
1535
|
+
itemsRef.current[index] = el;
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
if (el === null) {
|
|
1539
|
+
itemsRef.current = itemsRef.current.filter((x) => x !== el && x != null);
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
if (!itemsRef.current.includes(el)) itemsRef.current.push(el);
|
|
1543
|
+
}, []);
|
|
1457
1544
|
return /* @__PURE__ */ jsxs("div", { ref: dropdownRef, className: `relative ${className}`, children: [
|
|
1458
1545
|
/* @__PURE__ */ jsx(
|
|
1459
1546
|
"button",
|
|
@@ -1468,7 +1555,7 @@ function Dropdown({
|
|
|
1468
1555
|
children: trigger
|
|
1469
1556
|
}
|
|
1470
1557
|
),
|
|
1471
|
-
isOpen && /* @__PURE__ */ jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose }, children: /* @__PURE__ */ jsx(
|
|
1558
|
+
isOpen && /* @__PURE__ */ jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose, registerItem }, children: /* @__PURE__ */ jsx(
|
|
1472
1559
|
"div",
|
|
1473
1560
|
{
|
|
1474
1561
|
id: "dropdown-menu",
|
|
@@ -1477,10 +1564,7 @@ function Dropdown({
|
|
|
1477
1564
|
role: "menu",
|
|
1478
1565
|
"aria-orientation": "vertical",
|
|
1479
1566
|
tabIndex: -1,
|
|
1480
|
-
children
|
|
1481
|
-
if (!React3.isValidElement(child)) return child;
|
|
1482
|
-
return React3.cloneElement(child, { __dropdownIndex: i, __registerItem: registerItem, size });
|
|
1483
|
-
})
|
|
1567
|
+
children
|
|
1484
1568
|
}
|
|
1485
1569
|
) })
|
|
1486
1570
|
] });
|
|
@@ -1576,6 +1660,22 @@ Pagination.displayName = "Pagination";
|
|
|
1576
1660
|
var pagination_default = Pagination;
|
|
1577
1661
|
function Sidebar({ children, className = "", width = "16rem" }) {
|
|
1578
1662
|
const widthClass = width === "16rem" ? "w-64" : width === "4rem" ? "w-16" : "";
|
|
1663
|
+
const enhancedChildren = React5.Children.map(children, (child) => {
|
|
1664
|
+
if (!React5.isValidElement(child)) return child;
|
|
1665
|
+
const childProps = child.props || {};
|
|
1666
|
+
if ("href" in childProps) {
|
|
1667
|
+
const existing = typeof childProps.className === "string" ? childProps.className : "";
|
|
1668
|
+
const sidebarItemClasses = "flex items-center w-full justify-start gap-2 px-2 py-1.5 rounded hover:bg-muted";
|
|
1669
|
+
const childInner = child.props.children;
|
|
1670
|
+
const wrappedChildren = /* @__PURE__ */ jsx("span", { className: "flex items-center gap-2", children: childInner });
|
|
1671
|
+
const newProps = {
|
|
1672
|
+
...child.props,
|
|
1673
|
+
className: `${existing} ${sidebarItemClasses}`.trim()
|
|
1674
|
+
};
|
|
1675
|
+
return React5.cloneElement(child, newProps, wrappedChildren);
|
|
1676
|
+
}
|
|
1677
|
+
return child;
|
|
1678
|
+
});
|
|
1579
1679
|
return /* @__PURE__ */ jsx(
|
|
1580
1680
|
"nav",
|
|
1581
1681
|
{
|
|
@@ -1588,7 +1688,7 @@ function Sidebar({ children, className = "", width = "16rem" }) {
|
|
|
1588
1688
|
`.replace(/\s+/g, " "),
|
|
1589
1689
|
style: !widthClass ? { width } : void 0,
|
|
1590
1690
|
"aria-label": "Sidebar navigation",
|
|
1591
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex-1 px-4 py-3
|
|
1691
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex-1 px-4 py-3 flex flex-col gap-2", children: enhancedChildren })
|
|
1592
1692
|
}
|
|
1593
1693
|
);
|
|
1594
1694
|
}
|
|
@@ -1756,6 +1856,12 @@ function Toast({ message, children, type = "info", onClose, className = "", dura
|
|
|
1756
1856
|
warning: "bg-warning text-warning-foreground",
|
|
1757
1857
|
error: "bg-destructive text-destructive-foreground"
|
|
1758
1858
|
};
|
|
1859
|
+
const handleClose = useCallback(() => {
|
|
1860
|
+
setIsClosing(true);
|
|
1861
|
+
setTimeout(() => {
|
|
1862
|
+
onClose?.();
|
|
1863
|
+
}, 300);
|
|
1864
|
+
}, [onClose]);
|
|
1759
1865
|
useEffect(() => {
|
|
1760
1866
|
if (duration > 0) {
|
|
1761
1867
|
const timer = setTimeout(() => {
|
|
@@ -1764,25 +1870,20 @@ function Toast({ message, children, type = "info", onClose, className = "", dura
|
|
|
1764
1870
|
return () => clearTimeout(timer);
|
|
1765
1871
|
}
|
|
1766
1872
|
return void 0;
|
|
1767
|
-
}, [duration]);
|
|
1768
|
-
const
|
|
1769
|
-
setIsClosing(true);
|
|
1770
|
-
setTimeout(() => {
|
|
1771
|
-
onClose?.();
|
|
1772
|
-
}, 300);
|
|
1773
|
-
};
|
|
1774
|
-
return /* @__PURE__ */ jsxs(
|
|
1873
|
+
}, [duration, handleClose]);
|
|
1874
|
+
const toast = /* @__PURE__ */ jsxs(
|
|
1775
1875
|
"div",
|
|
1776
1876
|
{
|
|
1777
1877
|
role: "alert",
|
|
1778
1878
|
"aria-live": "polite",
|
|
1779
|
-
className: `fixed bottom-4 right-4 px-4 py-3 rounded-md shadow-lg ${typeClasses[type]} transition-all duration-300 ease-out ${isClosing ? "opacity-0 translate-x-full" : "opacity-100 translate-x-0 animate-slideInRight"} ${className}`,
|
|
1879
|
+
className: `fixed bottom-4 right-4 px-4 py-3 rounded-md shadow-lg z-[9999] ${typeClasses[type]} transition-all duration-300 ease-out ${isClosing ? "opacity-0 translate-x-full" : "opacity-100 translate-x-0 animate-slideInRight"} ${className}`,
|
|
1780
1880
|
children: [
|
|
1781
1881
|
/* @__PURE__ */ jsx("span", { children: children || message }),
|
|
1782
1882
|
onClose && /* @__PURE__ */ jsx("button", { onClick: handleClose, className: "ml-4 font-bold hover:opacity-70 transition-opacity", "aria-label": "Close", children: "\xD7" })
|
|
1783
1883
|
]
|
|
1784
1884
|
}
|
|
1785
1885
|
);
|
|
1886
|
+
return typeof document !== "undefined" ? createPortal(toast, document.body) : toast;
|
|
1786
1887
|
}
|
|
1787
1888
|
Toast.displayName = "Toast";
|
|
1788
1889
|
var toast_default = Toast;
|
|
@@ -1908,6 +2009,19 @@ function Tooltip({
|
|
|
1908
2009
|
}
|
|
1909
2010
|
Tooltip.displayName = "Tooltip";
|
|
1910
2011
|
var tooltip_default = Tooltip;
|
|
2012
|
+
|
|
2013
|
+
// src/utils/portal.ts
|
|
2014
|
+
function getPortalRoot(id = "hydn-ui-portal") {
|
|
2015
|
+
if (typeof document === "undefined") return null;
|
|
2016
|
+
let root = document.getElementById(id);
|
|
2017
|
+
if (!root) {
|
|
2018
|
+
root = document.createElement("div");
|
|
2019
|
+
root.id = id;
|
|
2020
|
+
document.body.appendChild(root);
|
|
2021
|
+
}
|
|
2022
|
+
return root;
|
|
2023
|
+
}
|
|
2024
|
+
var portal_default = getPortalRoot;
|
|
1911
2025
|
function useOverlay(options) {
|
|
1912
2026
|
const {
|
|
1913
2027
|
isOpen,
|
|
@@ -1923,9 +2037,10 @@ function useOverlay(options) {
|
|
|
1923
2037
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
1924
2038
|
const [phase, setPhase] = useState("mount");
|
|
1925
2039
|
useLayoutEffect(() => {
|
|
1926
|
-
if (isOpen) {
|
|
2040
|
+
if (isOpen && !shouldRender) {
|
|
1927
2041
|
setShouldRender(true);
|
|
1928
2042
|
setPhase("mount");
|
|
2043
|
+
} else if (isOpen && shouldRender && phase === "mount") {
|
|
1929
2044
|
requestAnimationFrame(() => {
|
|
1930
2045
|
setPhase("animating-in");
|
|
1931
2046
|
let frame = 0;
|
|
@@ -1937,12 +2052,16 @@ function useOverlay(options) {
|
|
|
1937
2052
|
requestAnimationFrame(step);
|
|
1938
2053
|
}
|
|
1939
2054
|
};
|
|
1940
|
-
|
|
2055
|
+
if (animationFrames > 0) {
|
|
2056
|
+
requestAnimationFrame(step);
|
|
2057
|
+
} else {
|
|
2058
|
+
setPhase("visible");
|
|
2059
|
+
}
|
|
1941
2060
|
});
|
|
1942
|
-
} else if (!isOpen && shouldRender) {
|
|
2061
|
+
} else if (!isOpen && shouldRender && phase !== "animating-out") {
|
|
1943
2062
|
setPhase("animating-out");
|
|
1944
2063
|
}
|
|
1945
|
-
}, [isOpen, shouldRender, animationFrames]);
|
|
2064
|
+
}, [isOpen, shouldRender, phase, animationFrames]);
|
|
1946
2065
|
useEffect(() => {
|
|
1947
2066
|
if (phase === "animating-out" && unmountOnExit) {
|
|
1948
2067
|
const timeout = setTimeout(() => {
|
|
@@ -2027,7 +2146,8 @@ function Modal({
|
|
|
2027
2146
|
actions,
|
|
2028
2147
|
className = "",
|
|
2029
2148
|
ariaLabel,
|
|
2030
|
-
align = "center"
|
|
2149
|
+
align = "center",
|
|
2150
|
+
portalRoot = portal_default()
|
|
2031
2151
|
}) {
|
|
2032
2152
|
const {
|
|
2033
2153
|
phase,
|
|
@@ -2041,7 +2161,7 @@ function Modal({
|
|
|
2041
2161
|
animationFrames: 2,
|
|
2042
2162
|
restoreFocus: true
|
|
2043
2163
|
});
|
|
2044
|
-
|
|
2164
|
+
React5.useEffect(() => {
|
|
2045
2165
|
if (!isOpen) return;
|
|
2046
2166
|
const handleEscape = (e) => {
|
|
2047
2167
|
if (e.key === "Escape") {
|
|
@@ -2059,7 +2179,7 @@ function Modal({
|
|
|
2059
2179
|
const backdropOpacity = phase === "visible" || phase === "animating-in" ? "opacity-100" : "opacity-0 transition-opacity delay-50";
|
|
2060
2180
|
const hasStructured = title || description || content || actions;
|
|
2061
2181
|
const alignmentClasses = align === "center" ? "grid place-items-center" : "flex items-start justify-center pt-20";
|
|
2062
|
-
|
|
2182
|
+
const panel = /* @__PURE__ */ jsx(
|
|
2063
2183
|
"div",
|
|
2064
2184
|
{
|
|
2065
2185
|
"data-phase": phase,
|
|
@@ -2093,6 +2213,7 @@ function Modal({
|
|
|
2093
2213
|
)
|
|
2094
2214
|
}
|
|
2095
2215
|
);
|
|
2216
|
+
return portalRoot ? createPortal(panel, portalRoot) : panel;
|
|
2096
2217
|
}
|
|
2097
2218
|
Modal.displayName = "Modal";
|
|
2098
2219
|
var modal_default = Modal;
|
|
@@ -2209,12 +2330,13 @@ function Popover({ trigger, children, content, position = "bottom", className =
|
|
|
2209
2330
|
}
|
|
2210
2331
|
Popover.displayName = "Popover";
|
|
2211
2332
|
var popover_default = Popover;
|
|
2212
|
-
function Alert({ children, type = "info", dismissible = false, onClose, className = "" }) {
|
|
2333
|
+
function Alert({ children, type = "info", dismissible = false, onClose, className = "", position = "relative", duration = 0 }) {
|
|
2334
|
+
const [isClosing, setIsClosing] = useState(false);
|
|
2213
2335
|
const typeClasses = {
|
|
2214
|
-
info: "bg-info/
|
|
2215
|
-
success: "bg-success/
|
|
2216
|
-
warning: "bg-warning/
|
|
2217
|
-
error: "bg-destructive/
|
|
2336
|
+
info: "bg-info/20 text-foreground border-info/50 backdrop-blur-sm",
|
|
2337
|
+
success: "bg-success/20 text-foreground border-success/50 backdrop-blur-sm",
|
|
2338
|
+
warning: "bg-warning/20 text-foreground border-warning/50 backdrop-blur-sm",
|
|
2339
|
+
error: "bg-destructive/20 text-foreground border-destructive/50 backdrop-blur-sm"
|
|
2218
2340
|
};
|
|
2219
2341
|
const iconClasses = {
|
|
2220
2342
|
info: "text-info",
|
|
@@ -2222,6 +2344,21 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
|
|
|
2222
2344
|
warning: "text-warning",
|
|
2223
2345
|
error: "text-destructive"
|
|
2224
2346
|
};
|
|
2347
|
+
const handleClose = useCallback(() => {
|
|
2348
|
+
setIsClosing(true);
|
|
2349
|
+
setTimeout(() => {
|
|
2350
|
+
onClose?.();
|
|
2351
|
+
}, 300);
|
|
2352
|
+
}, [onClose]);
|
|
2353
|
+
useEffect(() => {
|
|
2354
|
+
if (duration > 0 && onClose) {
|
|
2355
|
+
const timer = setTimeout(() => {
|
|
2356
|
+
handleClose();
|
|
2357
|
+
}, duration);
|
|
2358
|
+
return () => clearTimeout(timer);
|
|
2359
|
+
}
|
|
2360
|
+
return void 0;
|
|
2361
|
+
}, [duration, onClose, handleClose]);
|
|
2225
2362
|
const icons = {
|
|
2226
2363
|
info: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 flex-shrink-0", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(
|
|
2227
2364
|
"path",
|
|
@@ -2256,19 +2393,44 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
|
|
|
2256
2393
|
}
|
|
2257
2394
|
) })
|
|
2258
2395
|
};
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2396
|
+
const positionClasses = {
|
|
2397
|
+
top: "fixed top-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
|
|
2398
|
+
bottom: "fixed bottom-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
|
|
2399
|
+
relative: ""
|
|
2400
|
+
};
|
|
2401
|
+
const getAnimationClasses = () => {
|
|
2402
|
+
if (position === "top") {
|
|
2403
|
+
return isClosing ? "opacity-0 -translate-y-full" : "opacity-100 translate-y-0 animate-slideInTop";
|
|
2404
|
+
}
|
|
2405
|
+
if (position === "bottom") {
|
|
2406
|
+
return isClosing ? "opacity-0 translate-y-full" : "opacity-100 translate-y-0 animate-slideInBottom";
|
|
2407
|
+
}
|
|
2408
|
+
return isClosing ? "opacity-0" : "opacity-100";
|
|
2409
|
+
};
|
|
2410
|
+
const alertContent = /* @__PURE__ */ jsxs(
|
|
2411
|
+
"div",
|
|
2412
|
+
{
|
|
2413
|
+
role: "alert",
|
|
2414
|
+
className: `p-4 border rounded-lg flex items-start gap-3 transition-all duration-300 ease-out ${typeClasses[type]} ${positionClasses[position]} ${getAnimationClasses()} ${className}`,
|
|
2415
|
+
children: [
|
|
2416
|
+
/* @__PURE__ */ jsx("span", { className: iconClasses[type], children: icons[type] }),
|
|
2417
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm", children }),
|
|
2418
|
+
dismissible && onClose && /* @__PURE__ */ jsx(
|
|
2419
|
+
"button",
|
|
2420
|
+
{
|
|
2421
|
+
onClick: handleClose,
|
|
2422
|
+
className: "flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus:ring-2 focus:ring-ring rounded p-0.5",
|
|
2423
|
+
"aria-label": "Close alert",
|
|
2424
|
+
children: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
2425
|
+
}
|
|
2426
|
+
)
|
|
2427
|
+
]
|
|
2428
|
+
}
|
|
2429
|
+
);
|
|
2430
|
+
if (position !== "relative" && typeof document !== "undefined") {
|
|
2431
|
+
return createPortal(alertContent, document.body);
|
|
2432
|
+
}
|
|
2433
|
+
return alertContent;
|
|
2272
2434
|
}
|
|
2273
2435
|
Alert.displayName = "Alert";
|
|
2274
2436
|
var alert_default = Alert;
|
|
@@ -3385,7 +3547,7 @@ function Drawer({
|
|
|
3385
3547
|
closeOnEscape = true,
|
|
3386
3548
|
closeOnOutside = true,
|
|
3387
3549
|
unmountOnExit = true,
|
|
3388
|
-
portalRoot =
|
|
3550
|
+
portalRoot = portal_default(),
|
|
3389
3551
|
noAnimation = false
|
|
3390
3552
|
}) {
|
|
3391
3553
|
const { phase, shouldRender, ref, getPhaseClass } = useOverlay_default({
|
|
@@ -3394,8 +3556,8 @@ function Drawer({
|
|
|
3394
3556
|
restoreFocus: true,
|
|
3395
3557
|
focusTrap: true,
|
|
3396
3558
|
unmountOnExit,
|
|
3397
|
-
exitDuration: noAnimation ? 0 :
|
|
3398
|
-
animationFrames: noAnimation ? 0 :
|
|
3559
|
+
exitDuration: noAnimation ? 0 : 250,
|
|
3560
|
+
animationFrames: noAnimation ? 0 : 0
|
|
3399
3561
|
});
|
|
3400
3562
|
if (!shouldRender) return null;
|
|
3401
3563
|
const sizeClasses = {
|
|
@@ -3419,7 +3581,7 @@ function Drawer({
|
|
|
3419
3581
|
};
|
|
3420
3582
|
const openTransform = "translate-x-0 translate-y-0";
|
|
3421
3583
|
const panelTransform = noAnimation ? "" : getPhaseClass(openTransform, closedTransform[position]);
|
|
3422
|
-
const overlayOpacity = noAnimation ? "" : getPhaseClass("opacity-100", "opacity-0");
|
|
3584
|
+
const overlayOpacity = noAnimation ? "opacity-100" : getPhaseClass("opacity-100", "opacity-0");
|
|
3423
3585
|
const handleKeyDown = (e) => {
|
|
3424
3586
|
if (e.key === "Escape" && closeOnEscape) {
|
|
3425
3587
|
e.stopPropagation();
|
|
@@ -3428,11 +3590,21 @@ function Drawer({
|
|
|
3428
3590
|
};
|
|
3429
3591
|
const panel = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3430
3592
|
/* @__PURE__ */ jsx(
|
|
3431
|
-
"
|
|
3593
|
+
"button",
|
|
3432
3594
|
{
|
|
3433
|
-
|
|
3434
|
-
|
|
3595
|
+
type: "button",
|
|
3596
|
+
className: `fixed inset-0 z-[999] bg-black/50 backdrop-blur-sm transition-opacity duration-[250ms] ease-in-out ${overlayOpacity} border-0 p-0 m-0`,
|
|
3597
|
+
"aria-label": closeOnOutside ? "Close overlay" : void 0,
|
|
3598
|
+
"aria-hidden": !closeOnOutside,
|
|
3599
|
+
tabIndex: closeOnOutside ? 0 : -1,
|
|
3435
3600
|
onClick: () => closeOnOutside && onClose(),
|
|
3601
|
+
onKeyDown: (e) => {
|
|
3602
|
+
if (!closeOnOutside) return;
|
|
3603
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3604
|
+
e.preventDefault();
|
|
3605
|
+
onClose();
|
|
3606
|
+
}
|
|
3607
|
+
},
|
|
3436
3608
|
"data-phase": phase
|
|
3437
3609
|
}
|
|
3438
3610
|
),
|
|
@@ -3446,7 +3618,7 @@ function Drawer({
|
|
|
3446
3618
|
tabIndex: -1,
|
|
3447
3619
|
"data-phase": phase,
|
|
3448
3620
|
"data-position": position,
|
|
3449
|
-
className: `fixed ${edgeClasses[position]} ${position === "left" || position === "right" ? sizeClasses[size] : ""} bg-card text-card-foreground shadow-2xl z-
|
|
3621
|
+
className: `fixed ${edgeClasses[position]} ${position === "left" || position === "right" ? sizeClasses[size] : ""} bg-card text-card-foreground shadow-2xl z-[1000] flex flex-col outline-none ${panelTransform} ${noAnimation ? "" : "transition-transform duration-[250ms] ease-out will-change-transform"} ${className}`,
|
|
3450
3622
|
onKeyDown: handleKeyDown,
|
|
3451
3623
|
children: [
|
|
3452
3624
|
title && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/60 bg-card/95 backdrop-blur-sm", children: [
|
|
@@ -3726,10 +3898,14 @@ function useScrollReset(deps, container) {
|
|
|
3726
3898
|
let cancelled = false;
|
|
3727
3899
|
const maxRaf = 6;
|
|
3728
3900
|
let rafCount = 0;
|
|
3901
|
+
const isRef = (obj) => {
|
|
3902
|
+
return typeof obj === "object" && obj !== null && "current" in obj;
|
|
3903
|
+
};
|
|
3729
3904
|
const setAllScrollTop = () => {
|
|
3730
3905
|
if (cancelled) return;
|
|
3731
3906
|
window.scrollTo(0, 0);
|
|
3732
|
-
|
|
3907
|
+
const resolved = isRef(container) ? container.current : container;
|
|
3908
|
+
if (resolved) resolved.scrollTop = 0;
|
|
3733
3909
|
document.documentElement.scrollTop = 0;
|
|
3734
3910
|
document.body.scrollTop = 0;
|
|
3735
3911
|
};
|
|
@@ -3796,7 +3972,7 @@ function LeftNavLayout({
|
|
|
3796
3972
|
navRef.current.scrollTop = scrollPosRef.current;
|
|
3797
3973
|
}
|
|
3798
3974
|
}, [children]);
|
|
3799
|
-
useScrollReset_default([children], contentRef
|
|
3975
|
+
useScrollReset_default([children], contentRef);
|
|
3800
3976
|
const containerClasses = embedded ? "flex bg-background border border-border rounded-lg overflow-hidden" : "flex h-[calc(100vh-4rem)] bg-background";
|
|
3801
3977
|
return /* @__PURE__ */ jsxs("div", { className: `${containerClasses} ${className}`, children: [
|
|
3802
3978
|
mobileCollapsible && mobileMenuOpen && /* @__PURE__ */ jsx(
|