{"version":3,"file":"useSidebar.cjs","sources":["../../../../src/components/Sidebar/useSidebar.tsx"],"sourcesContent":["import { clamp } from 'lodash';\nimport React, { useCallback } from 'react';\n\nimport { store } from '@grafana/data';\n\nimport { useTheme2 } from '../../themes/ThemeContext';\n\nexport type SidebarPosition = 'left' | 'right';\n\nexport interface SidebarContextValue {\n  isDocked: boolean;\n  position: SidebarPosition;\n  compact: boolean;\n  hasOpenPane?: boolean;\n  tabsMode?: boolean;\n  outerWrapperProps: React.HTMLAttributes<HTMLDivElement>;\n  paneWidth: number;\n  bottomMargin: number;\n  edgeMargin: number;\n  contentMargin: number;\n  isHidden: boolean;\n  onToggleDock: () => void;\n  onResize: (diff: number) => void;\n  /** Called when pane is closed or clicked outside of (in undocked mode) */\n  onClosePane?: () => void;\n}\n\nexport const SidebarContext: React.Context<SidebarContextValue | undefined> = React.createContext<\n  SidebarContextValue | undefined\n>(undefined);\n\nexport interface UseSideBarOptions {\n  hasOpenPane?: boolean;\n  position?: SidebarPosition;\n  tabsMode?: boolean;\n  /** Initial state for compact mode */\n  defaultToCompact?: boolean;\n  /** Initial state for docked mode */\n  defaultToDocked?: boolean;\n  /** defaults to 2 grid units (16px) */\n  bottomMargin?: number;\n  /** defaults to 2 grid units (16px) */\n  edgeMargin?: number;\n  /** defaults to 2 grid units (16px) */\n  contentMargin?: number;\n  /** Called when pane is closed or clicked outside of (in undocked mode) */\n  onClosePane?: () => void;\n  /**\n   * Optional key to use for persisting sidebar state (docked / compact / size)\n   * Can only be app name as the final local storag key will be `grafana.ui.sidebar.{persistanceKey}.{docked|compact|size}`\n   */\n  persistanceKey?: string;\n  /** Whether the sidebar is hidden */\n  isHidden?: boolean;\n}\n\nexport const SIDE_BAR_WIDTH_ICON_ONLY = 5;\nexport const SIDE_BAR_WIDTH_WITH_TEXT = 8;\n\nexport function useSidebar({\n  hasOpenPane,\n  position = 'right',\n  tabsMode,\n  defaultToCompact = true,\n  defaultToDocked = false,\n  bottomMargin = 2,\n  edgeMargin = 2,\n  contentMargin = 2,\n  persistanceKey,\n  onClosePane,\n  isHidden = false,\n}: UseSideBarOptions): SidebarContextValue {\n  const theme = useTheme2();\n\n  const [isDocked, setIsDocked] = useSidebarSavedState(persistanceKey, 'docked', defaultToDocked);\n  const [compact, setCompact] = useSidebarSavedState(persistanceKey, 'compact', defaultToCompact);\n  const [paneWidth, setPaneWidth] = useSidebarSavedState(persistanceKey, 'size', 280);\n\n  // Used to accumulate drag distance to know when to change compact mode\n  const [_, setCompactDrag] = React.useState(0);\n\n  const onToggleDock = useCallback(() => {\n    setIsDocked((prev) => {\n      return !prev;\n    });\n  }, [setIsDocked]);\n\n  // Calculate how much space the outer wrapper needs to reserve for the sidebar toolbar + pane (if docked)\n  const prop = position === 'right' ? 'paddingRight' : 'paddingLeft';\n  const toolbarWidth =\n    ((compact ? SIDE_BAR_WIDTH_ICON_ONLY : SIDE_BAR_WIDTH_WITH_TEXT) + edgeMargin + contentMargin) *\n    theme.spacing.gridSize;\n\n  const outerWrapperProps = isHidden\n    ? {}\n    : {\n        style: {\n          [prop]: isDocked && hasOpenPane ? paneWidth + toolbarWidth : toolbarWidth,\n        },\n      };\n\n  const onResize = useCallback(\n    (diff: number) => {\n      setPaneWidth((prevWidth) => {\n        // If no pane is open we use the resize action to toggle compact mode (button text visibility)\n        if (!hasOpenPane) {\n          setCompactDrag((prevDrag) => {\n            const newDrag = prevDrag + diff;\n            if (newDrag < -20 && !compact) {\n              setCompact(() => true);\n              return 0;\n            } else if (newDrag > 20 && compact) {\n              setCompact(() => false);\n              return 0;\n            }\n\n            return newDrag;\n          });\n\n          return prevWidth;\n        }\n\n        return clamp(prevWidth + diff, 100, 500);\n      });\n    },\n    [hasOpenPane, setCompact, setPaneWidth, compact]\n  );\n\n  return {\n    isDocked,\n    onToggleDock,\n    onResize,\n    outerWrapperProps,\n    position,\n    compact,\n    hasOpenPane,\n    tabsMode,\n    paneWidth,\n    edgeMargin,\n    bottomMargin,\n    contentMargin,\n    isHidden,\n    onClosePane,\n  };\n}\n\nfunction useSidebarSavedState<T = number | boolean>(\n  persistanceKey: string | undefined,\n  subKey: string,\n  defaultValue: T\n) {\n  const [state, setState] = React.useState<T>(() => {\n    if (!persistanceKey) {\n      return defaultValue;\n    }\n\n    if (typeof defaultValue === 'boolean') {\n      // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n      return store.getBool(`grafana.ui.sidebar.${persistanceKey}.${subKey}`, defaultValue) as T;\n    }\n\n    if (typeof defaultValue === 'number') {\n      const value = Number.parseInt(store.get(`grafana.ui.sidebar.${persistanceKey}.${subKey}`), 10);\n      if (Number.isNaN(value)) {\n        return defaultValue;\n      }\n\n      // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n      return value as T;\n    }\n\n    return defaultValue;\n  });\n\n  const setPersisted = useCallback(\n    (cb: (prevState: T) => T) => {\n      setState((prevState) => {\n        const newState = cb(prevState);\n\n        if (!persistanceKey) {\n          return newState;\n        }\n\n        if (persistanceKey) {\n          store.set(`grafana.ui.sidebar.${persistanceKey}.${subKey}`, String(newState));\n        }\n\n        return newState;\n      });\n    },\n    [persistanceKey, subKey]\n  );\n\n  return [state, setPersisted] as const;\n}\n"],"names":["React","useTheme2","useCallback","clamp","store"],"mappings":"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"}