{"version":3,"file":"ConsoleShell.mjs","names":["Flexbox"],"sources":["../../../src/dashboard/ConsoleShell/ConsoleShell.tsx"],"sourcesContent":["'use client';\n\nimport { PanelLeft, X } from 'lucide-react';\nimport { useEffect, useId, useRef, useState } from 'react';\n\nimport Button from '@/base-ui/Button';\nimport { Drawer } from '@/base-ui/Drawer';\nimport { Flexbox } from '@/Flex';\n\nimport { useIsCompact, useLocalStorage, usePrefersReducedMotion } from '../hooks';\nimport { ConsoleShellContext } from './context';\nimport { styles } from './style';\nimport type { ConsoleShellProps, ConsoleShellState } from './type';\n\nfunction isTypingTarget(target: EventTarget | null) {\n  if (!(target instanceof HTMLElement)) return false;\n  const tag = target.tagName;\n  return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable;\n}\n\nfunction ConsoleShell({\n  brand,\n  breadcrumb,\n  children,\n  className,\n  collapsed,\n  closeNavigationLabel = 'Close navigation',\n  collapseLabel = 'Collapse sidebar',\n  defaultCollapsed = false,\n  expandLabel = 'Expand sidebar',\n  footer,\n  hotkey = true,\n  navigation,\n  onCollapsedChange,\n  openNavigationLabel = 'Open navigation',\n  skipToContentLabel = 'Skip to content',\n  storageKey,\n  tools,\n  ...rest\n}: ConsoleShellProps) {\n  const mainId = `console-main-${useId().replaceAll(':', '')}`;\n  const shellRef = useRef<HTMLDivElement>(null);\n  const isCompact = useIsCompact();\n  const reducedMotion = usePrefersReducedMotion();\n  const [storedCollapsed, setStoredCollapsed] = useLocalStorage(storageKey, defaultCollapsed);\n  const [drawerOpen, setDrawerOpen] = useState(false);\n  const isControlled = collapsed !== undefined;\n  const railCollapsed = isControlled ? collapsed : storedCollapsed;\n  const railed = railCollapsed && !isCompact;\n\n  const setCollapsed = (next: boolean) => {\n    if (!isControlled) setStoredCollapsed(next);\n    onCollapsedChange?.(next);\n  };\n\n  const closeNavigation = () => setDrawerOpen(false);\n  const toggleNavigation = () => {\n    if (isCompact) {\n      setDrawerOpen((open) => !open);\n      return;\n    }\n    setCollapsed(!railCollapsed);\n  };\n  const toggleRef = useRef(toggleNavigation);\n  toggleRef.current = toggleNavigation;\n\n  useEffect(() => {\n    if (!hotkey) return;\n    const node = shellRef.current;\n    if (!node) return;\n\n    const onKeyDown = (event: KeyboardEvent) => {\n      if (event.key.toLowerCase() !== 'b' || !(event.metaKey || event.ctrlKey) || event.altKey) {\n        return;\n      }\n      if (event.repeat || isTypingTarget(event.target)) return;\n      if (!node.contains(event.target as Node)) return;\n      event.preventDefault();\n      toggleRef.current();\n    };\n\n    document.addEventListener('keydown', onKeyDown);\n    return () => document.removeEventListener('keydown', onKeyDown);\n  }, [hotkey]);\n\n  const stateFor = (rail: boolean): ConsoleShellState => ({\n    closeNavigation,\n    collapsed: rail,\n    compact: isCompact,\n  });\n\n  const sidebar = (rail: boolean) => (\n    <ConsoleShellContext value={stateFor(rail)}>\n      {brand || isCompact ? (\n        <div className={styles.brand} data-collapsed={rail}>\n          {brand}\n          {isCompact ? (\n            // In the drawer the close button sits in the brand row's flow, so it never\n            // overlaps a brand switcher the way the drawer's floating close button did.\n            <Button\n              aria-label={closeNavigationLabel}\n              className={styles.brandClose}\n              icon={X}\n              type=\"text\"\n              onClick={closeNavigation}\n            />\n          ) : null}\n        </div>\n      ) : null}\n      {navigation ? <div className={styles.navSlot}>{navigation}</div> : null}\n      {footer ? <div className={styles.sidebarBottom}>{footer}</div> : null}\n    </ConsoleShellContext>\n  );\n\n  const toggleLabel = isCompact ? openNavigationLabel : railed ? expandLabel : collapseLabel;\n\n  return (\n    <div\n      className={className ? `${styles.shell} ${className}` : styles.shell}\n      data-console-shell=\"\"\n      ref={shellRef}\n      {...rest}\n    >\n      <a\n        className={styles.skipLink}\n        href={`#${mainId}`}\n        onClick={(event) => {\n          event.preventDefault();\n          document.getElementById(mainId)?.focus();\n        }}\n      >\n        {skipToContentLabel}\n      </a>\n      <aside className={styles.sidebar} data-collapsed={railed} data-instant={reducedMotion}>\n        {!isCompact && sidebar(railed)}\n      </aside>\n      {isCompact ? (\n        <Drawer\n          noHeader\n          classNames={{ bodyContent: styles.drawerBody }}\n          closable={false}\n          open={drawerOpen}\n          placement=\"left\"\n          width={272}\n          onClose={closeNavigation}\n        >\n          <Flexbox height=\"100%\">{sidebar(false)}</Flexbox>\n        </Drawer>\n      ) : null}\n      <div className={styles.workspace}>\n        <header className={styles.topbar}>\n          <Button\n            aria-label={toggleLabel}\n            icon={PanelLeft}\n            type=\"text\"\n            onClick={toggleNavigation}\n          />\n          <span aria-hidden className={styles.topbarDivider} />\n          <div className={styles.topbarMain}>{breadcrumb}</div>\n          {tools ? <div className={styles.tools}>{tools}</div> : null}\n        </header>\n        <main className={styles.main} id={mainId} tabIndex={-1}>\n          {children}\n        </main>\n      </div>\n    </div>\n  );\n}\n\nConsoleShell.displayName = 'ConsoleShell';\n\nexport default ConsoleShell;\n"],"mappings":"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"}