@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 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
  }
@@ -870,7 +871,7 @@ function FormField({
870
871
  validationState = "default"
871
872
  }) {
872
873
  const effectiveValidationState = error ? "error" : validationState;
873
- const childWithValidation = React3.isValidElement(children) ? React3.cloneElement(children, {
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] = React3.useState(value || /* @__PURE__ */ new Date());
899
- const [selectedDate, setSelectedDate] = React3.useState(value);
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] = 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(() => {
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
- React3.useEffect(() => {
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
- React3.useEffect(() => {
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({ children, className = "", ariaLabel = "Main navigation" }) {
1186
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, className: `flex items-center ${className}`, children });
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
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `px-4 ${sizeClasses[size]} ${paddingClasses[padding]} ${alignClasses[align]} ${className}`, children });
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] = React3.useState(false);
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] = React3__default.default.useState(false);
1327
- React3__default.default.useEffect(() => {
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] = React3.useState(defaultTab || tabs[0]?.id);
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 = React3.createContext(null);
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] = 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(() => {
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
- React3.useEffect(() => {
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
- React3.useEffect(() => {
1522
+ React5.useLayoutEffect(() => {
1523
+ let raf;
1450
1524
  if (isOpen) {
1451
1525
  const itemEls = itemsRef.current.filter(Boolean);
1452
1526
  if (itemEls.length) {
1453
- setActiveIndex(0);
1454
- itemEls[0]?.focus();
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
- itemsRef.current[index] = el;
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: 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
- })
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 space-y-2", children })
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] = React3.useState(false);
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
- React3.useEffect(() => {
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 handleClose = () => {
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] = React3.useState(false);
1805
- const [tooltipPosition, setTooltipPosition] = React3.useState({ top: 0, left: 0 });
1806
- const triggerRef = React3.useRef(null);
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
- React3.useEffect(() => {
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 = 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) {
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
- requestAnimationFrame(step);
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
- React3.useEffect(() => {
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
- React3.useEffect(() => {
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
- React3.useEffect(() => {
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 = React3.useCallback(
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
- React3.useEffect(() => {
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 = React3.useCallback(
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
- React3__default.default.useEffect(() => {
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
- return /* @__PURE__ */ jsxRuntime.jsx(
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] = React3.useState(false);
2165
- const popoverRef = React3.useRef(null);
2285
+ const [isOpen, setIsOpen] = React5.useState(false);
2286
+ const popoverRef = React5.useRef(null);
2166
2287
  const triggerContent = children || trigger;
2167
- React3.useEffect(() => {
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/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"
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
- 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
- ] });
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] = React3.useState(
2745
+ const [sortConfig, setSortConfig] = React5.useState(
2584
2746
  initialSort ? { key: initialSort.key, direction: initialSort.direction } : null
2585
2747
  );
2586
- const [currentPage, setCurrentPage] = React3.useState(1);
2587
- const [selectedRows, setSelectedRows] = React3.useState(/* @__PURE__ */ new Set());
2588
- const sortedData = React3.useMemo(() => {
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 React3.createElement(
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] = React3.useState(false);
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 = typeof document !== "undefined" ? document.body : null,
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 : 300,
3404
- animationFrames: noAnimation ? 0 : 2
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
- "div",
3599
+ "button",
3438
3600
  {
3439
- className: `fixed inset-0 z-40 bg-black/50 backdrop-blur-sm transition-opacity duration-300 ${overlayOpacity}`,
3440
- "aria-hidden": "true",
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-50 flex flex-col outline-none ${panelTransform} ${noAnimation ? "" : "transition-[transform] duration-300 ease-out"} ${className}`,
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] = React3.useState(defaultOpen);
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
- React3.useEffect(() => {
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
- if (container) container.scrollTop = 0;
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] = 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);
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
- React3.useEffect(() => {
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.current);
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 = React3.useRef(null);
3894
- const [isCollapsed, setIsCollapsed] = React3.useState(() => {
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
- React3.useEffect(() => {
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 = React3.createContext(void 0);
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] = React3.useState(() => {
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
- React3.useEffect(() => {
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 = React3.useCallback(
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 = React3.useMemo(
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 = React3.useContext(ThemeContext);
4221
+ const context = React5.useContext(ThemeContext);
4046
4222
  if (!context) {
4047
4223
  throw new Error("useTheme must be used within a ThemeProvider");
4048
4224
  }