@hyddenlabs/hydn-ui 0.3.0-alpha.2 → 0.3.0-alpha.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var React3 = require('react');
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 React3__default = /*#__PURE__*/_interopDefault(React3);
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 = React3.createContext(null);
224
+ var RadioGroupContext = React5.createContext(null);
225
225
  var useRadioGroup = () => {
226
- const context = React3.useContext(RadioGroupContext);
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 inputId = id || `radio-${value || Math.random().toString(36).slice(2)}`;
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] = React3.useState(false);
371
- const [searchQuery, setSearchQuery] = React3.useState("");
372
- const [focusedIndex, setFocusedIndex] = React3.useState(-1);
373
- const containerRef = React3.useRef(null);
374
- const searchInputRef = React3.useRef(null);
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
- React3.useEffect(() => {
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
- React3.useEffect(() => {
390
+ React5.useEffect(() => {
390
391
  if (isOpen && searchInputRef.current) {
391
392
  searchInputRef.current.focus();
392
393
  }
@@ -479,7 +480,13 @@ function MultiSelect({
479
480
  selectedValues.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: getSelectedLabels().map((label, index) => /* @__PURE__ */ jsxRuntime.jsxs(
480
481
  "span",
481
482
  {
482
- className: `inline-flex items-center gap-1 bg-primary/10 text-primary rounded-md font-medium ${currentSize.chip}`,
483
+ className: `
484
+ inline-flex items-center gap-1
485
+ bg-primary/10 text-primary rounded-md font-medium
486
+ animate-scaleIn origin-left
487
+ transition-all duration-200
488
+ ${currentSize.chip}
489
+ `.trim(),
483
490
  children: [
484
491
  label,
485
492
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -487,7 +494,7 @@ function MultiSelect({
487
494
  {
488
495
  type: "button",
489
496
  onClick: (e) => handleRemoveValue(selectedValues[index], e),
490
- className: "hover:bg-primary/20 rounded-sm transition-colors",
497
+ className: "hover:bg-primary/20 rounded-sm transition-colors duration-150",
491
498
  "aria-label": `Remove ${label}`,
492
499
  tabIndex: -1,
493
500
  children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconX, { size: currentSize.icon - 4 })
@@ -547,7 +554,7 @@ function MultiSelect({
547
554
  onClick: () => !isDisabled && handleToggleOption(option.value),
548
555
  className: `
549
556
  w-full px-3 py-2 flex items-center justify-between gap-2
550
- transition-colors text-left ${currentSize.text}
557
+ transition-all duration-200 text-left ${currentSize.text}
551
558
  ${isFocused ? "bg-muted" : ""}
552
559
  ${isSelected ? "bg-primary/10 text-primary font-medium" : "hover:bg-muted"}
553
560
  ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}
@@ -557,7 +564,13 @@ function MultiSelect({
557
564
  disabled: isDisabled,
558
565
  children: [
559
566
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: option.label }),
560
- isSelected && /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconCheck, { size: currentSize.icon, className: "flex-shrink-0" })
567
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx(
568
+ iconsReact.IconCheck,
569
+ {
570
+ size: currentSize.icon,
571
+ className: "flex-shrink-0 animate-scaleIn"
572
+ }
573
+ )
561
574
  ]
562
575
  },
563
576
  option.value
@@ -870,7 +883,7 @@ function FormField({
870
883
  validationState = "default"
871
884
  }) {
872
885
  const effectiveValidationState = error ? "error" : validationState;
873
- const childWithValidation = React3.isValidElement(children) ? React3.cloneElement(children, {
886
+ const childWithValidation = React5.isValidElement(children) ? React5.cloneElement(children, {
874
887
  validationState: effectiveValidationState
875
888
  }) : children;
876
889
  return /* @__PURE__ */ jsxRuntime.jsxs(stack_default, { direction: "vertical", spacing: "sm", className, children: [
@@ -886,17 +899,42 @@ function FormField({
886
899
  FormField.displayName = "FormField";
887
900
  var form_field_default = FormField;
888
901
  function InputGroup({ children, prefix, suffix, className = "" }) {
889
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-stretch ${className}`, children: [
890
- prefix && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-3 bg-muted border border-r-0 border-input rounded-l-md", children: prefix }),
891
- children,
892
- suffix && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-3 bg-muted border border-l-0 border-input rounded-r-md", children: suffix })
893
- ] });
902
+ const isTextSuffix = typeof suffix === "string" || typeof suffix === "number";
903
+ return /* @__PURE__ */ jsxRuntime.jsxs(
904
+ "div",
905
+ {
906
+ className: [
907
+ "inline-flex items-stretch rounded-lg border border-input shadow-sm bg-background",
908
+ "focus-within:ring-2 focus-within:ring-ring/20 focus-within:border-ring",
909
+ "transition-colors duration-150 overflow-hidden",
910
+ // Use CSS nesting to style child input without cloning
911
+ "[&>input]:border-0 [&>input]:shadow-none [&>input]:rounded-none [&>input]:ring-0",
912
+ "[&>input]:focus:ring-0 [&>input]:focus:border-0 [&>input]:bg-transparent",
913
+ "[&>input]:flex-1 [&>input]:min-w-0",
914
+ // Style child buttons (both direct and nested)
915
+ "[&_button]:rounded-none [&_button]:border-0 [&_button]:shadow-none [&_button]:m-0",
916
+ "[&_button]:h-full",
917
+ className
918
+ ].filter(Boolean).join(" "),
919
+ children: [
920
+ prefix && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-3 bg-muted/50 text-muted-foreground text-sm shrink-0", children: prefix }),
921
+ children,
922
+ suffix && /* @__PURE__ */ jsxRuntime.jsx(
923
+ "div",
924
+ {
925
+ className: isTextSuffix ? "flex items-center px-3 bg-muted/50 text-muted-foreground text-sm shrink-0" : "flex items-stretch shrink-0",
926
+ children: suffix
927
+ }
928
+ )
929
+ ]
930
+ }
931
+ );
894
932
  }
895
933
  InputGroup.displayName = "InputGroup";
896
934
  var input_group_default = InputGroup;
897
935
  function Calendar({ value, onChange, minDate, maxDate, disabled = false, className = "" }) {
898
- const [currentMonth, setCurrentMonth] = React3.useState(value || /* @__PURE__ */ new Date());
899
- const [selectedDate, setSelectedDate] = React3.useState(value);
936
+ const [currentMonth, setCurrentMonth] = React5.useState(value || /* @__PURE__ */ new Date());
937
+ const [selectedDate, setSelectedDate] = React5.useState(value);
900
938
  const getDaysInMonth = (date) => {
901
939
  return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
902
940
  };
@@ -1032,14 +1070,14 @@ function DatePicker({
1032
1070
  className = "",
1033
1071
  size = "md"
1034
1072
  }) {
1035
- const [isOpen, setIsOpen] = React3.useState(false);
1036
- const [selectedDate, setSelectedDate] = React3.useState(value);
1037
- const containerRef = React3.useRef(null);
1038
- const inputRef = React3.useRef(null);
1039
- React3.useEffect(() => {
1073
+ const [isOpen, setIsOpen] = React5.useState(false);
1074
+ const [selectedDate, setSelectedDate] = React5.useState(value);
1075
+ const containerRef = React5.useRef(null);
1076
+ const inputRef = React5.useRef(null);
1077
+ React5.useEffect(() => {
1040
1078
  setSelectedDate(value);
1041
1079
  }, [value]);
1042
- React3.useEffect(() => {
1080
+ React5.useEffect(() => {
1043
1081
  const handleClickOutside = (event) => {
1044
1082
  if (containerRef.current && !containerRef.current.contains(event.target)) {
1045
1083
  setIsOpen(false);
@@ -1051,7 +1089,7 @@ function DatePicker({
1051
1089
  }
1052
1090
  return void 0;
1053
1091
  }, [isOpen]);
1054
- React3.useEffect(() => {
1092
+ React5.useEffect(() => {
1055
1093
  const handleEscape = (event) => {
1056
1094
  if (event.key === "Escape" && isOpen) {
1057
1095
  setIsOpen(false);
@@ -1182,8 +1220,31 @@ function DatePicker({
1182
1220
  }
1183
1221
  DatePicker.displayName = "DatePicker";
1184
1222
  var date_picker_default = DatePicker;
1185
- function Nav({ children, className = "", ariaLabel = "Main navigation" }) {
1186
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, className: `flex items-center ${className}`, children });
1223
+ function Nav({
1224
+ children,
1225
+ className = "",
1226
+ ariaLabel = "Main navigation",
1227
+ direction = "horizontal",
1228
+ spacing = "md",
1229
+ align = "center"
1230
+ }) {
1231
+ const spacingClasses = {
1232
+ none: "gap-0",
1233
+ sm: "gap-2",
1234
+ md: "gap-4",
1235
+ lg: "gap-6",
1236
+ xl: "gap-8"
1237
+ };
1238
+ const alignClasses = {
1239
+ start: "items-start",
1240
+ center: "items-center",
1241
+ end: "items-end",
1242
+ stretch: "items-stretch"
1243
+ };
1244
+ const directionClass = direction === "horizontal" ? "flex-row" : "flex-col";
1245
+ const spacingClass = spacingClasses[spacing];
1246
+ const alignClass = alignClasses[align];
1247
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, className: `flex ${directionClass} ${spacingClass} ${alignClass} ${className}`, children });
1187
1248
  }
1188
1249
  Nav.displayName = "Nav";
1189
1250
  var nav_default = Nav;
@@ -1192,7 +1253,9 @@ function Container({
1192
1253
  className = "",
1193
1254
  size = "lg",
1194
1255
  padding = "lg",
1195
- align = "center"
1256
+ align = "center",
1257
+ minWidth,
1258
+ minHeight
1196
1259
  }) {
1197
1260
  const sizeClasses = {
1198
1261
  sm: "max-w-screen-sm",
@@ -1213,7 +1276,54 @@ function Container({
1213
1276
  center: "mx-auto",
1214
1277
  end: "ml-auto"
1215
1278
  };
1216
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `px-4 ${sizeClasses[size]} ${paddingClasses[padding]} ${alignClasses[align]} ${className}`, children });
1279
+ const minWidthClasses = {
1280
+ xs: "min-w-[20rem]",
1281
+ // 320px
1282
+ sm: "min-w-[24rem]",
1283
+ // 384px
1284
+ md: "min-w-[28rem]",
1285
+ // 448px
1286
+ lg: "min-w-[32rem]",
1287
+ // 512px
1288
+ xl: "min-w-[36rem]",
1289
+ // 576px
1290
+ "2xl": "min-w-[42rem]",
1291
+ // 672px
1292
+ "3xl": "min-w-[48rem]",
1293
+ // 768px
1294
+ full: "min-w-full"
1295
+ };
1296
+ const minHeightClasses = {
1297
+ xs: "min-h-[10rem]",
1298
+ // 160px
1299
+ sm: "min-h-[15rem]",
1300
+ // 240px
1301
+ md: "min-h-[20rem]",
1302
+ // 320px
1303
+ lg: "min-h-[25rem]",
1304
+ // 400px
1305
+ xl: "min-h-[30rem]",
1306
+ // 480px
1307
+ "2xl": "min-h-[35rem]",
1308
+ // 560px
1309
+ "3xl": "min-h-[40rem]",
1310
+ // 640px
1311
+ screen: "min-h-screen"
1312
+ };
1313
+ const minWidthClass = minWidth && minWidthClasses[minWidth] ? minWidthClasses[minWidth] : "";
1314
+ const minHeightClass = minHeight && minHeightClasses[minHeight] ? minHeightClasses[minHeight] : "";
1315
+ const inlineStyles = {
1316
+ ...minWidth && !minWidthClasses[minWidth] && { minWidth },
1317
+ ...minHeight && !minHeightClasses[minHeight] && { minHeight }
1318
+ };
1319
+ return /* @__PURE__ */ jsxRuntime.jsx(
1320
+ "div",
1321
+ {
1322
+ className: `px-4 ${sizeClasses[size]} ${paddingClasses[padding]} ${alignClasses[align]} ${minWidthClass} ${minHeightClass} ${className}`,
1323
+ style: Object.keys(inlineStyles).length > 0 ? inlineStyles : void 0,
1324
+ children
1325
+ }
1326
+ );
1217
1327
  }
1218
1328
  Container.displayName = "Container";
1219
1329
  var container_default = Container;
@@ -1228,7 +1338,7 @@ function Navbar({
1228
1338
  border = "none",
1229
1339
  disableMobileMenu = false
1230
1340
  }) {
1231
- const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
1341
+ const [mobileMenuOpen, setMobileMenuOpen] = React5.useState(false);
1232
1342
  const appearanceClasses = {
1233
1343
  solid: "bg-background shadow-sm",
1234
1344
  blur: "bg-background/70 backdrop-blur-md supports-[backdrop-filter]:bg-background/60 border border-border/60",
@@ -1323,8 +1433,8 @@ var PageTransition = ({
1323
1433
  type = "fade",
1324
1434
  className = ""
1325
1435
  }) => {
1326
- const [isVisible, setIsVisible] = React3__default.default.useState(false);
1327
- React3__default.default.useEffect(() => {
1436
+ const [isVisible, setIsVisible] = React5__default.default.useState(false);
1437
+ React5__default.default.useEffect(() => {
1328
1438
  requestAnimationFrame(() => {
1329
1439
  requestAnimationFrame(() => {
1330
1440
  setIsVisible(true);
@@ -1355,7 +1465,7 @@ var PageTransition = ({
1355
1465
  PageTransition.displayName = "PageTransition";
1356
1466
  var page_transition_default = PageTransition;
1357
1467
  function Tabs({ tabs, defaultTab, className = "", ariaLabel = "Tabs" }) {
1358
- const [activeTab, setActiveTab] = React3.useState(defaultTab || tabs[0]?.id);
1468
+ const [activeTab, setActiveTab] = React5.useState(defaultTab || tabs[0]?.id);
1359
1469
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
1360
1470
  /* @__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
1471
  "button",
@@ -1385,7 +1495,7 @@ function Tabs({ tabs, defaultTab, className = "", ariaLabel = "Tabs" }) {
1385
1495
  }
1386
1496
  Tabs.displayName = "Tabs";
1387
1497
  var tabs_default = Tabs;
1388
- var DropdownContext = React3.createContext(null);
1498
+ var DropdownContext = React5.createContext(null);
1389
1499
  function Dropdown({
1390
1500
  trigger,
1391
1501
  children,
@@ -1394,14 +1504,14 @@ function Dropdown({
1394
1504
  autoClose = true,
1395
1505
  size = "md"
1396
1506
  }) {
1397
- const [isOpen, setIsOpen] = React3.useState(false);
1398
- const dropdownRef = React3.useRef(null);
1399
- const menuRef = React3.useRef(null);
1400
- const itemsRef = React3.useRef([]);
1401
- const [activeIndex, setActiveIndex] = React3.useState(-1);
1402
- const close = React3.useCallback(() => setIsOpen(false), []);
1403
- const open = React3.useCallback(() => setIsOpen(true), []);
1404
- React3.useEffect(() => {
1507
+ const [isOpen, setIsOpen] = React5.useState(false);
1508
+ const dropdownRef = React5.useRef(null);
1509
+ const menuRef = React5.useRef(null);
1510
+ const itemsRef = React5.useRef([]);
1511
+ const [activeIndex, setActiveIndex] = React5.useState(-1);
1512
+ const close = React5.useCallback(() => setIsOpen(false), []);
1513
+ const open = React5.useCallback(() => setIsOpen(true), []);
1514
+ React5.useEffect(() => {
1405
1515
  if (!isOpen) return;
1406
1516
  const handleKey = (e) => {
1407
1517
  if (!menuRef.current) return;
@@ -1436,7 +1546,7 @@ function Dropdown({
1436
1546
  document.addEventListener("keydown", handleKey);
1437
1547
  return () => document.removeEventListener("keydown", handleKey);
1438
1548
  }, [isOpen, activeIndex, close]);
1439
- React3.useEffect(() => {
1549
+ React5.useEffect(() => {
1440
1550
  if (!isOpen) return;
1441
1551
  const handleClickOutside = (event) => {
1442
1552
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -1446,20 +1556,34 @@ function Dropdown({
1446
1556
  document.addEventListener("mousedown", handleClickOutside);
1447
1557
  return () => document.removeEventListener("mousedown", handleClickOutside);
1448
1558
  }, [isOpen, close]);
1449
- React3.useEffect(() => {
1559
+ React5.useLayoutEffect(() => {
1560
+ let raf;
1450
1561
  if (isOpen) {
1451
1562
  const itemEls = itemsRef.current.filter(Boolean);
1452
1563
  if (itemEls.length) {
1453
- setActiveIndex(0);
1454
- itemEls[0]?.focus();
1564
+ raf = requestAnimationFrame(() => {
1565
+ setActiveIndex(0);
1566
+ itemEls[0]?.focus();
1567
+ });
1455
1568
  }
1456
1569
  } else {
1457
- setActiveIndex(-1);
1570
+ raf = requestAnimationFrame(() => setActiveIndex(-1));
1458
1571
  }
1572
+ return () => {
1573
+ if (raf) cancelAnimationFrame(raf);
1574
+ };
1459
1575
  }, [isOpen]);
1460
- const registerItem = (el, index) => {
1461
- itemsRef.current[index] = el;
1462
- };
1576
+ const registerItem = React5.useCallback((el, index) => {
1577
+ if (typeof index === "number" && index >= 0) {
1578
+ itemsRef.current[index] = el;
1579
+ return;
1580
+ }
1581
+ if (el === null) {
1582
+ itemsRef.current = itemsRef.current.filter((x) => x !== el && x != null);
1583
+ return;
1584
+ }
1585
+ if (!itemsRef.current.includes(el)) itemsRef.current.push(el);
1586
+ }, []);
1463
1587
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: `relative ${className}`, children: [
1464
1588
  /* @__PURE__ */ jsxRuntime.jsx(
1465
1589
  "button",
@@ -1474,7 +1598,7 @@ function Dropdown({
1474
1598
  children: trigger
1475
1599
  }
1476
1600
  ),
1477
- isOpen && /* @__PURE__ */ jsxRuntime.jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose }, children: /* @__PURE__ */ jsxRuntime.jsx(
1601
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(DropdownContext.Provider, { value: { requestClose: close, autoClose, registerItem }, children: /* @__PURE__ */ jsxRuntime.jsx(
1478
1602
  "div",
1479
1603
  {
1480
1604
  id: "dropdown-menu",
@@ -1483,10 +1607,7 @@ function Dropdown({
1483
1607
  role: "menu",
1484
1608
  "aria-orientation": "vertical",
1485
1609
  tabIndex: -1,
1486
- children: React3__default.default.Children.map(children, (child, i) => {
1487
- if (!React3__default.default.isValidElement(child)) return child;
1488
- return React3__default.default.cloneElement(child, { __dropdownIndex: i, __registerItem: registerItem, size });
1489
- })
1610
+ children
1490
1611
  }
1491
1612
  ) })
1492
1613
  ] });
@@ -1582,6 +1703,22 @@ Pagination.displayName = "Pagination";
1582
1703
  var pagination_default = Pagination;
1583
1704
  function Sidebar({ children, className = "", width = "16rem" }) {
1584
1705
  const widthClass = width === "16rem" ? "w-64" : width === "4rem" ? "w-16" : "";
1706
+ const enhancedChildren = React5__default.default.Children.map(children, (child) => {
1707
+ if (!React5__default.default.isValidElement(child)) return child;
1708
+ const childProps = child.props || {};
1709
+ if ("href" in childProps) {
1710
+ const existing = typeof childProps.className === "string" ? childProps.className : "";
1711
+ const sidebarItemClasses = "flex items-center w-full justify-start gap-2 px-2 py-1.5 rounded hover:bg-muted";
1712
+ const childInner = child.props.children;
1713
+ const wrappedChildren = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-2", children: childInner });
1714
+ const newProps = {
1715
+ ...child.props,
1716
+ className: `${existing} ${sidebarItemClasses}`.trim()
1717
+ };
1718
+ return React5__default.default.cloneElement(child, newProps, wrappedChildren);
1719
+ }
1720
+ return child;
1721
+ });
1585
1722
  return /* @__PURE__ */ jsxRuntime.jsx(
1586
1723
  "nav",
1587
1724
  {
@@ -1594,7 +1731,7 @@ function Sidebar({ children, className = "", width = "16rem" }) {
1594
1731
  `.replace(/\s+/g, " "),
1595
1732
  style: !widthClass ? { width } : void 0,
1596
1733
  "aria-label": "Sidebar navigation",
1597
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 px-4 py-3 space-y-2", children })
1734
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 px-4 py-3 flex flex-col gap-2", children: enhancedChildren })
1598
1735
  }
1599
1736
  );
1600
1737
  }
@@ -1755,14 +1892,20 @@ function Stepper({
1755
1892
  Stepper.displayName = "Stepper";
1756
1893
  var stepper_default = Stepper;
1757
1894
  function Toast({ message, children, type = "info", onClose, className = "", duration = 5e3 }) {
1758
- const [isClosing, setIsClosing] = React3.useState(false);
1895
+ const [isClosing, setIsClosing] = React5.useState(false);
1759
1896
  const typeClasses = {
1760
1897
  info: "bg-info text-info-foreground",
1761
1898
  success: "bg-success text-success-foreground",
1762
1899
  warning: "bg-warning text-warning-foreground",
1763
1900
  error: "bg-destructive text-destructive-foreground"
1764
1901
  };
1765
- React3.useEffect(() => {
1902
+ const handleClose = React5.useCallback(() => {
1903
+ setIsClosing(true);
1904
+ setTimeout(() => {
1905
+ onClose?.();
1906
+ }, 300);
1907
+ }, [onClose]);
1908
+ React5.useEffect(() => {
1766
1909
  if (duration > 0) {
1767
1910
  const timer = setTimeout(() => {
1768
1911
  handleClose();
@@ -1770,25 +1913,20 @@ function Toast({ message, children, type = "info", onClose, className = "", dura
1770
1913
  return () => clearTimeout(timer);
1771
1914
  }
1772
1915
  return void 0;
1773
- }, [duration]);
1774
- const handleClose = () => {
1775
- setIsClosing(true);
1776
- setTimeout(() => {
1777
- onClose?.();
1778
- }, 300);
1779
- };
1780
- return /* @__PURE__ */ jsxRuntime.jsxs(
1916
+ }, [duration, handleClose]);
1917
+ const toast = /* @__PURE__ */ jsxRuntime.jsxs(
1781
1918
  "div",
1782
1919
  {
1783
1920
  role: "alert",
1784
1921
  "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}`,
1922
+ 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
1923
  children: [
1787
1924
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: children || message }),
1788
1925
  onClose && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleClose, className: "ml-4 font-bold hover:opacity-70 transition-opacity", "aria-label": "Close", children: "\xD7" })
1789
1926
  ]
1790
1927
  }
1791
1928
  );
1929
+ return typeof document !== "undefined" ? reactDom.createPortal(toast, document.body) : toast;
1792
1930
  }
1793
1931
  Toast.displayName = "Toast";
1794
1932
  var toast_default = Toast;
@@ -1801,11 +1939,11 @@ function Tooltip({
1801
1939
  usePortal = false,
1802
1940
  className = ""
1803
1941
  }) {
1804
- const [showTooltip, setShowTooltip] = React3.useState(false);
1805
- const [tooltipPosition, setTooltipPosition] = React3.useState({ top: 0, left: 0 });
1806
- const triggerRef = React3.useRef(null);
1942
+ const [showTooltip, setShowTooltip] = React5.useState(false);
1943
+ const [tooltipPosition, setTooltipPosition] = React5.useState({ top: 0, left: 0 });
1944
+ const triggerRef = React5.useRef(null);
1807
1945
  const isVisible = open || showTooltip;
1808
- React3.useEffect(() => {
1946
+ React5.useEffect(() => {
1809
1947
  if (usePortal && isVisible && triggerRef.current) {
1810
1948
  const rect = triggerRef.current.getBoundingClientRect();
1811
1949
  const positions = {
@@ -1914,6 +2052,19 @@ function Tooltip({
1914
2052
  }
1915
2053
  Tooltip.displayName = "Tooltip";
1916
2054
  var tooltip_default = Tooltip;
2055
+
2056
+ // src/utils/portal.ts
2057
+ function getPortalRoot(id = "hydn-ui-portal") {
2058
+ if (typeof document === "undefined") return null;
2059
+ let root = document.getElementById(id);
2060
+ if (!root) {
2061
+ root = document.createElement("div");
2062
+ root.id = id;
2063
+ document.body.appendChild(root);
2064
+ }
2065
+ return root;
2066
+ }
2067
+ var portal_default = getPortalRoot;
1917
2068
  function useOverlay(options) {
1918
2069
  const {
1919
2070
  isOpen,
@@ -1924,14 +2075,15 @@ function useOverlay(options) {
1924
2075
  exitDuration = 300,
1925
2076
  unmountOnExit = true
1926
2077
  } = options;
1927
- const previouslyFocusedRef = React3.useRef(null);
1928
- const containerRef = React3.useRef(null);
1929
- const [shouldRender, setShouldRender] = React3.useState(isOpen);
1930
- const [phase, setPhase] = React3.useState("mount");
1931
- React3.useLayoutEffect(() => {
1932
- if (isOpen) {
2078
+ const previouslyFocusedRef = React5.useRef(null);
2079
+ const containerRef = React5.useRef(null);
2080
+ const [shouldRender, setShouldRender] = React5.useState(isOpen);
2081
+ const [phase, setPhase] = React5.useState("mount");
2082
+ React5.useLayoutEffect(() => {
2083
+ if (isOpen && !shouldRender) {
1933
2084
  setShouldRender(true);
1934
2085
  setPhase("mount");
2086
+ } else if (isOpen && shouldRender && phase === "mount") {
1935
2087
  requestAnimationFrame(() => {
1936
2088
  setPhase("animating-in");
1937
2089
  let frame = 0;
@@ -1943,13 +2095,17 @@ function useOverlay(options) {
1943
2095
  requestAnimationFrame(step);
1944
2096
  }
1945
2097
  };
1946
- requestAnimationFrame(step);
2098
+ if (animationFrames > 0) {
2099
+ requestAnimationFrame(step);
2100
+ } else {
2101
+ setPhase("visible");
2102
+ }
1947
2103
  });
1948
- } else if (!isOpen && shouldRender) {
2104
+ } else if (!isOpen && shouldRender && phase !== "animating-out") {
1949
2105
  setPhase("animating-out");
1950
2106
  }
1951
- }, [isOpen, shouldRender, animationFrames]);
1952
- React3.useEffect(() => {
2107
+ }, [isOpen, shouldRender, phase, animationFrames]);
2108
+ React5.useEffect(() => {
1953
2109
  if (phase === "animating-out" && unmountOnExit) {
1954
2110
  const timeout = setTimeout(() => {
1955
2111
  setShouldRender(false);
@@ -1959,7 +2115,7 @@ function useOverlay(options) {
1959
2115
  }
1960
2116
  return void 0;
1961
2117
  }, [phase, exitDuration, unmountOnExit]);
1962
- React3.useEffect(() => {
2118
+ React5.useEffect(() => {
1963
2119
  if (isOpen) {
1964
2120
  if (typeof document !== "undefined") {
1965
2121
  if (restoreFocus) previouslyFocusedRef.current = document.activeElement;
@@ -1975,7 +2131,7 @@ function useOverlay(options) {
1975
2131
  }
1976
2132
  };
1977
2133
  }, [isOpen, lockScroll, restoreFocus]);
1978
- React3.useEffect(() => {
2134
+ React5.useEffect(() => {
1979
2135
  if (phase === "visible" && containerRef.current) {
1980
2136
  const el = containerRef.current;
1981
2137
  try {
@@ -1985,7 +2141,7 @@ function useOverlay(options) {
1985
2141
  }
1986
2142
  }
1987
2143
  }, [phase]);
1988
- const handleKeyDown = React3.useCallback(
2144
+ const handleKeyDown = React5.useCallback(
1989
2145
  (e) => {
1990
2146
  if (!focusTrap || phase !== "visible" || e.key !== "Tab" || !containerRef.current) return;
1991
2147
  const node = containerRef.current;
@@ -2007,14 +2163,14 @@ function useOverlay(options) {
2007
2163
  },
2008
2164
  [focusTrap, phase]
2009
2165
  );
2010
- React3.useEffect(() => {
2166
+ React5.useEffect(() => {
2011
2167
  if (focusTrap && phase === "visible") {
2012
2168
  document.addEventListener("keydown", handleKeyDown);
2013
2169
  return () => document.removeEventListener("keydown", handleKeyDown);
2014
2170
  }
2015
2171
  return void 0;
2016
2172
  }, [phase, focusTrap, handleKeyDown]);
2017
- const getPhaseClass = React3.useCallback(
2173
+ const getPhaseClass = React5.useCallback(
2018
2174
  (openClass, closedClass) => {
2019
2175
  return phase === "animating-in" || phase === "visible" ? openClass : closedClass;
2020
2176
  },
@@ -2033,7 +2189,8 @@ function Modal({
2033
2189
  actions,
2034
2190
  className = "",
2035
2191
  ariaLabel,
2036
- align = "center"
2192
+ align = "center",
2193
+ portalRoot = portal_default()
2037
2194
  }) {
2038
2195
  const {
2039
2196
  phase,
@@ -2047,7 +2204,7 @@ function Modal({
2047
2204
  animationFrames: 2,
2048
2205
  restoreFocus: true
2049
2206
  });
2050
- React3__default.default.useEffect(() => {
2207
+ React5__default.default.useEffect(() => {
2051
2208
  if (!isOpen) return;
2052
2209
  const handleEscape = (e) => {
2053
2210
  if (e.key === "Escape") {
@@ -2065,7 +2222,7 @@ function Modal({
2065
2222
  const backdropOpacity = phase === "visible" || phase === "animating-in" ? "opacity-100" : "opacity-0 transition-opacity delay-50";
2066
2223
  const hasStructured = title || description || content || actions;
2067
2224
  const alignmentClasses = align === "center" ? "grid place-items-center" : "flex items-start justify-center pt-20";
2068
- return /* @__PURE__ */ jsxRuntime.jsx(
2225
+ const panel = /* @__PURE__ */ jsxRuntime.jsx(
2069
2226
  "div",
2070
2227
  {
2071
2228
  "data-phase": phase,
@@ -2099,6 +2256,7 @@ function Modal({
2099
2256
  )
2100
2257
  }
2101
2258
  );
2259
+ return portalRoot ? reactDom.createPortal(panel, portalRoot) : panel;
2102
2260
  }
2103
2261
  Modal.displayName = "Modal";
2104
2262
  var modal_default = Modal;
@@ -2161,10 +2319,10 @@ function DeleteDialog({
2161
2319
  DeleteDialog.displayName = "DeleteDialog";
2162
2320
  var delete_dialog_default = DeleteDialog;
2163
2321
  function Popover({ trigger, children, content, position = "bottom", className = "" }) {
2164
- const [isOpen, setIsOpen] = React3.useState(false);
2165
- const popoverRef = React3.useRef(null);
2322
+ const [isOpen, setIsOpen] = React5.useState(false);
2323
+ const popoverRef = React5.useRef(null);
2166
2324
  const triggerContent = children || trigger;
2167
- React3.useEffect(() => {
2325
+ React5.useEffect(() => {
2168
2326
  const handleClickOutside = (event) => {
2169
2327
  if (popoverRef.current && !popoverRef.current.contains(event.target)) {
2170
2328
  setIsOpen(false);
@@ -2215,12 +2373,13 @@ function Popover({ trigger, children, content, position = "bottom", className =
2215
2373
  }
2216
2374
  Popover.displayName = "Popover";
2217
2375
  var popover_default = Popover;
2218
- function Alert({ children, type = "info", dismissible = false, onClose, className = "" }) {
2376
+ function Alert({ children, type = "info", dismissible = false, onClose, className = "", position = "relative", duration = 0 }) {
2377
+ const [isClosing, setIsClosing] = React5.useState(false);
2219
2378
  const typeClasses = {
2220
- info: "bg-info/10 text-foreground border-info/30",
2221
- success: "bg-success/10 text-foreground border-success/30",
2222
- warning: "bg-warning/10 text-foreground border-warning/30",
2223
- error: "bg-destructive/10 text-foreground border-destructive/30"
2379
+ info: "bg-info/20 text-foreground border-info/50 backdrop-blur-sm",
2380
+ success: "bg-success/20 text-foreground border-success/50 backdrop-blur-sm",
2381
+ warning: "bg-warning/20 text-foreground border-warning/50 backdrop-blur-sm",
2382
+ error: "bg-destructive/20 text-foreground border-destructive/50 backdrop-blur-sm"
2224
2383
  };
2225
2384
  const iconClasses = {
2226
2385
  info: "text-info",
@@ -2228,6 +2387,21 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
2228
2387
  warning: "text-warning",
2229
2388
  error: "text-destructive"
2230
2389
  };
2390
+ const handleClose = React5.useCallback(() => {
2391
+ setIsClosing(true);
2392
+ setTimeout(() => {
2393
+ onClose?.();
2394
+ }, 300);
2395
+ }, [onClose]);
2396
+ React5.useEffect(() => {
2397
+ if (duration > 0 && onClose) {
2398
+ const timer = setTimeout(() => {
2399
+ handleClose();
2400
+ }, duration);
2401
+ return () => clearTimeout(timer);
2402
+ }
2403
+ return void 0;
2404
+ }, [duration, onClose, handleClose]);
2231
2405
  const icons = {
2232
2406
  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
2407
  "path",
@@ -2262,19 +2436,44 @@ function Alert({ children, type = "info", dismissible = false, onClose, classNam
2262
2436
  }
2263
2437
  ) })
2264
2438
  };
2265
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: `p-4 border rounded-lg flex items-start gap-3 ${typeClasses[type]} ${className}`, children: [
2266
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: iconClasses[type], children: icons[type] }),
2267
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm", children }),
2268
- dismissible && onClose && /* @__PURE__ */ jsxRuntime.jsx(
2269
- "button",
2270
- {
2271
- onClick: onClose,
2272
- 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",
2273
- "aria-label": "Close alert",
2274
- 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" }) })
2275
- }
2276
- )
2277
- ] });
2439
+ const positionClasses = {
2440
+ top: "fixed top-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
2441
+ bottom: "fixed bottom-4 left-1/2 -translate-x-1/2 z-[9999] max-w-2xl w-full mx-4",
2442
+ relative: ""
2443
+ };
2444
+ const getAnimationClasses = () => {
2445
+ if (position === "top") {
2446
+ return isClosing ? "opacity-0 -translate-y-full" : "opacity-100 translate-y-0 animate-slideInTop";
2447
+ }
2448
+ if (position === "bottom") {
2449
+ return isClosing ? "opacity-0 translate-y-full" : "opacity-100 translate-y-0 animate-slideInBottom";
2450
+ }
2451
+ return isClosing ? "opacity-0" : "opacity-100";
2452
+ };
2453
+ const alertContent = /* @__PURE__ */ jsxRuntime.jsxs(
2454
+ "div",
2455
+ {
2456
+ role: "alert",
2457
+ className: `p-4 border rounded-lg flex items-start gap-3 transition-all duration-300 ease-out ${typeClasses[type]} ${positionClasses[position]} ${getAnimationClasses()} ${className}`,
2458
+ children: [
2459
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: iconClasses[type], children: icons[type] }),
2460
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm", children }),
2461
+ dismissible && onClose && /* @__PURE__ */ jsxRuntime.jsx(
2462
+ "button",
2463
+ {
2464
+ onClick: handleClose,
2465
+ 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",
2466
+ "aria-label": "Close alert",
2467
+ 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" }) })
2468
+ }
2469
+ )
2470
+ ]
2471
+ }
2472
+ );
2473
+ if (position !== "relative" && typeof document !== "undefined") {
2474
+ return reactDom.createPortal(alertContent, document.body);
2475
+ }
2476
+ return alertContent;
2278
2477
  }
2279
2478
  Alert.displayName = "Alert";
2280
2479
  var alert_default = Alert;
@@ -2580,12 +2779,12 @@ function TableCell({ children, className = "", align = "left", ...props }) {
2580
2779
  return /* @__PURE__ */ jsxRuntime.jsx("td", { className: `px-6 py-4 whitespace-nowrap ${alignClasses[align]} ${className}`, ...props, children });
2581
2780
  }
2582
2781
  function useTable({ data, initialSort, pageSize = 10 }) {
2583
- const [sortConfig, setSortConfig] = React3.useState(
2782
+ const [sortConfig, setSortConfig] = React5.useState(
2584
2783
  initialSort ? { key: initialSort.key, direction: initialSort.direction } : null
2585
2784
  );
2586
- const [currentPage, setCurrentPage] = React3.useState(1);
2587
- const [selectedRows, setSelectedRows] = React3.useState(/* @__PURE__ */ new Set());
2588
- const sortedData = React3.useMemo(() => {
2785
+ const [currentPage, setCurrentPage] = React5.useState(1);
2786
+ const [selectedRows, setSelectedRows] = React5.useState(/* @__PURE__ */ new Set());
2787
+ const sortedData = React5.useMemo(() => {
2589
2788
  if (!sortConfig) return data;
2590
2789
  const sorted = [...data].sort((a, b) => {
2591
2790
  const aValue = a[sortConfig.key];
@@ -3061,7 +3260,7 @@ function Heading({ children, level = 1, className = "", noMargin = false }) {
3061
3260
  6: "mb-2"
3062
3261
  };
3063
3262
  const margin = noMargin ? "" : marginClasses[level];
3064
- return React3.createElement(
3263
+ return React5.createElement(
3065
3264
  `h${level}`,
3066
3265
  {
3067
3266
  className: `text-foreground ${levelClasses[level]} ${margin} ${className}`
@@ -3254,7 +3453,7 @@ function PricingTier({
3254
3453
  PricingTier.displayName = "PricingTier";
3255
3454
  var pricing_tier_default = PricingTier;
3256
3455
  function CodeBlock({ code, className = "", showCopy = true }) {
3257
- const [copied, setCopied] = React3.useState(false);
3456
+ const [copied, setCopied] = React5.useState(false);
3258
3457
  const handleCopy = async () => {
3259
3458
  try {
3260
3459
  await navigator.clipboard.writeText(code);
@@ -3391,7 +3590,7 @@ function Drawer({
3391
3590
  closeOnEscape = true,
3392
3591
  closeOnOutside = true,
3393
3592
  unmountOnExit = true,
3394
- portalRoot = typeof document !== "undefined" ? document.body : null,
3593
+ portalRoot = portal_default(),
3395
3594
  noAnimation = false
3396
3595
  }) {
3397
3596
  const { phase, shouldRender, ref, getPhaseClass } = useOverlay_default({
@@ -3400,8 +3599,8 @@ function Drawer({
3400
3599
  restoreFocus: true,
3401
3600
  focusTrap: true,
3402
3601
  unmountOnExit,
3403
- exitDuration: noAnimation ? 0 : 300,
3404
- animationFrames: noAnimation ? 0 : 2
3602
+ exitDuration: noAnimation ? 0 : 250,
3603
+ animationFrames: noAnimation ? 0 : 0
3405
3604
  });
3406
3605
  if (!shouldRender) return null;
3407
3606
  const sizeClasses = {
@@ -3425,7 +3624,7 @@ function Drawer({
3425
3624
  };
3426
3625
  const openTransform = "translate-x-0 translate-y-0";
3427
3626
  const panelTransform = noAnimation ? "" : getPhaseClass(openTransform, closedTransform[position]);
3428
- const overlayOpacity = noAnimation ? "" : getPhaseClass("opacity-100", "opacity-0");
3627
+ const overlayOpacity = noAnimation ? "opacity-100" : getPhaseClass("opacity-100", "opacity-0");
3429
3628
  const handleKeyDown = (e) => {
3430
3629
  if (e.key === "Escape" && closeOnEscape) {
3431
3630
  e.stopPropagation();
@@ -3434,11 +3633,21 @@ function Drawer({
3434
3633
  };
3435
3634
  const panel = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3436
3635
  /* @__PURE__ */ jsxRuntime.jsx(
3437
- "div",
3636
+ "button",
3438
3637
  {
3439
- className: `fixed inset-0 z-40 bg-black/50 backdrop-blur-sm transition-opacity duration-300 ${overlayOpacity}`,
3440
- "aria-hidden": "true",
3638
+ type: "button",
3639
+ 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`,
3640
+ "aria-label": closeOnOutside ? "Close overlay" : void 0,
3641
+ "aria-hidden": !closeOnOutside,
3642
+ tabIndex: closeOnOutside ? 0 : -1,
3441
3643
  onClick: () => closeOnOutside && onClose(),
3644
+ onKeyDown: (e) => {
3645
+ if (!closeOnOutside) return;
3646
+ if (e.key === "Enter" || e.key === " ") {
3647
+ e.preventDefault();
3648
+ onClose();
3649
+ }
3650
+ },
3442
3651
  "data-phase": phase
3443
3652
  }
3444
3653
  ),
@@ -3452,7 +3661,7 @@ function Drawer({
3452
3661
  tabIndex: -1,
3453
3662
  "data-phase": phase,
3454
3663
  "data-position": position,
3455
- className: `fixed ${edgeClasses[position]} ${position === "left" || position === "right" ? sizeClasses[size] : ""} bg-card text-card-foreground shadow-2xl z-50 flex flex-col outline-none ${panelTransform} ${noAnimation ? "" : "transition-[transform] duration-300 ease-out"} ${className}`,
3664
+ 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
3665
  onKeyDown: handleKeyDown,
3457
3666
  children: [
3458
3667
  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 +3709,7 @@ function Page({ children, className = "" }) {
3500
3709
  Page.displayName = "Page";
3501
3710
  var page_default = Page;
3502
3711
  function AccordionItem({ title, children, defaultOpen = false }) {
3503
- const [isOpen, setIsOpen] = React3.useState(defaultOpen);
3712
+ const [isOpen, setIsOpen] = React5.useState(defaultOpen);
3504
3713
  return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "border-b border-border", children: [
3505
3714
  /* @__PURE__ */ jsxRuntime.jsxs(
3506
3715
  "button",
@@ -3728,14 +3937,18 @@ function Footer({ sections, copyright, social, className = "" }) {
3728
3937
  Footer.displayName = "Footer";
3729
3938
  var footer_default = Footer;
3730
3939
  function useScrollReset(deps, container) {
3731
- React3.useEffect(() => {
3940
+ React5.useEffect(() => {
3732
3941
  let cancelled = false;
3733
3942
  const maxRaf = 6;
3734
3943
  let rafCount = 0;
3944
+ const isRef = (obj) => {
3945
+ return typeof obj === "object" && obj !== null && "current" in obj;
3946
+ };
3735
3947
  const setAllScrollTop = () => {
3736
3948
  if (cancelled) return;
3737
3949
  window.scrollTo(0, 0);
3738
- if (container) container.scrollTop = 0;
3950
+ const resolved = isRef(container) ? container.current : container;
3951
+ if (resolved) resolved.scrollTop = 0;
3739
3952
  document.documentElement.scrollTop = 0;
3740
3953
  document.body.scrollTop = 0;
3741
3954
  };
@@ -3773,11 +3986,11 @@ function LeftNavLayout({
3773
3986
  embedded = false,
3774
3987
  mainContentRef
3775
3988
  }) {
3776
- const [internalCollapsed, setInternalCollapsed] = React3.useState(false);
3777
- const [internalMobileMenuOpen, setInternalMobileMenuOpen] = React3.useState(false);
3778
- const navRef = React3.useRef(null);
3779
- const scrollPosRef = React3.useRef(0);
3780
- const internalContentRef = React3.useRef(null);
3989
+ const [internalCollapsed, setInternalCollapsed] = React5.useState(false);
3990
+ const [internalMobileMenuOpen, setInternalMobileMenuOpen] = React5.useState(false);
3991
+ const navRef = React5.useRef(null);
3992
+ const scrollPosRef = React5.useRef(0);
3993
+ const internalContentRef = React5.useRef(null);
3781
3994
  const contentRef = mainContentRef || internalContentRef;
3782
3995
  const collapsed = controlledCollapsed ?? internalCollapsed;
3783
3996
  const setCollapsed = (value) => {
@@ -3797,12 +4010,12 @@ function LeftNavLayout({
3797
4010
  };
3798
4011
  const toggleCollapsed = () => setCollapsed(!collapsed);
3799
4012
  const toggleMobileMenu = () => setMobileMenuOpen(!mobileMenuOpen);
3800
- React3.useEffect(() => {
4013
+ React5.useEffect(() => {
3801
4014
  if (navRef.current) {
3802
4015
  navRef.current.scrollTop = scrollPosRef.current;
3803
4016
  }
3804
4017
  }, [children]);
3805
- useScrollReset_default([children], contentRef.current);
4018
+ useScrollReset_default([children], contentRef);
3806
4019
  const containerClasses = embedded ? "flex bg-background border border-border rounded-lg overflow-hidden" : "flex h-[calc(100vh-4rem)] bg-background";
3807
4020
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${containerClasses} ${className}`, children: [
3808
4021
  mobileCollapsible && mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
@@ -3834,17 +4047,34 @@ function LeftNavLayout({
3834
4047
  "div",
3835
4048
  {
3836
4049
  className: `
3837
- flex items-center h-12 flex-shrink-0
4050
+ relative flex items-center h-12 flex-shrink-0
3838
4051
  px-4 border-b border-border
3839
- ${collapsed ? "justify-center" : "justify-between"}
3840
4052
  `,
3841
4053
  children: [
3842
- !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground", children: "Navigation" }),
4054
+ /* @__PURE__ */ jsxRuntime.jsx(
4055
+ "span",
4056
+ {
4057
+ className: `
4058
+ text-sm font-semibold text-foreground
4059
+ transition-all duration-300 ease-in-out
4060
+ ${collapsed ? "opacity-0 w-0 overflow-hidden" : "opacity-100"}
4061
+ `,
4062
+ children: "Navigation"
4063
+ }
4064
+ ),
3843
4065
  /* @__PURE__ */ jsxRuntime.jsx(
3844
4066
  "button",
3845
4067
  {
3846
4068
  onClick: toggleCollapsed,
3847
- className: "\n hidden lg:flex items-center justify-center\n w-8 h-8 rounded-md\n text-muted-foreground hover:text-foreground\n hover:bg-muted\n transition-colors\n focus:outline-none focus:ring-2 focus:ring-ring\n ",
4069
+ className: `
4070
+ hidden lg:flex items-center justify-center
4071
+ w-8 h-8 rounded-md
4072
+ text-muted-foreground hover:text-foreground
4073
+ hover:bg-muted
4074
+ transition-all duration-300 ease-in-out
4075
+ focus:outline-none focus:ring-2 focus:ring-ring
4076
+ ${collapsed ? "absolute left-1/2 -translate-x-1/2" : "absolute right-4"}
4077
+ `,
3848
4078
  "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
3849
4079
  type: "button",
3850
4080
  children: collapsed ? /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronRight, { size: 20 }) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconChevronLeft, { size: 20 })
@@ -3890,15 +4120,15 @@ function LeftNavItem({
3890
4120
  title,
3891
4121
  preventNavigation = false
3892
4122
  }) {
3893
- const navRef = React3.useRef(null);
3894
- const [isCollapsed, setIsCollapsed] = React3.useState(() => {
4123
+ const navRef = React5.useRef(null);
4124
+ const [isCollapsed, setIsCollapsed] = React5.useState(() => {
3895
4125
  if (typeof window !== "undefined") {
3896
4126
  const navElement = document.querySelector("nav[data-collapsed]");
3897
4127
  return navElement?.getAttribute("data-collapsed") === "true";
3898
4128
  }
3899
4129
  return false;
3900
4130
  });
3901
- React3.useEffect(() => {
4131
+ React5.useEffect(() => {
3902
4132
  const checkCollapsed = () => {
3903
4133
  const navElement2 = navRef.current?.closest("nav");
3904
4134
  if (navElement2) {
@@ -4001,26 +4231,26 @@ function Code({ children, block = false, variant = "default", className = "" })
4001
4231
  }
4002
4232
  Code.displayName = "Code";
4003
4233
  var code_default = Code;
4004
- var ThemeContext = React3.createContext(void 0);
4234
+ var ThemeContext = React5.createContext(void 0);
4005
4235
  function ThemeProvider({
4006
4236
  children,
4007
4237
  defaultTheme = "light",
4008
4238
  storageKey = "hydn-theme",
4009
4239
  themes = ["light", "dark"]
4010
4240
  }) {
4011
- const [theme, setThemeState] = React3.useState(() => {
4241
+ const [theme, setThemeState] = React5.useState(() => {
4012
4242
  if (typeof window !== "undefined") {
4013
4243
  const stored = localStorage.getItem(storageKey);
4014
4244
  return stored && themes.includes(stored) ? stored : defaultTheme;
4015
4245
  }
4016
4246
  return defaultTheme;
4017
4247
  });
4018
- React3.useEffect(() => {
4248
+ React5.useEffect(() => {
4019
4249
  const root = window.document.documentElement;
4020
4250
  root.classList.remove(...themes);
4021
4251
  root.classList.add(theme);
4022
4252
  }, [theme, themes]);
4023
- const setTheme = React3.useCallback(
4253
+ const setTheme = React5.useCallback(
4024
4254
  (newTheme) => {
4025
4255
  if (themes.includes(newTheme)) {
4026
4256
  localStorage.setItem(storageKey, newTheme);
@@ -4031,7 +4261,7 @@ function ThemeProvider({
4031
4261
  },
4032
4262
  [themes, storageKey]
4033
4263
  );
4034
- const value = React3.useMemo(
4264
+ const value = React5.useMemo(
4035
4265
  () => ({
4036
4266
  theme,
4037
4267
  setTheme,
@@ -4042,7 +4272,7 @@ function ThemeProvider({
4042
4272
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value, children });
4043
4273
  }
4044
4274
  function useTheme() {
4045
- const context = React3.useContext(ThemeContext);
4275
+ const context = React5.useContext(ThemeContext);
4046
4276
  if (!context) {
4047
4277
  throw new Error("useTheme must be used within a ThemeProvider");
4048
4278
  }