{"version":3,"file":"useSheet.mjs","names":[],"sources":["../../../../package/common/hooks/useSheet.ts"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport { Presentation } from '../configProvider/presentation.types';\nimport { useCoarsePointer } from './useCoarsePointer';\nimport { useMediaQuery } from './useMediaQuery';\nimport { useVisualViewportSize } from './useVisualViewportSize';\n\n/** Below this, `Presentation.Auto` switches a touch device over to a sheet. */\nconst SMALL_SCREEN_QUERY = '(max-width: 767px)';\n\n/** Sliver kept above a full-height sheet, so it still reads as a sheet rather than a full screen. */\nconst TOP_GAP = 8;\n\nexport interface Sheet {\n  /** Whether the popup should render as a bottom sheet instead of anchored to its trigger. */\n  isSheet: boolean;\n  /**\n   * Inline style for the sheet root: keeps it above an open on-screen keyboard, and hands the CSS\n   * the height actually left on screen as `--sheet-available-height`.\n   */\n  sheetStyle: CSSProperties | undefined;\n}\n\n/**\n * Resolves whether a popup presents as a bottom sheet.\n *\n * `Auto` asks for a coarse pointer *and* a small screen: pointer alone turns a touchscreen laptop\n * into a phone, and width alone turns a narrow desktop window into one.\n */\nexport function useSheet(presentation: Presentation = Presentation.Default): Sheet {\n  const isCoarsePointer = useCoarsePointer();\n  const isSmallScreen = useMediaQuery(SMALL_SCREEN_QUERY);\n  const { height: viewportHeight, offsetTop } = useVisualViewportSize();\n\n  const isSheet =\n    presentation === Presentation.Sheet || (presentation === Presentation.Auto && isCoarsePointer && isSmallScreen);\n\n  if (!isSheet) return { isSheet: false, sheetStyle: undefined };\n\n  // `position: fixed` resolves against the layout viewport, which an open keyboard doesn't\n  // shrink — so a sheet at `bottom: 0` sits behind the keyboard. Lift it by the difference.\n  const keyboardHeight =\n    typeof window === 'undefined' ? 0 : Math.max(0, window.innerHeight - (offsetTop + viewportHeight));\n\n  // Lifting the sheet is only half of it: it also has to *fit* in what's left. No viewport unit\n  // can express that, because `dvh` (like `vh`) measures the layout viewport, which the keyboard\n  // doesn't shrink either — so a tall sheet capped at, say, `90dvh` and lifted by the keyboard\n  // height ends up with its top edge above the screen, taking the header and the first part of\n  // the body with it, out of reach of the body's own scrolling. The visual viewport is the only\n  // thing that knows the real number, so it's measured here and handed to the CSS to clamp with.\n  const availableHeight = Math.max(0, viewportHeight - TOP_GAP);\n\n  const sheetStyle = {\n    bottom: keyboardHeight,\n    '--sheet-available-height': `${availableHeight}px`,\n  } as CSSProperties;\n\n  return { isSheet: true, sheetStyle };\n}\n\nexport default useSheet;\n"],"mappings":"kOAOA,IAAM,EAAqB,qBAGrB,EAAU,EAkBhB,SAAgB,EAAS,EAA6B,EAAa,QAAgB,CACjF,IAAM,EAAkB,EAAiB,EACnC,EAAgB,EAAc,CAAkB,EAChD,CAAE,OAAQ,EAAgB,aAAc,EAAsB,EAyBpE,OAtBE,IAAiB,EAAa,OAAU,IAAiB,EAAa,MAAQ,GAAmB,EAsB5F,CAAE,QAAS,GAAM,WAAA,CAJtB,OAXA,OAAO,OAAW,IAAc,EAAI,KAAK,IAAI,EAAG,OAAO,aAAe,EAAY,EAAe,EAYjG,2BAA4B,GAJN,KAAK,IAAI,EAAG,EAAiB,CAIpB,EAAgB,GAGzB,CAAW,EApBd,CAAE,QAAS,GAAO,WAAY,IAAA,EAAU,CAqB/D"}