{"version":3,"file":"FloatingSheet.mjs","names":[],"sources":["../../../src/base-ui/FloatingSheet/FloatingSheet.tsx"],"sourcesContent":["import { cx } from 'antd-style';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { FloatingSheetHeader } from './FloatingSheetHeader';\nimport { clamp, dampenValue, resolveSize } from './helpers';\nimport { styles } from './style';\nimport type { FloatingSheetProps } from './type';\nimport { useSheetDrag } from './useSheetDrag';\nimport { useSnapPoints } from './useSnapPoints';\n\nconst ANIMATION_MS = 300;\n\nexport function FloatingSheet({\n  open: openProp,\n  onOpenChange,\n  defaultOpen = false,\n  snapPoints: snapPointsProp,\n  activeSnapPoint: activeSnapPointProp,\n  onSnapPointChange,\n  minHeight: minHeightProp = 200,\n  maxHeight: maxHeightProp = 0.8,\n  restingHeight: restingHeightProp,\n  mode = 'overlay',\n  variant = 'elevated',\n  width = '100%',\n  title,\n  headerActions,\n  dismissible = true,\n  closeThreshold = 0.25,\n  children,\n  className,\n}: FloatingSheetProps) {\n  const s = styles;\n\n  // Controlled / uncontrolled open state\n  const isControlled = openProp !== undefined;\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const isOpen = isControlled ? openProp : internalOpen;\n\n  const setOpen = useCallback(\n    (value: boolean) => {\n      if (!isControlled) setInternalOpen(value);\n      onOpenChange?.(value);\n    },\n    [isControlled, onOpenChange],\n  );\n\n  // Container measurement via ResizeObserver\n  const containerRef = useRef<HTMLElement | null>(null);\n  const sheetRef = useRef<HTMLDivElement>(null);\n  const [containerHeight, setContainerHeight] = useState(0);\n\n  useEffect(() => {\n    const parent = sheetRef.current?.parentElement;\n    if (!parent) return;\n    containerRef.current = parent;\n\n    const observer = new ResizeObserver((entries) => {\n      for (const entry of entries) {\n        setContainerHeight(entry.contentRect.height);\n      }\n    });\n    observer.observe(parent);\n    setContainerHeight(parent.getBoundingClientRect().height);\n\n    return () => observer.disconnect();\n  }, []);\n\n  // Resolve min/max to px\n  const minHeightPx = useMemo(\n    () => resolveSize(minHeightProp, containerHeight),\n    [minHeightProp, containerHeight],\n  );\n  const maxHeightPx = useMemo(\n    () => resolveSize(maxHeightProp, containerHeight),\n    [maxHeightProp, containerHeight],\n  );\n  const restingHeightPx = useMemo(\n    () =>\n      restingHeightProp !== undefined\n        ? clamp(resolveSize(restingHeightProp, containerHeight), minHeightPx, maxHeightPx)\n        : minHeightPx,\n    [restingHeightProp, containerHeight, minHeightPx, maxHeightPx],\n  );\n\n  // Snap points\n  const hasSnapPoints = !!snapPointsProp && snapPointsProp.length > 0;\n  const { snapPointHeights, findActiveIndex, getSnapRelease } = useSnapPoints({\n    closeThreshold,\n    containerHeight,\n    containerRef,\n    maxHeightPx,\n    minHeightPx,\n    snapPoints: snapPointsProp ?? [],\n  });\n\n  // Compute the \"resting\" height for the current open + snap state\n  const restingHeight = useMemo(() => {\n    if (!containerHeight) return 0;\n    if (hasSnapPoints && activeSnapPointProp !== undefined) {\n      const resolved = resolveSize(activeSnapPointProp, containerHeight);\n      return clamp(resolved, minHeightPx, maxHeightPx);\n    }\n    if (hasSnapPoints && snapPointHeights.length > 0) {\n      return snapPointHeights[0];\n    }\n    return restingHeightPx;\n  }, [\n    containerHeight,\n    hasSnapPoints,\n    activeSnapPointProp,\n    snapPointHeights,\n    minHeightPx,\n    maxHeightPx,\n    restingHeightPx,\n  ]);\n\n  const [height, setHeight] = useState(isOpen ? restingHeight : 0);\n  const [isAnimating, setIsAnimating] = useState(false);\n  // Keeps sheet visible during close animation (height → 0)\n  const [isClosing, setIsClosing] = useState(false);\n  const heightBeforeDrag = useRef(0);\n  const prevOpenRef = useRef(isOpen);\n\n  // Handle open/close transitions\n  useEffect(() => {\n    const wasOpen = prevOpenRef.current;\n    prevOpenRef.current = isOpen;\n\n    if (isOpen && !wasOpen) {\n      // Opening: animate from 0 → resting height\n      setIsClosing(false);\n      setIsAnimating(true);\n      setHeight(restingHeight);\n      const timer = setTimeout(() => setIsAnimating(false), ANIMATION_MS);\n      return () => clearTimeout(timer);\n    }\n\n    if (!isOpen && wasOpen) {\n      // Closing: animate from current height → 0, then hide\n      setIsClosing(true);\n      setIsAnimating(true);\n      setHeight(0);\n      const timer = setTimeout(() => {\n        setIsAnimating(false);\n        setIsClosing(false);\n      }, ANIMATION_MS);\n      return () => clearTimeout(timer);\n    }\n  }, [isOpen]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  // Sync height when resting height changes (container resize, snap point change)\n  useEffect(() => {\n    if (isOpen && !isDragging) {\n      setHeight(restingHeight);\n    }\n  }, [restingHeight]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  // Drag handlers\n  const onDragChange = useCallback(\n    (draggedDistance: number) => {\n      const newHeight = heightBeforeDrag.current + draggedDistance;\n\n      if (hasSnapPoints) {\n        const highest = snapPointHeights.at(-1) ?? maxHeightPx;\n        const lowest = snapPointHeights[0] ?? minHeightPx;\n\n        if (newHeight > highest) {\n          const overshoot = newHeight - highest;\n          setHeight(highest + dampenValue(overshoot));\n        } else if (newHeight < lowest) {\n          const undershoot = lowest - newHeight;\n          setHeight(Math.max(0, lowest - dampenValue(undershoot)));\n        } else {\n          setHeight(newHeight);\n        }\n      } else {\n        setHeight(clamp(newHeight, 0, maxHeightPx));\n      }\n    },\n    [hasSnapPoints, snapPointHeights, maxHeightPx, minHeightPx],\n  );\n\n  const onDragEnd = useCallback(\n    (draggedDistance: number, velocity: number) => {\n      setIsAnimating(true);\n      const currentHeight = heightBeforeDrag.current + draggedDistance;\n\n      if (hasSnapPoints) {\n        const activeIndex = findActiveIndex(heightBeforeDrag.current);\n        const result = getSnapRelease({\n          activeIndex,\n          currentHeight,\n          dismissible,\n          draggedDistance,\n          velocity,\n        });\n\n        if (result.type === 'dismiss') {\n          setIsClosing(true);\n          setHeight(0);\n          const timer = setTimeout(() => {\n            setOpen(false);\n            setIsAnimating(false);\n            setIsClosing(false);\n          }, ANIMATION_MS);\n          return () => clearTimeout(timer);\n        }\n\n        setHeight(result.height);\n        const originalSnapValue = snapPointsProp?.find(\n          (sp) =>\n            resolveSize(sp, containerHeight) === result.height ||\n            clamp(resolveSize(sp, containerHeight), minHeightPx, maxHeightPx) === result.height,\n        );\n        if (originalSnapValue !== undefined) {\n          onSnapPointChange?.(originalSnapValue);\n        }\n      } else {\n        if (dismissible && currentHeight < minHeightPx * closeThreshold) {\n          setIsClosing(true);\n          setHeight(0);\n          const timer = setTimeout(() => {\n            setOpen(false);\n            setIsAnimating(false);\n            setIsClosing(false);\n          }, ANIMATION_MS);\n          return () => clearTimeout(timer);\n        }\n        setHeight(clamp(currentHeight, minHeightPx, maxHeightPx));\n      }\n\n      setTimeout(() => setIsAnimating(false), ANIMATION_MS);\n    },\n    [\n      hasSnapPoints,\n      findActiveIndex,\n      getSnapRelease,\n      dismissible,\n      snapPointsProp,\n      containerHeight,\n      minHeightPx,\n      maxHeightPx,\n      closeThreshold,\n      setOpen,\n      onSnapPointChange,\n    ],\n  );\n\n  const { isDragging, handleProps } = useSheetDrag({\n    enabled: isOpen ?? false,\n    onDragChange,\n    onDragEnd,\n  });\n\n  // Record height at drag start\n  useEffect(() => {\n    if (isDragging) {\n      heightBeforeDrag.current = height;\n    }\n  }, [isDragging]); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const isVisible = isOpen || isClosing || height > 0;\n  const shouldAnimate = !isDragging && isAnimating;\n  const inlineOverflowUp =\n    mode === 'inline' && isVisible ? Math.max(0, height - restingHeightPx) : 0;\n\n  return (\n    <div\n      data-floating-sheet=\"\"\n      data-state={isOpen ? 'open' : 'closed'}\n      ref={sheetRef}\n      className={cx(\n        s.root,\n        variant === 'embedded' ? s.embedded : s.elevated,\n        mode === 'overlay' ? s.overlay : s.inline,\n        mode === 'overlay' ? s.overlayRadius : s.inlineRadius,\n        shouldAnimate && s.transition,\n        !isVisible && s.hidden,\n        className,\n      )}\n      style={{\n        height: isVisible ? height : 0,\n        marginTop: inlineOverflowUp ? -inlineOverflowUp : undefined,\n        width,\n      }}\n    >\n      <FloatingSheetHeader\n        handleProps={handleProps}\n        headerActions={headerActions}\n        isDragging={isDragging}\n        title={title}\n      />\n      <div className={s.content}>{children}</div>\n    </div>\n  );\n}\n"],"mappings":"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"}