@hyddenlabs/hydn-ui 0.3.0-alpha.189 → 0.3.0-alpha.191

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
@@ -2338,17 +2338,44 @@ function LeftNavLayout({
2338
2338
  contentClassName = "",
2339
2339
  navWidth = "16rem",
2340
2340
  navWidthCollapsed = "4.5rem",
2341
- mobileCollapsible = true,
2342
- mobileMenuOpen: controlledMobileMenuOpen,
2341
+ hideOnMobile = false,
2342
+ autoCollapseOnMobile = true,
2343
2343
  embedded = false,
2344
2344
  header = "Navigation",
2345
2345
  mainContentRef
2346
2346
  }) {
2347
2347
  const [internalCollapsed, setInternalCollapsed] = React.useState(false);
2348
+ const [mobileMenuOpen, setMobileMenuOpen] = React.useState(!hideOnMobile);
2349
+ const [isMobile, setIsMobile] = React.useState(false);
2350
+ const [mobileCollapsedOverride, setMobileCollapsedOverride] = React.useState(null);
2351
+ const desktopCollapsedRef = React.useRef(void 0);
2348
2352
  const navRef = React.useRef(null);
2349
2353
  const scrollPosRef = React.useRef(0);
2350
2354
  const internalContentRef = React.useRef(null);
2351
2355
  const contentRef = mainContentRef || internalContentRef;
2356
+ React.useEffect(() => {
2357
+ const checkMobile = () => {
2358
+ const newIsMobile = window.innerWidth < 1024;
2359
+ if (newIsMobile !== isMobile) {
2360
+ const wasDesktop = !isMobile;
2361
+ const isNowDesktop = !newIsMobile;
2362
+ setIsMobile(newIsMobile);
2363
+ if (wasDesktop && autoCollapseOnMobile) {
2364
+ const currentCollapsed = controlledCollapsed ?? internalCollapsed;
2365
+ desktopCollapsedRef.current = currentCollapsed;
2366
+ }
2367
+ if (isNowDesktop && autoCollapseOnMobile && desktopCollapsedRef.current !== void 0) {
2368
+ if (controlledCollapsed === void 0) {
2369
+ setInternalCollapsed(desktopCollapsedRef.current);
2370
+ }
2371
+ }
2372
+ setMobileCollapsedOverride(null);
2373
+ }
2374
+ };
2375
+ checkMobile();
2376
+ window.addEventListener("resize", checkMobile);
2377
+ return () => window.removeEventListener("resize", checkMobile);
2378
+ }, [isMobile, autoCollapseOnMobile, controlledCollapsed, internalCollapsed]);
2352
2379
  const collapsed = controlledCollapsed ?? internalCollapsed;
2353
2380
  const setCollapsed = (value) => {
2354
2381
  if (onCollapsedChange) {
@@ -2357,8 +2384,18 @@ function LeftNavLayout({
2357
2384
  setInternalCollapsed(value);
2358
2385
  }
2359
2386
  };
2360
- const mobileMenuOpen = controlledMobileMenuOpen ?? false;
2387
+ const effectiveCollapsed = autoCollapseOnMobile && isMobile ? mobileCollapsedOverride !== null ? mobileCollapsedOverride : true : collapsed;
2361
2388
  const toggleCollapsed = () => setCollapsed(!collapsed);
2389
+ const closeMobileMenu = () => setMobileMenuOpen(false);
2390
+ const handleToggleClick = () => {
2391
+ if (hideOnMobile && isMobile) {
2392
+ closeMobileMenu();
2393
+ } else if (autoCollapseOnMobile && isMobile) {
2394
+ setMobileCollapsedOverride(!effectiveCollapsed);
2395
+ } else {
2396
+ toggleCollapsed();
2397
+ }
2398
+ };
2362
2399
  React.useEffect(() => {
2363
2400
  if (navRef.current) {
2364
2401
  navRef.current.scrollTop = scrollPosRef.current;
@@ -2367,20 +2404,28 @@ function LeftNavLayout({
2367
2404
  useScrollReset_default([children], contentRef);
2368
2405
  const containerClasses = embedded ? "flex bg-background border border-border rounded-lg overflow-hidden" : "flex h-[calc(100vh-3.5rem)] md:h-[calc(100vh-4rem)] bg-background";
2369
2406
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${containerClasses} ${className}`, children: [
2407
+ !embedded && hideOnMobile && mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
2408
+ "div",
2409
+ {
2410
+ className: "fixed inset-0 bg-black/50 z-30 lg:hidden transition-opacity duration-300",
2411
+ onClick: closeMobileMenu,
2412
+ "aria-hidden": "true"
2413
+ }
2414
+ ),
2370
2415
  /* @__PURE__ */ jsxRuntime.jsx(
2371
2416
  "aside",
2372
2417
  {
2373
2418
  className: `
2374
- ${embedded ? "relative flex flex-col h-full" : "fixed lg:relative top-14 md:top-16 lg:top-0 left-0 z-40 lg:z-10 h-[calc(100vh-3.5rem)] md:h-[calc(100vh-4rem)] lg:h-full"}
2419
+ ${embedded ? "relative flex flex-col h-full" : hideOnMobile ? "fixed lg:relative top-14 md:top-16 lg:top-0 left-0 z-40 lg:z-10 h-[calc(100vh-3.5rem)] md:h-[calc(100vh-4rem)] lg:h-full" : "relative h-full"}
2375
2420
  flex flex-col shrink-0
2376
2421
  bg-background border-r border-border
2377
2422
  transition-all duration-300 ease-in-out
2378
- ${!embedded && mobileCollapsible && !mobileMenuOpen ? "-translate-x-full lg:translate-x-0" : "translate-x-0"}
2379
- ${collapsed ? "w-18" : "w-64"}
2423
+ ${!embedded && hideOnMobile && !mobileMenuOpen ? "-translate-x-full lg:translate-x-0" : "translate-x-0"}
2424
+ ${effectiveCollapsed ? "w-18" : "w-64"}
2380
2425
  ${navClassName}
2381
2426
  `,
2382
- style: !collapsed && navWidth !== "16rem" || collapsed && navWidthCollapsed !== "4.5rem" ? {
2383
- width: collapsed ? navWidthCollapsed : navWidth
2427
+ style: !effectiveCollapsed && navWidth !== "16rem" || effectiveCollapsed && navWidthCollapsed !== "4.5rem" ? {
2428
+ width: effectiveCollapsed ? navWidthCollapsed : navWidth
2384
2429
  } : void 0,
2385
2430
  "aria-label": "Main navigation",
2386
2431
  children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2388,7 +2433,7 @@ function LeftNavLayout({
2388
2433
  {
2389
2434
  ref: navRef,
2390
2435
  className: "flex-1 overflow-y-auto overflow-x-hidden scrollbar-thin",
2391
- "data-collapsed": collapsed,
2436
+ "data-collapsed": effectiveCollapsed,
2392
2437
  onScroll: (e) => {
2393
2438
  scrollPosRef.current = e.currentTarget.scrollTop;
2394
2439
  },
@@ -2407,26 +2452,26 @@ function LeftNavLayout({
2407
2452
  className: `
2408
2453
  text-sm font-semibold text-foreground
2409
2454
  transition-all duration-300 ease-in-out
2410
- ${collapsed ? "opacity-0 w-0 overflow-hidden" : "opacity-100"}
2455
+ ${effectiveCollapsed ? "opacity-0 w-0 overflow-hidden" : "opacity-100"}
2411
2456
  `,
2412
- "aria-hidden": collapsed,
2457
+ "aria-hidden": effectiveCollapsed,
2413
2458
  children: header
2414
2459
  }
2415
2460
  ),
2416
2461
  /* @__PURE__ */ jsxRuntime.jsx(
2417
2462
  icon_button_default,
2418
2463
  {
2419
- icon: collapsed ? "layout-sidebar-left-expand" : "layout-sidebar-left-collapse",
2420
- hoverIcon: collapsed ? "layout-sidebar-left-expand-filled" : "layout-sidebar-left-collapse-filled",
2421
- ariaLabel: collapsed ? "Expand sidebar" : "Collapse sidebar",
2464
+ icon: effectiveCollapsed ? "layout-sidebar-left-expand" : "layout-sidebar-left-collapse",
2465
+ hoverIcon: effectiveCollapsed ? "layout-sidebar-left-expand-filled" : "layout-sidebar-left-collapse-filled",
2466
+ ariaLabel: effectiveCollapsed ? "Expand sidebar" : "Collapse sidebar",
2422
2467
  buttonStyle: "ghost",
2423
2468
  variant: "neutral",
2424
2469
  size: "sm",
2425
2470
  iconSize: "sm",
2426
2471
  className: `
2427
- ${collapsed ? "absolute left-1/2 -translate-x-1/2" : "absolute right-0"}
2472
+ ${effectiveCollapsed ? "absolute left-1/2 -translate-x-1/2" : "absolute right-0"}
2428
2473
  `,
2429
- onClick: toggleCollapsed
2474
+ onClick: handleToggleClick
2430
2475
  }
2431
2476
  )
2432
2477
  ]
@@ -4467,7 +4512,7 @@ function DataTable({
4467
4512
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
4468
4513
  hasHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 mb-3", children: [
4469
4514
  title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground", children: title }),
4470
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
4515
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 ${searchable ? "justify-between" : "justify-end"}`, children: [
4471
4516
  searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(input_group_default, { prefix: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "search", size: "sm" }), className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
4472
4517
  input_default,
4473
4518
  {