@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.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var
|
|
4
|
+
var React5 = require('react');
|
|
5
5
|
var iconsReact = require('@tabler/icons-react');
|
|
6
6
|
var reactRouterDom = require('react-router-dom');
|
|
7
7
|
var reactDom = require('react-dom');
|
|
8
8
|
|
|
9
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var React5__default = /*#__PURE__*/_interopDefault(React5);
|
|
12
12
|
|
|
13
13
|
// src/components/forms/button/button.tsx
|
|
14
14
|
function Button({
|
|
@@ -221,9 +221,9 @@ function Checkbox({
|
|
|
221
221
|
}
|
|
222
222
|
Checkbox.displayName = "Checkbox";
|
|
223
223
|
var checkbox_default = Checkbox;
|
|
224
|
-
var RadioGroupContext =
|
|
224
|
+
var RadioGroupContext = React5.createContext(null);
|
|
225
225
|
var useRadioGroup = () => {
|
|
226
|
-
const context =
|
|
226
|
+
const context = React5.useContext(RadioGroupContext);
|
|
227
227
|
return context;
|
|
228
228
|
};
|
|
229
229
|
function RadioGroup({
|
|
@@ -269,7 +269,8 @@ function Radio({
|
|
|
269
269
|
success: "border-success focus:ring-success",
|
|
270
270
|
warning: "border-warning focus:ring-warning"
|
|
271
271
|
};
|
|
272
|
-
const
|
|
272
|
+
const generatedId = React5.useId();
|
|
273
|
+
const inputId = id || `radio-${value || generatedId}`;
|
|
273
274
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
274
275
|
"div",
|
|
275
276
|
{
|
|
@@ -283,7 +284,7 @@ function Radio({
|
|
|
283
284
|
onChange: handleChange,
|
|
284
285
|
disabled,
|
|
285
286
|
"aria-label": ariaLabel,
|
|
286
|
-
"aria-invalid": validationState === "error",
|
|
287
|
+
"aria-invalid": validationState === "error" ? "true" : void 0,
|
|
287
288
|
id: inputId,
|
|
288
289
|
name,
|
|
289
290
|
value,
|
|
@@ -367,13 +368,13 @@ function MultiSelect({
|
|
|
367
368
|
size = "md",
|
|
368
369
|
className = ""
|
|
369
370
|
}) {
|
|
370
|
-
const [isOpen, setIsOpen] =
|
|
371
|
-
const [searchQuery, setSearchQuery] =
|
|
372
|
-
const [focusedIndex, setFocusedIndex] =
|
|
373
|
-
const containerRef =
|
|
374
|
-
const searchInputRef =
|
|
371
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
372
|
+
const [searchQuery, setSearchQuery] = React5.useState("");
|
|
373
|
+
const [focusedIndex, setFocusedIndex] = React5.useState(-1);
|
|
374
|
+
const containerRef = React5.useRef(null);
|
|
375
|
+
const searchInputRef = React5.useRef(null);
|
|
375
376
|
const selectedValues = value || [];
|
|
376
|
-
|
|
377
|
+
React5.useEffect(() => {
|
|
377
378
|
const handleClickOutside = (event) => {
|
|
378
379
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
379
380
|
setIsOpen(false);
|
|
@@ -386,7 +387,7 @@ function MultiSelect({
|
|
|
386
387
|
}
|
|
387
388
|
return void 0;
|
|
388
389
|
}, [isOpen]);
|
|
389
|
-
|
|
390
|
+
React5.useEffect(() => {
|
|
390
391
|
if (isOpen && searchInputRef.current) {
|
|
391
392
|
searchInputRef.current.focus();
|
|
392
393
|
}
|
|
@@ -870,7 +871,7 @@ function FormField({
|
|
|
870
871
|
validationState = "default"
|
|
871
872
|
}) {
|
|
872
873
|
const effectiveValidationState = error ? "error" : validationState;
|
|
873
|
-
const childWithValidation =
|
|
874
|
+
const childWithValidation = React5.isValidElement(children) ? React5.cloneElement(children, {
|
|
874
875
|
validationState: effectiveValidationState
|
|
875
876
|
}) : children;
|
|
876
877
|
return /* @__PURE__ */ jsxRuntime.jsxs(stack_default, { direction: "vertical", spacing: "sm", className, children: [
|
|
@@ -895,8 +896,8 @@ function InputGroup({ children, prefix, suffix, className = "" }) {
|
|
|
895
896
|
InputGroup.displayName = "InputGroup";
|
|
896
897
|
var input_group_default = InputGroup;
|
|
897
898
|
function Calendar({ value, onChange, minDate, maxDate, disabled = false, className = "" }) {
|
|
898
|
-
const [currentMonth, setCurrentMonth] =
|
|
899
|
-
const [selectedDate, setSelectedDate] =
|
|
899
|
+
const [currentMonth, setCurrentMonth] = React5.useState(value || /* @__PURE__ */ new Date());
|
|
900
|
+
const [selectedDate, setSelectedDate] = React5.useState(value);
|
|
900
901
|
const getDaysInMonth = (date) => {
|
|
901
902
|
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
902
903
|
};
|
|
@@ -1032,14 +1033,14 @@ function DatePicker({
|
|
|
1032
1033
|
className = "",
|
|
1033
1034
|
size = "md"
|
|
1034
1035
|
}) {
|
|
1035
|
-
const [isOpen, setIsOpen] =
|
|
1036
|
-
const [selectedDate, setSelectedDate] =
|
|
1037
|
-
const containerRef =
|
|
1038
|
-
const inputRef =
|
|
1039
|
-
|
|
1036
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
1037
|
+
const [selectedDate, setSelectedDate] = React5.useState(value);
|
|
1038
|
+
const containerRef = React5.useRef(null);
|
|
1039
|
+
const inputRef = React5.useRef(null);
|
|
1040
|
+
React5.useEffect(() => {
|
|
1040
1041
|
setSelectedDate(value);
|
|
1041
1042
|
}, [value]);
|
|
1042
|
-
|
|
1043
|
+
React5.useEffect(() => {
|
|
1043
1044
|
const handleClickOutside = (event) => {
|
|
1044
1045
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1045
1046
|
setIsOpen(false);
|
|
@@ -1051,7 +1052,7 @@ function DatePicker({
|
|
|
1051
1052
|
}
|
|
1052
1053
|
return void 0;
|
|
1053
1054
|
}, [isOpen]);
|
|
1054
|
-
|
|
1055
|
+
React5.useEffect(() => {
|
|
1055
1056
|
const handleEscape = (event) => {
|
|
1056
1057
|
if (event.key === "Escape" && isOpen) {
|
|
1057
1058
|
setIsOpen(false);
|
|
@@ -1182,8 +1183,31 @@ function DatePicker({
|
|
|
1182
1183
|
}
|
|
1183
1184
|
DatePicker.displayName = "DatePicker";
|
|
1184
1185
|
var date_picker_default = DatePicker;
|
|
1185
|
-
function Nav({
|
|
1186
|
-
|
|
1186
|
+
function Nav({
|
|
1187
|
+
children,
|
|
1188
|
+
className = "",
|
|
1189
|
+
ariaLabel = "Main navigation",
|
|
1190
|
+
direction = "horizontal",
|
|
1191
|
+
spacing = "md",
|
|
1192
|
+
align = "center"
|
|
1193
|
+
}) {
|
|
1194
|
+
const spacingClasses = {
|
|
1195
|
+
none: "gap-0",
|
|
1196
|
+
sm: "gap-2",
|
|
1197
|
+
md: "gap-4",
|
|
1198
|
+
lg: "gap-6",
|
|
1199
|
+
xl: "gap-8"
|
|
1200
|
+
};
|
|
1201
|
+
const alignClasses = {
|
|
1202
|
+
start: "items-start",
|
|
1203
|
+
center: "items-center",
|
|
1204
|
+
end: "items-end",
|
|
1205
|
+
stretch: "items-stretch"
|
|
1206
|
+
};
|
|
1207
|
+
const directionClass = direction === "horizontal" ? "flex-row" : "flex-col";
|
|
1208
|
+
const spacingClass = spacingClasses[spacing];
|
|
1209
|
+
const alignClass = alignClasses[align];
|
|
1210
|
+
return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, className: `flex ${directionClass} ${spacingClass} ${alignClass} ${className}`, children });
|
|
1187
1211
|
}
|
|
1188
1212
|
Nav.displayName = "Nav";
|
|
1189
1213
|
var nav_default = Nav;
|
|
@@ -1192,7 +1216,9 @@ function Container({
|
|
|
1192
1216
|
className = "",
|
|
1193
1217
|
size = "lg",
|
|
1194
1218
|
padding = "lg",
|
|
1195
|
-
align = "center"
|
|
1219
|
+
align = "center",
|
|
1220
|
+
minWidth,
|
|
1221
|
+
minHeight
|
|
1196
1222
|
}) {
|
|
1197
1223
|
const sizeClasses = {
|
|
1198
1224
|
sm: "max-w-screen-sm",
|
|
@@ -1213,7 +1239,54 @@ function Container({
|
|
|
1213
1239
|
center: "mx-auto",
|
|
1214
1240
|
end: "ml-auto"
|
|
1215
1241
|
};
|
|
1216
|
-
|
|
1242
|
+
const minWidthClasses = {
|
|
1243
|
+
xs: "min-w-[20rem]",
|
|
1244
|
+
// 320px
|
|
1245
|
+
sm: "min-w-[24rem]",
|
|
1246
|
+
// 384px
|
|
1247
|
+
md: "min-w-[28rem]",
|
|
1248
|
+
// 448px
|
|
1249
|
+
lg: "min-w-[32rem]",
|
|
1250
|
+
// 512px
|
|
1251
|
+
xl: "min-w-[36rem]",
|
|
1252
|
+
// 576px
|
|
1253
|
+
"2xl": "min-w-[42rem]",
|
|
1254
|
+
// 672px
|
|
1255
|
+
"3xl": "min-w-[48rem]",
|
|
1256
|
+
// 768px
|
|
1257
|
+
full: "min-w-full"
|
|
1258
|
+
};
|
|
1259
|
+
const minHeightClasses = {
|
|
1260
|
+
xs: "min-h-[10rem]",
|
|
1261
|
+
// 160px
|
|
1262
|
+
sm: "min-h-[15rem]",
|
|
1263
|
+
// 240px
|
|
1264
|
+
md: "min-h-[20rem]",
|
|
1265
|
+
// 320px
|
|
1266
|
+
lg: "min-h-[25rem]",
|
|
1267
|
+
// 400px
|
|
1268
|
+
xl: "min-h-[30rem]",
|
|
1269
|
+
// 480px
|
|
1270
|
+
"2xl": "min-h-[35rem]",
|
|
1271
|
+
// 560px
|
|
1272
|
+
"3xl": "min-h-[40rem]",
|
|
1273
|
+
// 640px
|
|
1274
|
+
screen: "min-h-screen"
|
|
1275
|
+
};
|
|
1276
|
+
const minWidthClass = minWidth && minWidthClasses[minWidth] ? minWidthClasses[minWidth] : "";
|
|
1277
|
+
const minHeightClass = minHeight && minHeightClasses[minHeight] ? minHeightClasses[minHeight] : "";
|
|
1278
|
+
const inlineStyles = {
|
|
1279
|
+
...minWidth && !minWidthClasses[minWidth] && { minWidth },
|
|
1280
|
+
...minHeight && !minHeightClasses[minHeight] && { minHeight }
|
|
1281
|
+
};
|
|
1282
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1283
|
+
"div",
|
|
1284
|
+
{
|
|
1285
|
+
className: `px-4 ${sizeClasses[size]} ${paddingClasses[padding]} ${alignClasses[align]} ${minWidthClass} ${minHeightClass} ${className}`,
|
|
1286
|
+
style: Object.keys(inlineStyles).length > 0 ? inlineStyles : void 0,
|
|
1287
|
+
children
|
|
1288
|
+
}
|
|
1289
|
+
);
|
|
1217
1290
|
}
|
|
1218
1291
|
Container.displayName = "Container";
|
|
1219
1292
|
var container_default = Container;
|
|
@@ -1228,7 +1301,7 @@ function Navbar({
|
|
|
1228
1301
|
border = "none",
|
|
1229
1302
|
disableMobileMenu = false
|
|
1230
1303
|
}) {
|
|
1231
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
1304
|
+
const [mobileMenuOpen, setMobileMenuOpen] = React5.useState(false);
|
|
1232
1305
|
const appearanceClasses = {
|
|
1233
1306
|
solid: "bg-background shadow-sm",
|
|
1234
1307
|
blur: "bg-background/70 backdrop-blur-md supports-[backdrop-filter]:bg-background/60 border border-border/60",
|
|
@@ -1323,8 +1396,8 @@ var PageTransition = ({
|
|
|
1323
1396
|
type = "fade",
|
|
1324
1397
|
className = ""
|
|
1325
1398
|
}) => {
|
|
1326
|
-
const [isVisible, setIsVisible] =
|
|
1327
|
-
|
|
1399
|
+
const [isVisible, setIsVisible] = React5__default.default.useState(false);
|
|
1400
|
+
React5__default.default.useEffect(() => {
|
|
1328
1401
|
requestAnimationFrame(() => {
|
|
1329
1402
|
requestAnimationFrame(() => {
|
|
1330
1403
|
setIsVisible(true);
|
|
@@ -1355,7 +1428,7 @@ var PageTransition = ({
|
|
|
1355
1428
|
PageTransition.displayName = "PageTransition";
|
|
1356
1429
|
var page_transition_default = PageTransition;
|
|
1357
1430
|
function Tabs({ tabs, defaultTab, className = "", ariaLabel = "Tabs" }) {
|
|
1358
|
-
const [activeTab, setActiveTab] =
|
|
1431
|
+
const [activeTab, setActiveTab] = React5.useState(defaultTab || tabs[0]?.id);
|
|
1359
1432
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
1360
1433
|
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", "aria-label": ariaLabel, className: "flex border-b-2 border-border/50", children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1361
1434
|
"button",
|
|
@@ -1385,7 +1458,7 @@ function Tabs({ tabs, defaultTab, className = "", ariaLabel = "Tabs" }) {
|
|
|
1385
1458
|
}
|
|
1386
1459
|
Tabs.displayName = "Tabs";
|
|
1387
1460
|
var tabs_default = Tabs;
|
|
1388
|
-
var DropdownContext =
|
|
1461
|
+
var DropdownContext = React5.createContext(null);
|
|
1389
1462
|
function Dropdown({
|
|
1390
1463
|
trigger,
|
|
1391
1464
|
children,
|
|
@@ -1394,14 +1467,14 @@ function Dropdown({
|
|
|
1394
1467
|
autoClose = true,
|
|
1395
1468
|
size = "md"
|
|
1396
1469
|
}) {
|
|
1397
|
-
const [isOpen, setIsOpen] =
|
|
1398
|
-
const dropdownRef =
|
|
1399
|
-
const menuRef =
|
|
1400
|
-
const itemsRef =
|
|
1401
|
-
const [activeIndex, setActiveIndex] =
|
|
1402
|
-
const close =
|
|
1403
|
-
const open =
|
|
1404
|
-
|
|
1470
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
1471
|
+
const dropdownRef = React5.useRef(null);
|
|
1472
|
+
const menuRef = React5.useRef(null);
|
|
1473
|
+
const itemsRef = React5.useRef([]);
|
|
1474
|
+
const [activeIndex, setActiveIndex] = React5.useState(-1);
|
|
1475
|
+
const close = React5.useCallback(() => setIsOpen(false), []);
|
|
1476
|
+
const open = React5.useCallback(() => setIsOpen(true), []);
|
|
1477
|
+
React5.useEffect(() => {
|
|
1405
1478
|
if (!isOpen) return;
|
|
1406
1479
|
const handleKey = (e) => {
|
|
1407
1480
|
if (!menuRef.current) return;
|
|
@@ -1436,7 +1509,7 @@ function Dropdown({
|
|
|
1436
1509
|
document.addEventListener("keydown", handleKey);
|
|
1437
1510
|
return () => document.removeEventListener("keydown", handleKey);
|
|
1438
1511
|
}, [isOpen, activeIndex, close]);
|
|
1439
|
-
|
|
1512
|
+
React5.useEffect(() => {
|
|
1440
1513
|
if (!isOpen) return;
|
|
1441
1514
|
const handleClickOutside = (event) => {
|
|
1442
1515
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
@@ -1446,20 +1519,34 @@ function Dropdown({
|
|
|
1446
1519
|
document.addEventListener("mousedown", handleClickOutside);
|
|
1447
1520
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1448
1521
|
}, [isOpen, close]);
|
|
1449
|
-
|
|
1522
|
+
React5.useLayoutEffect(() => {
|
|
1523
|
+
let raf;
|
|
1450
1524
|
if (isOpen) {
|
|
1451
1525
|
const itemEls = itemsRef.current.filter(Boolean);
|
|
1452
1526
|
if (itemEls.length) {
|
|
1453
|
-
|
|
1454
|
-
|
|
1527
|
+
raf = requestAnimationFrame(() => {
|
|
1528
|
+
setActiveIndex(0);
|
|
1529
|
+
itemEls[0]?.focus();
|
|
1530
|
+
});
|
|
1455
1531
|
}
|
|
1456
1532
|
} else {
|
|
1457
|
-
setActiveIndex(-1);
|
|
1533
|
+
raf = requestAnimationFrame(() => setActiveIndex(-1));
|
|
1458
1534
|
}
|
|
1535
|
+
return () => {
|
|
1536
|
+
if (raf) cancelAnimationFrame(raf);
|
|
1537
|
+
};
|
|
1459
1538
|
}, [isOpen]);
|
|
1460
|
-
const registerItem = (el, index) => {
|
|
1461
|
-
|
|
1462
|
-
|
|
1539
|
+
const registerItem = React5.useCallback((el, index) => {
|
|
1540
|
+
if (typeof index === "number" && index >= 0) {
|
|
1541
|
+
itemsRef.current[index] = el;
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
if (el === null) {
|
|
1545
|
+
itemsRef.current = itemsRef.current.filter((x) => x !== el && x != null);
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
if (!itemsRef.current.includes(el)) itemsRef.current.push(el);
|
|
1549
|
+
}, []);
|
|
1463
1550
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: `relative ${className}`, children: [
|
|
1464
1551
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1465
1552
|
"button",
|
|
@@ -1474,7 +1561,7 @@ function Dropdown({
|
|
|
1474
1561
|
children: trigger
|
|
1475
1562
|
}
|
|
1476
1563
|
),
|
|
1477
|
-
isOpen && /* @__PURE__ */ jsxRuntime.jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1564
|
+
isOpen && /* @__PURE__ */ jsxRuntime.jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose, registerItem }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1478
1565
|
"div",
|
|
1479
1566
|
{
|
|
1480
1567
|
id: "dropdown-menu",
|
|
@@ -1483,10 +1570,7 @@ function Dropdown({
|
|
|
1483
1570
|
role: "menu",
|
|
1484
1571
|
"aria-orientation": "vertical",
|
|
1485
1572
|
tabIndex: -1,
|
|
1486
|
-
children
|
|
1487
|
-
if (!React3__default.default.isValidElement(child)) return child;
|
|
1488
|
-
return React3__default.default.cloneElement(child, { __dropdownIndex: i, __registerItem: registerItem, size });
|
|
1489
|
-
})
|
|
1573
|
+
children
|
|
1490
1574
|
}
|
|
1491
1575
|
) })
|
|
1492
1576
|
] });
|
|
@@ -1582,6 +1666,22 @@ Pagination.displayName = "Pagination";
|
|
|
1582
1666
|
var pagination_default = Pagination;
|
|
1583
1667
|
function Sidebar({ children, className = "", width = "16rem" }) {
|
|
1584
1668
|
const widthClass = width === "16rem" ? "w-64" : width === "4rem" ? "w-16" : "";
|
|
1669
|
+
const enhancedChildren = React5__default.default.Children.map(children, (child) => {
|
|
1670
|
+
if (!React5__default.default.isValidElement(child)) return child;
|
|
1671
|
+
const childProps = child.props || {};
|
|
1672
|
+
if ("href" in childProps) {
|
|
1673
|
+
const existing = typeof childProps.className === "string" ? childProps.className : "";
|
|
1674
|
+
const sidebarItemClasses = "flex items-center w-full justify-start gap-2 px-2 py-1.5 rounded hover:bg-muted";
|
|
1675
|
+
const childInner = child.props.children;
|
|
1676
|
+
const wrappedChildren = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-2", children: childInner });
|
|
1677
|
+
const newProps = {
|
|
1678
|
+
...child.props,
|
|
1679
|
+
className: `${existing} ${sidebarItemClasses}`.trim()
|
|
1680
|
+
};
|
|
1681
|
+
return React5__default.default.cloneElement(child, newProps, wrappedChildren);
|
|
1682
|
+
}
|
|
1683
|
+
return child;
|
|
1684
|
+
});
|
|
1585
1685
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1586
1686
|
"nav",
|
|
1587
1687
|
{
|
|
@@ -1594,7 +1694,7 @@ function Sidebar({ children, className = "", width = "16rem" }) {
|
|
|
1594
1694
|
`.replace(/\s+/g, " "),
|
|
1595
1695
|
style: !widthClass ? { width } : void 0,
|
|
1596
1696
|
"aria-label": "Sidebar navigation",
|
|
1597
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 px-4 py-3
|
|
1697
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 px-4 py-3 flex flex-col gap-2", children: enhancedChildren })
|
|
1598
1698
|
}
|
|
1599
1699
|
);
|
|
1600
1700
|
}
|
|
@@ -1755,14 +1855,20 @@ function Stepper({
|
|
|
1755
1855
|
Stepper.displayName = "Stepper";
|
|
1756
1856
|
var stepper_default = Stepper;
|
|
1757
1857
|
function Toast({ message, children, type = "info", onClose, className = "", duration = 5e3 }) {
|
|
1758
|
-
const [isClosing, setIsClosing] =
|
|
1858
|
+
const [isClosing, setIsClosing] = React5.useState(false);
|
|
1759
1859
|
const typeClasses = {
|
|
1760
1860
|
info: "bg-info text-info-foreground",
|
|
1761
1861
|
success: "bg-success text-success-foreground",
|
|
1762
1862
|
warning: "bg-warning text-warning-foreground",
|
|
1763
1863
|
error: "bg-destructive text-destructive-foreground"
|
|
1764
1864
|
};
|
|
1765
|
-
|
|
1865
|
+
const handleClose = React5.useCallback(() => {
|
|
1866
|
+
setIsClosing(true);
|
|
1867
|
+
setTimeout(() => {
|
|
1868
|
+
onClose?.();
|
|
1869
|
+
}, 300);
|
|
1870
|
+
}, [onClose]);
|
|
1871
|
+
React5.useEffect(() => {
|
|
1766
1872
|
if (duration > 0) {
|
|
1767
1873
|
const timer = setTimeout(() => {
|
|
1768
1874
|
handleClose();
|
|
@@ -1770,25 +1876,20 @@ function Toast({ message, children, type = "info", onClose, className = "", dura
|
|
|
1770
1876
|
return () => clearTimeout(timer);
|
|
1771
1877
|
}
|
|
1772
1878
|
return void 0;
|
|
1773
|
-
}, [duration]);
|
|
1774
|
-
const
|
|
1775
|
-
setIsClosing(true);
|
|
1776
|
-
setTimeout(() => {
|
|
1777
|
-
onClose?.();
|
|
1778
|
-
}, 300);
|
|
1779
|
-
};
|
|
1780
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1879
|
+
}, [duration, handleClose]);
|
|
1880
|
+
const toast = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1781
1881
|
"div",
|
|
1782
1882
|
{
|
|
1783
1883
|
role: "alert",
|
|
1784
1884
|
"aria-live": "polite",
|
|
1785
|
-
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}`,
|
|
1885
|
+
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}`,
|
|
1786
1886
|
children: [
|
|
1787
1887
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: children || message }),
|
|
1788
1888
|
onClose && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleClose, className: "ml-4 font-bold hover:opacity-70 transition-opacity", "aria-label": "Close", children: "\xD7" })
|
|
1789
1889
|
]
|
|
1790
1890
|
}
|
|
1791
1891
|
);
|
|
1892
|
+
return typeof document !== "undefined" ? reactDom.createPortal(toast, document.body) : toast;
|
|
1792
1893
|
}
|
|
1793
1894
|
Toast.displayName = "Toast";
|
|
1794
1895
|
var toast_default = Toast;
|
|
@@ -1801,11 +1902,11 @@ function Tooltip({
|
|
|
1801
1902
|
usePortal = false,
|
|
1802
1903
|
className = ""
|
|
1803
1904
|
}) {
|
|
1804
|
-
const [showTooltip, setShowTooltip] =
|
|
1805
|
-
const [tooltipPosition, setTooltipPosition] =
|
|
1806
|
-
const triggerRef =
|
|
1905
|
+
const [showTooltip, setShowTooltip] = React5.useState(false);
|
|
1906
|
+
const [tooltipPosition, setTooltipPosition] = React5.useState({ top: 0, left: 0 });
|
|
1907
|
+
const triggerRef = React5.useRef(null);
|
|
1807
1908
|
const isVisible = open || showTooltip;
|
|
1808
|
-
|
|
1909
|
+
React5.useEffect(() => {
|
|
1809
1910
|
if (usePortal && isVisible && triggerRef.current) {
|
|
1810
1911
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
1811
1912
|
const positions = {
|
|
@@ -1914,6 +2015,19 @@ function Tooltip({
|
|
|
1914
2015
|
}
|
|
1915
2016
|
Tooltip.displayName = "Tooltip";
|
|
1916
2017
|
var tooltip_default = Tooltip;
|
|
2018
|
+
|
|
2019
|
+
// src/utils/portal.ts
|
|
2020
|
+
function getPortalRoot(id = "hydn-ui-portal") {
|
|
2021
|
+
if (typeof document === "undefined") return null;
|
|
2022
|
+
let root = document.getElementById(id);
|
|
2023
|
+
if (!root) {
|
|
2024
|
+
root = document.createElement("div");
|
|
2025
|
+
root.id = id;
|
|
2026
|
+
document.body.appendChild(root);
|
|
2027
|
+
}
|
|
2028
|
+
return root;
|
|
2029
|
+
}
|
|
2030
|
+
var portal_default = getPortalRoot;
|
|
1917
2031
|
function useOverlay(options) {
|
|
1918
2032
|
const {
|
|
1919
2033
|
isOpen,
|
|
@@ -1924,14 +2038,15 @@ function useOverlay(options) {
|
|
|
1924
2038
|
exitDuration = 300,
|
|
1925
2039
|
unmountOnExit = true
|
|
1926
2040
|
} = options;
|
|
1927
|
-
const previouslyFocusedRef =
|
|
1928
|
-
const containerRef =
|
|
1929
|
-
const [shouldRender, setShouldRender] =
|
|
1930
|
-
const [phase, setPhase] =
|
|
1931
|
-
|
|
1932
|
-
if (isOpen) {
|
|
2041
|
+
const previouslyFocusedRef = React5.useRef(null);
|
|
2042
|
+
const containerRef = React5.useRef(null);
|
|
2043
|
+
const [shouldRender, setShouldRender] = React5.useState(isOpen);
|
|
2044
|
+
const [phase, setPhase] = React5.useState("mount");
|
|
2045
|
+
React5.useLayoutEffect(() => {
|
|
2046
|
+
if (isOpen && !shouldRender) {
|
|
1933
2047
|
setShouldRender(true);
|
|
1934
2048
|
setPhase("mount");
|
|
2049
|
+
} else if (isOpen && shouldRender && phase === "mount") {
|
|
1935
2050
|
requestAnimationFrame(() => {
|
|
1936
2051
|
setPhase("animating-in");
|
|
1937
2052
|
let frame = 0;
|
|
@@ -1943,13 +2058,17 @@ function useOverlay(options) {
|
|
|
1943
2058
|
requestAnimationFrame(step);
|
|
1944
2059
|
}
|
|
1945
2060
|
};
|
|
1946
|
-
|
|
2061
|
+
if (animationFrames > 0) {
|
|
2062
|
+
requestAnimationFrame(step);
|
|
2063
|
+
} else {
|
|
2064
|
+
setPhase("visible");
|
|
2065
|
+
}
|
|
1947
2066
|
});
|
|
1948
|
-
} else if (!isOpen && shouldRender) {
|
|
2067
|
+
} else if (!isOpen && shouldRender && phase !== "animating-out") {
|
|
1949
2068
|
setPhase("animating-out");
|
|
1950
2069
|
}
|
|
1951
|
-
}, [isOpen, shouldRender, animationFrames]);
|
|
1952
|
-
|
|
2070
|
+
}, [isOpen, shouldRender, phase, animationFrames]);
|
|
2071
|
+
React5.useEffect(() => {
|
|
1953
2072
|
if (phase === "animating-out" && unmountOnExit) {
|
|
1954
2073
|
const timeout = setTimeout(() => {
|
|
1955
2074
|
setShouldRender(false);
|
|
@@ -1959,7 +2078,7 @@ function useOverlay(options) {
|
|
|
1959
2078
|
}
|
|
1960
2079
|
return void 0;
|
|
1961
2080
|
}, [phase, exitDuration, unmountOnExit]);
|
|
1962
|
-
|
|
2081
|
+
React5.useEffect(() => {
|
|
1963
2082
|
if (isOpen) {
|
|
1964
2083
|
if (typeof document !== "undefined") {
|
|
1965
2084
|
if (restoreFocus) previouslyFocusedRef.current = document.activeElement;
|
|
@@ -1975,7 +2094,7 @@ function useOverlay(options) {
|
|
|
1975
2094
|
}
|
|
1976
2095
|
};
|
|
1977
2096
|
}, [isOpen, lockScroll, restoreFocus]);
|
|
1978
|
-
|
|
2097
|
+
React5.useEffect(() => {
|
|
1979
2098
|
if (phase === "visible" && containerRef.current) {
|
|
1980
2099
|
const el = containerRef.current;
|
|
1981
2100
|
try {
|
|
@@ -1985,7 +2104,7 @@ function useOverlay(options) {
|
|
|
1985
2104
|
}
|
|
1986
2105
|
}
|
|
1987
2106
|
}, [phase]);
|
|
1988
|
-
const handleKeyDown =
|
|
2107
|
+
const handleKeyDown = React5.useCallback(
|
|
1989
2108
|
(e) => {
|
|
1990
2109
|
if (!focusTrap || phase !== "visible" || e.key !== "Tab" || !containerRef.current) return;
|
|
1991
2110
|
const node = containerRef.current;
|
|
@@ -2007,14 +2126,14 @@ function useOverlay(options) {
|
|
|
2007
2126
|
},
|
|
2008
2127
|
[focusTrap, phase]
|
|
2009
2128
|
);
|
|
2010
|
-
|
|
2129
|
+
React5.useEffect(() => {
|
|
2011
2130
|
if (focusTrap && phase === "visible") {
|
|
2012
2131
|
document.addEventListener("keydown", handleKeyDown);
|
|
2013
2132
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
2014
2133
|
}
|
|
2015
2134
|
return void 0;
|
|
2016
2135
|
}, [phase, focusTrap, handleKeyDown]);
|
|
2017
|
-
const getPhaseClass =
|
|
2136
|
+
const getPhaseClass = React5.useCallback(
|
|
2018
2137
|
(openClass, closedClass) => {
|
|
2019
2138
|
return phase === "animating-in" || phase === "visible" ? openClass : closedClass;
|
|
2020
2139
|
},
|
|
@@ -2033,7 +2152,8 @@ function Modal({
|
|
|
2033
2152
|
actions,
|
|
2034
2153
|
className = "",
|
|
2035
2154
|
ariaLabel,
|
|
2036
|
-
align = "center"
|
|
2155
|
+
align = "center",
|
|
2156
|
+
portalRoot = portal_default()
|
|
2037
2157
|
}) {
|
|
2038
2158
|
const {
|
|
2039
2159
|
phase,
|
|
@@ -2047,7 +2167,7 @@ function Modal({
|
|
|
2047
2167
|
animationFrames: 2,
|
|
2048
2168
|
restoreFocus: true
|
|
2049
2169
|
});
|
|
2050
|
-
|
|
2170
|
+
React5__default.default.useEffect(() => {
|
|
2051
2171
|
if (!isOpen) return;
|
|
2052
2172
|
const handleEscape = (e) => {
|
|
2053
2173
|
if (e.key === "Escape") {
|
|
@@ -2065,7 +2185,7 @@ function Modal({
|
|
|
2065
2185
|
const backdropOpacity = phase === "visible" || phase === "animating-in" ? "opacity-100" : "opacity-0 transition-opacity delay-50";
|
|
2066
2186
|
const hasStructured = title || description || content || actions;
|
|
2067
2187
|
const alignmentClasses = align === "center" ? "grid place-items-center" : "flex items-start justify-center pt-20";
|
|
2068
|
-
|
|
2188
|
+
const panel = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2069
2189
|
"div",
|
|
2070
2190
|
{
|
|
2071
2191
|
"data-phase": phase,
|
|
@@ -2099,6 +2219,7 @@ function Modal({
|
|
|
2099
2219
|
)
|
|
2100
2220
|
}
|
|
2101
2221
|
);
|
|
2222
|
+
return portalRoot ? reactDom.createPortal(panel, portalRoot) : panel;
|
|
2102
2223
|
}
|
|
2103
2224
|
Modal.displayName = "Modal";
|
|
2104
2225
|
var modal_default = Modal;
|
|
@@ -2161,10 +2282,10 @@ function DeleteDialog({
|
|
|
2161
2282
|
DeleteDialog.displayName = "DeleteDialog";
|
|
2162
2283
|
var delete_dialog_default = DeleteDialog;
|
|
2163
2284
|
function Popover({ trigger, children, content, position = "bottom", className = "" }) {
|
|
2164
|
-
const [isOpen, setIsOpen] =
|
|
2165
|
-
const popoverRef =
|
|
2285
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
2286
|
+
const popoverRef = React5.useRef(null);
|
|
2166
2287
|
const triggerContent = children || trigger;
|
|
2167
|
-
|
|
2288
|
+
React5.useEffect(() => {
|
|
2168
2289
|
const handleClickOutside = (event) => {
|
|
2169
2290
|
if (popoverRef.current && !popoverRef.current.contains(event.target)) {
|
|
2170
2291
|
setIsOpen(false);
|
|
@@ -2215,12 +2336,13 @@ function Popover({ trigger, children, content, position = "bottom", className =
|
|
|
2215
2336
|
}
|
|
2216
2337
|
Popover.displayName = "Popover";
|
|
2217
2338
|
var popover_default = Popover;
|
|
2218
|
-
function Alert({ children, type = "info", dismissible = false, onClose, className = "" }) {
|
|
2339
|
+
function Alert({ children, type = "info", dismissible = false, onClose, className = "", position = "relative", duration = 0 }) {
|
|
2340
|
+
const [isClosing, setIsClosing] = React5.useState(false);
|
|
2219
2341
|
const typeClasses = {
|
|
2220
|
-
info: "bg-info/
|
|
2221
|
-
success: "bg-success/
|
|
2222
|
-
warning: "bg-warning/
|
|
2223
|
-
error: "bg-destructive/
|
|
2342
|
+
info: "bg-info/20 text-foreground border-info/50 backdrop-blur-sm",
|
|
2343
|
+
success: "bg-success/20 text-foreground border-success/50 backdrop-blur-sm",
|
|
2344
|
+
warning: "bg-warning/20 text-foreground border-warning/50 backdrop-blur-sm",
|
|
2345
|
+
error: "bg-destructive/20 text-foreground border-destructive/50 backdrop-blur-sm"
|
|
2224
2346
|
};
|
|
2225
2347
|
const iconClasses = {
|
|
2226
2348
|
info: "text-info",
|
|
@@ -2228,6 +2350,21 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
|
|
|
2228
2350
|
warning: "text-warning",
|
|
2229
2351
|
error: "text-destructive"
|
|
2230
2352
|
};
|
|
2353
|
+
const handleClose = React5.useCallback(() => {
|
|
2354
|
+
setIsClosing(true);
|
|
2355
|
+
setTimeout(() => {
|
|
2356
|
+
onClose?.();
|
|
2357
|
+
}, 300);
|
|
2358
|
+
}, [onClose]);
|
|
2359
|
+
React5.useEffect(() => {
|
|
2360
|
+
if (duration > 0 && onClose) {
|
|
2361
|
+
const timer = setTimeout(() => {
|
|
2362
|
+
handleClose();
|
|
2363
|
+
}, duration);
|
|
2364
|
+
return () => clearTimeout(timer);
|
|
2365
|
+
}
|
|
2366
|
+
return void 0;
|
|
2367
|
+
}, [duration, onClose, handleClose]);
|
|
2231
2368
|
const icons = {
|
|
2232
2369
|
info: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5 flex-shrink-0", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2233
2370
|
"path",
|
|
@@ -2262,19 +2399,44 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
|
|
|
2262
2399
|
}
|
|
2263
2400
|
) })
|
|
2264
2401
|
};
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2402
|
+
const positionClasses = {
|
|
2403
|
+
top: "fixed top-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
|
|
2404
|
+
bottom: "fixed bottom-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
|
|
2405
|
+
relative: ""
|
|
2406
|
+
};
|
|
2407
|
+
const getAnimationClasses = () => {
|
|
2408
|
+
if (position === "top") {
|
|
2409
|
+
return isClosing ? "opacity-0 -translate-y-full" : "opacity-100 translate-y-0 animate-slideInTop";
|
|
2410
|
+
}
|
|
2411
|
+
if (position === "bottom") {
|
|
2412
|
+
return isClosing ? "opacity-0 translate-y-full" : "opacity-100 translate-y-0 animate-slideInBottom";
|
|
2413
|
+
}
|
|
2414
|
+
return isClosing ? "opacity-0" : "opacity-100";
|
|
2415
|
+
};
|
|
2416
|
+
const alertContent = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2417
|
+
"div",
|
|
2418
|
+
{
|
|
2419
|
+
role: "alert",
|
|
2420
|
+
className: `p-4 border rounded-lg flex items-start gap-3 transition-all duration-300 ease-out ${typeClasses[type]} ${positionClasses[position]} ${getAnimationClasses()} ${className}`,
|
|
2421
|
+
children: [
|
|
2422
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: iconClasses[type], children: icons[type] }),
|
|
2423
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm", children }),
|
|
2424
|
+
dismissible && onClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2425
|
+
"button",
|
|
2426
|
+
{
|
|
2427
|
+
onClick: handleClose,
|
|
2428
|
+
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",
|
|
2429
|
+
"aria-label": "Close alert",
|
|
2430
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
2431
|
+
}
|
|
2432
|
+
)
|
|
2433
|
+
]
|
|
2434
|
+
}
|
|
2435
|
+
);
|
|
2436
|
+
if (position !== "relative" && typeof document !== "undefined") {
|
|
2437
|
+
return reactDom.createPortal(alertContent, document.body);
|
|
2438
|
+
}
|
|
2439
|
+
return alertContent;
|
|
2278
2440
|
}
|
|
2279
2441
|
Alert.displayName = "Alert";
|
|
2280
2442
|
var alert_default = Alert;
|
|
@@ -2580,12 +2742,12 @@ function TableCell({ children, className = "", align = "left", ...props }) {
|
|
|
2580
2742
|
return /* @__PURE__ */ jsxRuntime.jsx("td", { className: `px-6 py-4 whitespace-nowrap ${alignClasses[align]} ${className}`, ...props, children });
|
|
2581
2743
|
}
|
|
2582
2744
|
function useTable({ data, initialSort, pageSize = 10 }) {
|
|
2583
|
-
const [sortConfig, setSortConfig] =
|
|
2745
|
+
const [sortConfig, setSortConfig] = React5.useState(
|
|
2584
2746
|
initialSort ? { key: initialSort.key, direction: initialSort.direction } : null
|
|
2585
2747
|
);
|
|
2586
|
-
const [currentPage, setCurrentPage] =
|
|
2587
|
-
const [selectedRows, setSelectedRows] =
|
|
2588
|
-
const sortedData =
|
|
2748
|
+
const [currentPage, setCurrentPage] = React5.useState(1);
|
|
2749
|
+
const [selectedRows, setSelectedRows] = React5.useState(/* @__PURE__ */ new Set());
|
|
2750
|
+
const sortedData = React5.useMemo(() => {
|
|
2589
2751
|
if (!sortConfig) return data;
|
|
2590
2752
|
const sorted = [...data].sort((a, b) => {
|
|
2591
2753
|
const aValue = a[sortConfig.key];
|
|
@@ -3061,7 +3223,7 @@ function Heading({ children, level = 1, className = "", noMargin = false }) {
|
|
|
3061
3223
|
6: "mb-2"
|
|
3062
3224
|
};
|
|
3063
3225
|
const margin = noMargin ? "" : marginClasses[level];
|
|
3064
|
-
return
|
|
3226
|
+
return React5.createElement(
|
|
3065
3227
|
`h${level}`,
|
|
3066
3228
|
{
|
|
3067
3229
|
className: `text-foreground ${levelClasses[level]} ${margin} ${className}`
|
|
@@ -3254,7 +3416,7 @@ function PricingTier({
|
|
|
3254
3416
|
PricingTier.displayName = "PricingTier";
|
|
3255
3417
|
var pricing_tier_default = PricingTier;
|
|
3256
3418
|
function CodeBlock({ code, className = "", showCopy = true }) {
|
|
3257
|
-
const [copied, setCopied] =
|
|
3419
|
+
const [copied, setCopied] = React5.useState(false);
|
|
3258
3420
|
const handleCopy = async () => {
|
|
3259
3421
|
try {
|
|
3260
3422
|
await navigator.clipboard.writeText(code);
|
|
@@ -3391,7 +3553,7 @@ function Drawer({
|
|
|
3391
3553
|
closeOnEscape = true,
|
|
3392
3554
|
closeOnOutside = true,
|
|
3393
3555
|
unmountOnExit = true,
|
|
3394
|
-
portalRoot =
|
|
3556
|
+
portalRoot = portal_default(),
|
|
3395
3557
|
noAnimation = false
|
|
3396
3558
|
}) {
|
|
3397
3559
|
const { phase, shouldRender, ref, getPhaseClass } = useOverlay_default({
|
|
@@ -3400,8 +3562,8 @@ function Drawer({
|
|
|
3400
3562
|
restoreFocus: true,
|
|
3401
3563
|
focusTrap: true,
|
|
3402
3564
|
unmountOnExit,
|
|
3403
|
-
exitDuration: noAnimation ? 0 :
|
|
3404
|
-
animationFrames: noAnimation ? 0 :
|
|
3565
|
+
exitDuration: noAnimation ? 0 : 250,
|
|
3566
|
+
animationFrames: noAnimation ? 0 : 0
|
|
3405
3567
|
});
|
|
3406
3568
|
if (!shouldRender) return null;
|
|
3407
3569
|
const sizeClasses = {
|
|
@@ -3425,7 +3587,7 @@ function Drawer({
|
|
|
3425
3587
|
};
|
|
3426
3588
|
const openTransform = "translate-x-0 translate-y-0";
|
|
3427
3589
|
const panelTransform = noAnimation ? "" : getPhaseClass(openTransform, closedTransform[position]);
|
|
3428
|
-
const overlayOpacity = noAnimation ? "" : getPhaseClass("opacity-100", "opacity-0");
|
|
3590
|
+
const overlayOpacity = noAnimation ? "opacity-100" : getPhaseClass("opacity-100", "opacity-0");
|
|
3429
3591
|
const handleKeyDown = (e) => {
|
|
3430
3592
|
if (e.key === "Escape" && closeOnEscape) {
|
|
3431
3593
|
e.stopPropagation();
|
|
@@ -3434,11 +3596,21 @@ function Drawer({
|
|
|
3434
3596
|
};
|
|
3435
3597
|
const panel = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3436
3598
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3437
|
-
"
|
|
3599
|
+
"button",
|
|
3438
3600
|
{
|
|
3439
|
-
|
|
3440
|
-
|
|
3601
|
+
type: "button",
|
|
3602
|
+
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`,
|
|
3603
|
+
"aria-label": closeOnOutside ? "Close overlay" : void 0,
|
|
3604
|
+
"aria-hidden": !closeOnOutside,
|
|
3605
|
+
tabIndex: closeOnOutside ? 0 : -1,
|
|
3441
3606
|
onClick: () => closeOnOutside && onClose(),
|
|
3607
|
+
onKeyDown: (e) => {
|
|
3608
|
+
if (!closeOnOutside) return;
|
|
3609
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3610
|
+
e.preventDefault();
|
|
3611
|
+
onClose();
|
|
3612
|
+
}
|
|
3613
|
+
},
|
|
3442
3614
|
"data-phase": phase
|
|
3443
3615
|
}
|
|
3444
3616
|
),
|
|
@@ -3452,7 +3624,7 @@ function Drawer({
|
|
|
3452
3624
|
tabIndex: -1,
|
|
3453
3625
|
"data-phase": phase,
|
|
3454
3626
|
"data-position": position,
|
|
3455
|
-
className: `fixed ${edgeClasses[position]} ${position === "left" || position === "right" ? sizeClasses[size] : ""} bg-card text-card-foreground shadow-2xl z-
|
|
3627
|
+
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}`,
|
|
3456
3628
|
onKeyDown: handleKeyDown,
|
|
3457
3629
|
children: [
|
|
3458
3630
|
title && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/60 bg-card/95 backdrop-blur-sm", children: [
|
|
@@ -3500,7 +3672,7 @@ function Page({ children, className = "" }) {
|
|
|
3500
3672
|
Page.displayName = "Page";
|
|
3501
3673
|
var page_default = Page;
|
|
3502
3674
|
function AccordionItem({ title, children, defaultOpen = false }) {
|
|
3503
|
-
const [isOpen, setIsOpen] =
|
|
3675
|
+
const [isOpen, setIsOpen] = React5.useState(defaultOpen);
|
|
3504
3676
|
return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "border-b border-border", children: [
|
|
3505
3677
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3506
3678
|
"button",
|
|
@@ -3728,14 +3900,18 @@ function Footer({ sections, copyright, social, className = "" }) {
|
|
|
3728
3900
|
Footer.displayName = "Footer";
|
|
3729
3901
|
var footer_default = Footer;
|
|
3730
3902
|
function useScrollReset(deps, container) {
|
|
3731
|
-
|
|
3903
|
+
React5.useEffect(() => {
|
|
3732
3904
|
let cancelled = false;
|
|
3733
3905
|
const maxRaf = 6;
|
|
3734
3906
|
let rafCount = 0;
|
|
3907
|
+
const isRef = (obj) => {
|
|
3908
|
+
return typeof obj === "object" && obj !== null && "current" in obj;
|
|
3909
|
+
};
|
|
3735
3910
|
const setAllScrollTop = () => {
|
|
3736
3911
|
if (cancelled) return;
|
|
3737
3912
|
window.scrollTo(0, 0);
|
|
3738
|
-
|
|
3913
|
+
const resolved = isRef(container) ? container.current : container;
|
|
3914
|
+
if (resolved) resolved.scrollTop = 0;
|
|
3739
3915
|
document.documentElement.scrollTop = 0;
|
|
3740
3916
|
document.body.scrollTop = 0;
|
|
3741
3917
|
};
|
|
@@ -3773,11 +3949,11 @@ function LeftNavLayout({
|
|
|
3773
3949
|
embedded = false,
|
|
3774
3950
|
mainContentRef
|
|
3775
3951
|
}) {
|
|
3776
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
3777
|
-
const [internalMobileMenuOpen, setInternalMobileMenuOpen] =
|
|
3778
|
-
const navRef =
|
|
3779
|
-
const scrollPosRef =
|
|
3780
|
-
const internalContentRef =
|
|
3952
|
+
const [internalCollapsed, setInternalCollapsed] = React5.useState(false);
|
|
3953
|
+
const [internalMobileMenuOpen, setInternalMobileMenuOpen] = React5.useState(false);
|
|
3954
|
+
const navRef = React5.useRef(null);
|
|
3955
|
+
const scrollPosRef = React5.useRef(0);
|
|
3956
|
+
const internalContentRef = React5.useRef(null);
|
|
3781
3957
|
const contentRef = mainContentRef || internalContentRef;
|
|
3782
3958
|
const collapsed = controlledCollapsed ?? internalCollapsed;
|
|
3783
3959
|
const setCollapsed = (value) => {
|
|
@@ -3797,12 +3973,12 @@ function LeftNavLayout({
|
|
|
3797
3973
|
};
|
|
3798
3974
|
const toggleCollapsed = () => setCollapsed(!collapsed);
|
|
3799
3975
|
const toggleMobileMenu = () => setMobileMenuOpen(!mobileMenuOpen);
|
|
3800
|
-
|
|
3976
|
+
React5.useEffect(() => {
|
|
3801
3977
|
if (navRef.current) {
|
|
3802
3978
|
navRef.current.scrollTop = scrollPosRef.current;
|
|
3803
3979
|
}
|
|
3804
3980
|
}, [children]);
|
|
3805
|
-
useScrollReset_default([children], contentRef
|
|
3981
|
+
useScrollReset_default([children], contentRef);
|
|
3806
3982
|
const containerClasses = embedded ? "flex bg-background border border-border rounded-lg overflow-hidden" : "flex h-[calc(100vh-4rem)] bg-background";
|
|
3807
3983
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${containerClasses} ${className}`, children: [
|
|
3808
3984
|
mobileCollapsible && mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3890,15 +4066,15 @@ function LeftNavItem({
|
|
|
3890
4066
|
title,
|
|
3891
4067
|
preventNavigation = false
|
|
3892
4068
|
}) {
|
|
3893
|
-
const navRef =
|
|
3894
|
-
const [isCollapsed, setIsCollapsed] =
|
|
4069
|
+
const navRef = React5.useRef(null);
|
|
4070
|
+
const [isCollapsed, setIsCollapsed] = React5.useState(() => {
|
|
3895
4071
|
if (typeof window !== "undefined") {
|
|
3896
4072
|
const navElement = document.querySelector("nav[data-collapsed]");
|
|
3897
4073
|
return navElement?.getAttribute("data-collapsed") === "true";
|
|
3898
4074
|
}
|
|
3899
4075
|
return false;
|
|
3900
4076
|
});
|
|
3901
|
-
|
|
4077
|
+
React5.useEffect(() => {
|
|
3902
4078
|
const checkCollapsed = () => {
|
|
3903
4079
|
const navElement2 = navRef.current?.closest("nav");
|
|
3904
4080
|
if (navElement2) {
|
|
@@ -4001,26 +4177,26 @@ function Code({ children, block = false, variant = "default", className = "" })
|
|
|
4001
4177
|
}
|
|
4002
4178
|
Code.displayName = "Code";
|
|
4003
4179
|
var code_default = Code;
|
|
4004
|
-
var ThemeContext =
|
|
4180
|
+
var ThemeContext = React5.createContext(void 0);
|
|
4005
4181
|
function ThemeProvider({
|
|
4006
4182
|
children,
|
|
4007
4183
|
defaultTheme = "light",
|
|
4008
4184
|
storageKey = "hydn-theme",
|
|
4009
4185
|
themes = ["light", "dark"]
|
|
4010
4186
|
}) {
|
|
4011
|
-
const [theme, setThemeState] =
|
|
4187
|
+
const [theme, setThemeState] = React5.useState(() => {
|
|
4012
4188
|
if (typeof window !== "undefined") {
|
|
4013
4189
|
const stored = localStorage.getItem(storageKey);
|
|
4014
4190
|
return stored && themes.includes(stored) ? stored : defaultTheme;
|
|
4015
4191
|
}
|
|
4016
4192
|
return defaultTheme;
|
|
4017
4193
|
});
|
|
4018
|
-
|
|
4194
|
+
React5.useEffect(() => {
|
|
4019
4195
|
const root = window.document.documentElement;
|
|
4020
4196
|
root.classList.remove(...themes);
|
|
4021
4197
|
root.classList.add(theme);
|
|
4022
4198
|
}, [theme, themes]);
|
|
4023
|
-
const setTheme =
|
|
4199
|
+
const setTheme = React5.useCallback(
|
|
4024
4200
|
(newTheme) => {
|
|
4025
4201
|
if (themes.includes(newTheme)) {
|
|
4026
4202
|
localStorage.setItem(storageKey, newTheme);
|
|
@@ -4031,7 +4207,7 @@ function ThemeProvider({
|
|
|
4031
4207
|
},
|
|
4032
4208
|
[themes, storageKey]
|
|
4033
4209
|
);
|
|
4034
|
-
const value =
|
|
4210
|
+
const value = React5.useMemo(
|
|
4035
4211
|
() => ({
|
|
4036
4212
|
theme,
|
|
4037
4213
|
setTheme,
|
|
@@ -4042,7 +4218,7 @@ function ThemeProvider({
|
|
|
4042
4218
|
return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value, children });
|
|
4043
4219
|
}
|
|
4044
4220
|
function useTheme() {
|
|
4045
|
-
const context =
|
|
4221
|
+
const context = React5.useContext(ThemeContext);
|
|
4046
4222
|
if (!context) {
|
|
4047
4223
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
4048
4224
|
}
|