UNPKG

82 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.es.js","sources":["../src/hooks/useLayoutEffect.tsx","../src/utils.ts","../src/hooks/useSnapPoints.tsx","../src/machines/overlay.ts","../src/BottomSheet.tsx","../src/hooks/useReady.tsx","../src/hooks/useReducedMotion.tsx","../src/hooks/useSpring.tsx","../src/hooks/useScrollLock.tsx","../src/hooks/useAriaHider.tsx","../src/hooks/useFocusTrap.tsx","../src/hooks/useSpringInterpolations.tsx","../src/index.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect as useLayoutEffectSafely } from 'react'\n\n// Ensure the name used in components is useLayoutEffect so the eslint react hooks plugin works\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffectSafely : useEffect\n","/* eslint-disable no-self-compare */\n\n// stolen from lodash\nexport function clamp(number: number, lower: number, upper: number) {\n number = +number\n lower = +lower\n upper = +upper\n lower = lower === lower ? lower : 0\n upper = upper === upper ? upper : 0\n if (number === number) {\n number = number <= upper ? number : upper\n number = number >= lower ? number : lower\n }\n return number\n}\n\n// Mwahaha easiest way to filter out NaN I ever saw! >:3\nexport function deleteNaN(arr) {\n const set = new Set(arr)\n set.delete(NaN)\n return [...set]\n}\n\nexport function roundAndCheckForNaN(unrounded) {\n const rounded = Math.round(unrounded)\n if (Number.isNaN(unrounded)) {\n throw new TypeError(\n 'Found a NaN! Check your snapPoints / defaultSnap / snapTo '\n )\n }\n\n return rounded\n}\n\n// Validate, sanitize, round and dedupe snap points, as well as extracting the minSnap and maxSnap points\nexport function processSnapPoints(unsafeSnaps: number | number[], maxHeight) {\n const safeSnaps = [].concat(unsafeSnaps).map(roundAndCheckForNaN)\n\n const snapPointsDedupedSet = safeSnaps.reduce((acc, snapPoint) => {\n acc.add(clamp(snapPoint, 0, maxHeight))\n return acc\n }, new Set<number>())\n\n const snapPoints = Array.from(snapPointsDedupedSet)\n\n const minSnap = Math.min(...snapPoints)\n if (Number.isNaN(minSnap)) {\n throw new TypeError('minSnap is NaN')\n }\n const maxSnap = Math.max(...snapPoints)\n if (Number.isNaN(maxSnap)) {\n throw new TypeError('maxSnap is NaN')\n }\n\n return {\n snapPoints,\n minSnap,\n maxSnap,\n }\n}\n\nexport const debugging =\n process.env.NODE_ENV === 'development' && typeof window !== 'undefined'\n ? window.location.search === '?debug'\n : false\n","import React, {\n useCallback,\n useDebugValue,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { ResizeObserver, ResizeObserverEntry } from '@juggle/resize-observer'\nimport type { defaultSnapProps, ResizeSource, snapPoints } from '../types'\nimport { processSnapPoints, roundAndCheckForNaN } from '../utils'\nimport { useReady } from './useReady'\nimport { ResizeObserverOptions } from '@juggle/resize-observer/lib/ResizeObserverOptions'\nimport { useLayoutEffect } from './useLayoutEffect'\n\nexport function useSnapPoints({\n contentRef,\n controlledMaxHeight,\n footerEnabled,\n footerRef,\n getSnapPoints,\n headerEnabled,\n headerRef,\n heightRef,\n lastSnapRef,\n ready,\n registerReady,\n resizeSourceRef,\n}: {\n contentRef: React.RefObject<Element>\n controlledMaxHeight?: number\n footerEnabled: boolean\n footerRef: React.RefObject<Element>\n getSnapPoints: snapPoints\n headerEnabled: boolean\n headerRef: React.RefObject<Element>\n heightRef: React.RefObject<number>\n lastSnapRef: React.RefObject<number>\n ready: boolean\n registerReady: ReturnType<typeof useReady>['registerReady']\n resizeSourceRef: React.MutableRefObject<ResizeSource>\n}) {\n const { maxHeight, minHeight, headerHeight, footerHeight } = useDimensions({\n contentRef: contentRef,\n controlledMaxHeight,\n footerEnabled,\n footerRef,\n headerEnabled,\n headerRef,\n registerReady,\n resizeSourceRef,\n })\n\n const { snapPoints, minSnap, maxSnap } = processSnapPoints(\n ready\n ? getSnapPoints({\n height: heightRef.current,\n footerHeight,\n headerHeight,\n minHeight,\n maxHeight,\n })\n : [0],\n maxHeight\n )\n //console.log({ snapPoints, minSnap, maxSnap })\n\n // @TODO investigate the gains from memoizing this\n function findSnap(\n numberOrCallback: number | ((state: defaultSnapProps) => number)\n ) {\n let unsafeSearch: number\n if (typeof numberOrCallback === 'function') {\n unsafeSearch = numberOrCallback({\n footerHeight,\n headerHeight,\n height: heightRef.current,\n minHeight,\n maxHeight,\n snapPoints,\n lastSnap: lastSnapRef.current,\n })\n } else {\n unsafeSearch = numberOrCallback\n }\n const querySnap = roundAndCheckForNaN(unsafeSearch)\n return snapPoints.reduce(\n (prev, curr) =>\n Math.abs(curr - querySnap) < Math.abs(prev - querySnap) ? curr : prev,\n minSnap\n )\n }\n\n useDebugValue(`minSnap: ${minSnap}, maxSnap:${maxSnap}`)\n\n return { minSnap, maxSnap, findSnap, maxHeight }\n}\n\nfunction useDimensions({\n contentRef,\n controlledMaxHeight,\n footerEnabled,\n footerRef,\n headerEnabled,\n headerRef,\n registerReady,\n resizeSourceRef,\n}: {\n contentRef: React.RefObject<Element>\n controlledMaxHeight?: number\n footerEnabled: boolean\n footerRef: React.RefObject<Element>\n headerEnabled: boolean\n headerRef: React.RefObject<Element>\n registerReady: ReturnType<typeof useReady>['registerReady']\n resizeSourceRef: React.MutableRefObject<ResizeSource>\n}) {\n const setReady = useMemo(() => registerReady('contentHeight'), [\n registerReady,\n ])\n const maxHeight = useMaxHeight(\n controlledMaxHeight,\n registerReady,\n resizeSourceRef\n )\n\n // @TODO probably better to forward props instead of checking refs to decide if it's enabled\n const headerHeight = useElementSizeObserver(headerRef, {\n label: 'headerHeight',\n enabled: headerEnabled,\n resizeSourceRef,\n })\n const contentHeight = useElementSizeObserver(contentRef, {\n label: 'contentHeight',\n enabled: true,\n resizeSourceRef,\n })\n const footerHeight = useElementSizeObserver(footerRef, {\n label: 'footerHeight',\n enabled: footerEnabled,\n resizeSourceRef,\n })\n const minHeight =\n Math.min(maxHeight - headerHeight - footerHeight, contentHeight) +\n headerHeight +\n footerHeight\n\n useDebugValue(`minHeight: ${minHeight}`)\n\n const ready = contentHeight > 0\n useEffect(() => {\n if (ready) {\n setReady()\n }\n }, [ready, setReady])\n\n return {\n maxHeight,\n minHeight,\n headerHeight,\n footerHeight,\n }\n}\n\nconst observerOptions: ResizeObserverOptions = {\n // Respond to changes to padding, happens often on iOS when using env(safe-area-inset-bottom)\n // And the user hides or shows the Safari browser toolbar\n box: 'border-box',\n}\n/**\n * Hook for determining the size of an element using the Resize Observer API.\n *\n * @param ref - A React ref to an element\n */\nfunction useElementSizeObserver(\n ref: React.RefObject<Element>,\n {\n label,\n enabled,\n resizeSourceRef,\n }: {\n label: string\n enabled: boolean\n resizeSourceRef: React.MutableRefObject<ResizeSource>\n }\n): number {\n let [size, setSize] = useState(0)\n\n useDebugValue(`${label}: ${size}`)\n\n const handleResize = useCallback(\n (entries: ResizeObserverEntry[]) => {\n // we only observe one element, so accessing the first entry here is fine\n setSize(entries[0].borderBoxSize[0].blockSize)\n resizeSourceRef.current = 'element'\n },\n [resizeSourceRef]\n )\n\n useLayoutEffect(() => {\n if (!ref.current || !enabled) {\n return\n }\n\n const resizeObserver = new ResizeObserver(handleResize)\n resizeObserver.observe(ref.current, observerOptions)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [ref, handleResize, enabled])\n\n return enabled ? size : 0\n}\n\n// Blazingly keep track of the current viewport height without blocking the thread, keeping that sweet 60fps on smartphones\nfunction useMaxHeight(\n controlledMaxHeight,\n registerReady: ReturnType<typeof useReady>['registerReady'],\n resizeSourceRef: React.MutableRefObject<ResizeSource>\n) {\n const setReady = useMemo(() => registerReady('maxHeight'), [registerReady])\n const [maxHeight, setMaxHeight] = useState(() =>\n roundAndCheckForNaN(controlledMaxHeight) || typeof window !== 'undefined'\n ? window.innerHeight\n : 0\n )\n const ready = maxHeight > 0\n const raf = useRef(0)\n\n useDebugValue(controlledMaxHeight ? 'controlled' : 'auto')\n\n useEffect(() => {\n if (ready) {\n setReady()\n }\n }, [ready, setReady])\n\n useLayoutEffect(() => {\n // Bail if the max height is a controlled prop\n if (controlledMaxHeight) {\n setMaxHeight(roundAndCheckForNaN(controlledMaxHeight))\n resizeSourceRef.current = 'maxheightprop'\n\n return\n }\n\n const handleResize = () => {\n if (raf.current) {\n // bail to throttle the amount of resize changes\n return\n }\n\n // throttle state changes using rAF\n raf.current = requestAnimationFrame(() => {\n setMaxHeight(window.innerHeight)\n resizeSourceRef.current = 'window'\n\n raf.current = 0\n })\n }\n window.addEventListener('resize', handleResize)\n setMaxHeight(window.innerHeight)\n resizeSourceRef.current = 'window'\n setReady()\n\n return () => {\n window.removeEventListener('resize', handleResize)\n cancelAnimationFrame(raf.current)\n }\n }, [controlledMaxHeight, setReady, resizeSourceRef])\n\n return maxHeight\n}\n","import { Machine, assign } from 'xstate'\n\n// This is the root machine, composing all the other machines and is the brain of the bottom sheet\n\ninterface OverlayStateSchema {\n states: {\n // the overlay usually starts in the closed position\n closed: {}\n opening: {\n states: {\n // Used to fire off the springStart event\n start: {}\n // Decide how to transition to the open state based on what the initialState is\n transition: {}\n // Fast enter animation, sheet is open by default\n immediately: {\n states: {\n open: {}\n activating: {}\n }\n }\n smoothly: {\n states: {\n // This state only happens when the overlay should start in an open state, instead of animating from the bottom\n // openImmediately: {}\n // visuallyHidden will render the overlay in the open state, but with opacity 0\n // doing this solves two problems:\n // on Android focusing an input element will trigger the softkeyboard to show up, which will change the viewport height\n // on iOS the focus event will break the view by triggering a scrollIntoView event if focus happens while the overlay is below the viewport and body got overflow:hidden\n // by rendering things with opacity 0 we ensure keyboards and scrollIntoView all happen in a way that match up with what the sheet will look like.\n // we can then move it to the opening position below the viewport, and animate it into view without worrying about height changes or scrolling overflow:hidden events\n visuallyHidden: {}\n // In this state we're activating focus traps, scroll locks and more, this will sometimes trigger soft keyboards and scrollIntoView\n // @TODO we might want to add a delay here before proceeding to open, to give android and iOS enough time to adjust the viewport when focusing an interactive element\n activating: {}\n // Animates from the bottom\n open: {}\n }\n }\n // Used to fire off the springEnd event\n end: {}\n // And finally we're ready to transition to open\n done: {}\n }\n }\n open: {}\n // dragging responds to user gestures, which may interrupt the opening state, closing state or snapping\n // when interrupting an opening event, it fires onSpringEnd(OPEN) before onSpringStart(DRAG)\n // when interrupting a closing event, it fires onSpringCancel(CLOSE) before onSpringStart(DRAG)\n // when interrupting a dragging event, it fires onSpringCancel(SNAP) before onSpringStart(DRAG)\n dragging: {}\n // snapping happens whenever transitioning to a new snap point, often after dragging\n snapping: {\n states: {\n start: {}\n snappingSmoothly: {}\n end: {}\n done: {}\n }\n }\n resizing: {\n states: {\n start: {}\n resizingSmoothly: {}\n end: {}\n done: {}\n }\n }\n closing: {\n states: {\n start: {}\n deactivating: {}\n closingSmoothly: {}\n end: {}\n done: {}\n }\n }\n }\n}\n\ntype OverlayEvent =\n | { type: 'OPEN' }\n | {\n type: 'SNAP'\n payload: {\n y: number\n velocity: number\n source: 'dragging' | 'custom' | string\n }\n }\n | { type: 'CLOSE' }\n | { type: 'DRAG' }\n | { type: 'RESIZE' }\n\n// The context (extended state) of the machine\ninterface OverlayContext {\n initialState: 'OPEN' | 'CLOSED'\n}\nfunction sleep(ms = 1000) {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nconst cancelOpen = {\n CLOSE: { target: '#overlay.closing', actions: 'onOpenCancel' },\n}\nconst openToDrag = {\n DRAG: { target: '#overlay.dragging', actions: 'onOpenEnd' },\n}\nconst openToResize = {\n RESIZE: { target: '#overlay.resizing', actions: 'onOpenEnd' },\n}\n\nconst initiallyOpen = ({ initialState }) => initialState === 'OPEN'\nconst initiallyClosed = ({ initialState }) => initialState === 'CLOSED'\n\n// Copy paste the machine into https://xstate.js.org/viz/ to make sense of what's going on in here ;)\n\nexport const overlayMachine = Machine<\n OverlayContext,\n OverlayStateSchema,\n OverlayEvent\n>(\n {\n id: 'overlay',\n initial: 'closed',\n context: { initialState: 'CLOSED' },\n states: {\n closed: { on: { OPEN: 'opening', CLOSE: undefined } },\n opening: {\n initial: 'start',\n states: {\n start: {\n invoke: {\n src: 'onOpenStart',\n onDone: 'transition',\n },\n },\n transition: {\n always: [\n { target: 'immediately', cond: 'initiallyOpen' },\n { target: 'smoothly', cond: 'initiallyClosed' },\n ],\n },\n immediately: {\n initial: 'open',\n states: {\n open: {\n invoke: { src: 'openImmediately', onDone: 'activating' },\n },\n activating: {\n invoke: { src: 'activate', onDone: '#overlay.opening.end' },\n on: { ...openToDrag, ...openToResize },\n },\n },\n },\n smoothly: {\n initial: 'visuallyHidden',\n states: {\n visuallyHidden: {\n invoke: { src: 'renderVisuallyHidden', onDone: 'activating' },\n },\n activating: {\n invoke: { src: 'activate', onDone: 'open' },\n },\n open: {\n invoke: { src: 'openSmoothly', onDone: '#overlay.opening.end' },\n on: { ...openToDrag, ...openToResize },\n },\n },\n },\n end: {\n invoke: { src: 'onOpenEnd', onDone: 'done' },\n on: { CLOSE: '#overlay.closing', DRAG: '#overlay.dragging' },\n },\n done: {\n type: 'final',\n },\n },\n on: { ...cancelOpen },\n onDone: 'open',\n },\n open: {\n on: { DRAG: '#overlay.dragging', SNAP: 'snapping', RESIZE: 'resizing' },\n },\n dragging: {\n on: { SNAP: 'snapping' },\n },\n snapping: {\n initial: 'start',\n states: {\n start: {\n invoke: {\n src: 'onSnapStart',\n onDone: 'snappingSmoothly',\n },\n entry: [\n assign({\n // @ts-expect-error\n y: (_, { payload: { y } }) => y,\n velocity: (_, { payload: { velocity } }) => velocity,\n snapSource: (_, { payload: { source = 'custom' } }) => source,\n }),\n ],\n },\n snappingSmoothly: {\n invoke: { src: 'snapSmoothly', onDone: 'end' },\n },\n end: {\n invoke: { src: 'onSnapEnd', onDone: 'done' },\n on: {\n RESIZE: '#overlay.resizing',\n SNAP: '#overlay.snapping',\n CLOSE: '#overlay.closing',\n DRAG: '#overlay.dragging',\n },\n },\n done: { type: 'final' },\n },\n on: {\n SNAP: { target: 'snapping', actions: 'onSnapEnd' },\n RESIZE: { target: '#overlay.resizing', actions: 'onSnapCancel' },\n DRAG: { target: '#overlay.dragging', actions: 'onSnapCancel' },\n CLOSE: { target: '#overlay.closing', actions: 'onSnapCancel' },\n },\n onDone: 'open',\n },\n resizing: {\n initial: 'start',\n states: {\n start: {\n invoke: {\n src: 'onResizeStart',\n onDone: 'resizingSmoothly',\n },\n },\n resizingSmoothly: {\n invoke: { src: 'resizeSmoothly', onDone: 'end' },\n },\n end: {\n invoke: { src: 'onResizeEnd', onDone: 'done' },\n on: {\n SNAP: '#overlay.snapping',\n CLOSE: '#overlay.closing',\n DRAG: '#overlay.dragging',\n },\n },\n done: { type: 'final' },\n },\n on: {\n RESIZE: { target: 'resizing', actions: 'onResizeEnd' },\n SNAP: { target: 'snapping', actions: 'onResizeCancel' },\n DRAG: { target: '#overlay.dragging', actions: 'onResizeCancel' },\n CLOSE: { target: '#overlay.closing', actions: 'onResizeCancel' },\n },\n onDone: 'open',\n },\n closing: {\n initial: 'start',\n states: {\n start: {\n invoke: {\n src: 'onCloseStart',\n onDone: 'deactivating',\n },\n on: { OPEN: { target: '#overlay.open', actions: 'onCloseCancel' } },\n },\n deactivating: {\n invoke: { src: 'deactivate', onDone: 'closingSmoothly' },\n },\n closingSmoothly: {\n invoke: { src: 'closeSmoothly', onDone: 'end' },\n },\n end: {\n invoke: { src: 'onCloseEnd', onDone: 'done' },\n on: {\n OPEN: { target: '#overlay.opening', actions: 'onCloseCancel' },\n },\n },\n done: { type: 'final' },\n },\n on: {\n CLOSE: undefined,\n OPEN: { target: '#overlay.opening', actions: 'onCloseCancel' },\n },\n onDone: 'closed',\n },\n },\n on: {\n CLOSE: 'closing',\n },\n },\n {\n actions: {\n onOpenCancel: (context, event) => {\n console.log('onOpenCancel', { context, event })\n },\n onSnapCancel: (context, event) => {\n console.log('onSnapCancel', { context, event })\n },\n onResizeCancel: (context, event) => {\n console.log('onResizeCancel', { context, event })\n },\n onCloseCancel: (context, event) => {\n console.log('onCloseCancel', { context, event })\n },\n onOpenEnd: (context, event) => {\n console.log('onOpenCancel', { context, event })\n },\n onSnapEnd: (context, event) => {\n console.log('onSnapEnd', { context, event })\n },\n onRezizeEnd: (context, event) => {\n console.log('onRezizeEnd', { context, event })\n },\n },\n services: {\n onSnapStart: async () => {\n await sleep()\n },\n onOpenStart: async () => {\n await sleep()\n },\n onCloseStart: async () => {\n await sleep()\n },\n onResizeStart: async () => {\n await sleep()\n },\n onSnapEnd: async () => {\n await sleep()\n },\n onOpenEnd: async () => {\n await sleep()\n },\n onCloseEnd: async () => {\n await sleep()\n },\n onResizeEnd: async () => {\n await sleep()\n },\n renderVisuallyHidden: async (context, event) => {\n console.group('renderVisuallyHidden')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n activate: async (context, event) => {\n console.group('activate')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n deactivate: async (context, event) => {\n console.group('deactivate')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n openSmoothly: async (context, event) => {\n console.group('openSmoothly')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n openImmediately: async (context, event) => {\n console.group('openImmediately')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n snapSmoothly: async (context, event) => {\n console.group('snapSmoothly')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n resizeSmoothly: async (context, event) => {\n console.group('resizeSmoothly')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n closeSmoothly: async (context, event) => {\n console.group('closeSmoothly')\n console.log({ context, event })\n await sleep()\n console.groupEnd()\n },\n },\n guards: { initiallyClosed, initiallyOpen },\n }\n)\n","//\n// In order to greatly reduce complexity this component is designed to always transition to open on mount, and then\n// transition to a closed state later. This ensures that all memory used to keep track of animation and gesture state\n// can be reclaimed after the sheet is closed and then unmounted.\n// It also ensures that when transitioning to open on mount the state is always clean, not affected by previous states that could\n// cause race conditions.\n\nimport { useMachine } from '@xstate/react'\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react'\nimport { animated, config } from 'react-spring'\nimport { rubberbandIfOutOfBounds, useDrag } from 'react-use-gesture'\nimport {\n useAriaHider,\n useFocusTrap,\n useLayoutEffect,\n useReady,\n useReducedMotion,\n useScrollLock,\n useSnapPoints,\n useSpring,\n useSpringInterpolations,\n} from './hooks'\nimport { overlayMachine } from './machines/overlay'\nimport type {\n defaultSnapProps,\n Props,\n RefHandles,\n ResizeSource,\n SnapPointProps,\n} from './types'\nimport { debugging } from './utils'\n\nconst { tension, friction } = config.default\n\n// @TODO implement AbortController to deal with race conditions\n\n// @TODO rename to SpringBottomSheet and allow userland to import it directly, for those who want maximum control and minimal bundlesize\nexport const BottomSheet = React.forwardRef<\n RefHandles,\n {\n initialState: 'OPEN' | 'CLOSED'\n lastSnapRef: React.MutableRefObject<number | null>\n } & Props\n>(function BottomSheetInternal(\n {\n children,\n sibling,\n className,\n footer,\n header,\n open: _open,\n initialState,\n lastSnapRef,\n initialFocusRef,\n onDismiss,\n maxHeight: controlledMaxHeight,\n defaultSnap: getDefaultSnap = _defaultSnap,\n snapPoints: getSnapPoints = _snapPoints,\n blocking = true,\n scrollLocking = true,\n style,\n onSpringStart,\n onSpringCancel,\n onSpringEnd,\n reserveScrollBarGap = blocking,\n expandOnContentDrag = false,\n ...props\n },\n forwardRef\n) {\n // Before any animations can start we need to measure a few things, like the viewport and the dimensions of content, and header + footer if they exist\n // @TODO make ready its own state perhaps, before open or closed\n const { ready, registerReady } = useReady()\n\n // Controls the drag handler, used by spring operations that happen outside the render loop in React\n const canDragRef = useRef(false)\n\n // This way apps don't have to remember to wrap their callbacks in useCallback to avoid breaking the sheet\n const onSpringStartRef = useRef(onSpringStart)\n const onSpringCancelRef = useRef(onSpringCancel)\n const onSpringEndRef = useRef(onSpringEnd)\n useEffect(() => {\n onSpringStartRef.current = onSpringStart\n onSpringCancelRef.current = onSpringCancel\n onSpringEndRef.current = onSpringEnd\n }, [onSpringCancel, onSpringStart, onSpringEnd])\n\n // Behold, the engine of it all!\n const [spring, set] = useSpring()\n\n const containerRef = useRef<HTMLDivElement>(null)\n const scrollRef = useRef<HTMLDivElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n const headerRef = useRef<HTMLDivElement>(null)\n const footerRef = useRef<HTMLDivElement>(null)\n const overlayRef = useRef<HTMLDivElement | null>(null)\n\n // Keeps track of the current height, or the height transitioning to\n const heightRef = useRef(0)\n const resizeSourceRef = useRef<ResizeSource>()\n const preventScrollingRef = useRef(false)\n\n const prefersReducedMotion = useReducedMotion()\n\n // \"Plugins\" huhuhu\n const scrollLockRef = useScrollLock({\n targetRef: scrollRef,\n enabled: ready && scrollLocking,\n reserveScrollBarGap,\n })\n const ariaHiderRef = useAriaHider({\n targetRef: containerRef,\n enabled: ready && blocking,\n })\n const focusTrapRef = useFocusTrap({\n targetRef: containerRef,\n fallbackRef: overlayRef,\n initialFocusRef: initialFocusRef || undefined,\n enabled: ready && blocking && initialFocusRef !== false,\n })\n\n const { minSnap, maxSnap, maxHeight, findSnap } = useSnapPoints({\n contentRef,\n controlledMaxHeight,\n footerEnabled: !!footer,\n footerRef,\n getSnapPoints,\n headerEnabled: header !== false,\n headerRef,\n heightRef,\n lastSnapRef,\n ready,\n registerReady,\n resizeSourceRef,\n })\n\n // Setup refs that are used in cases where full control is needed over when a side effect is executed\n const maxHeightRef = useRef(maxHeight)\n const minSnapRef = useRef(minSnap)\n const maxSnapRef = useRef(maxSnap)\n const findSnapRef = useRef(findSnap)\n const defaultSnapRef = useRef(0)\n // Sync the refs with current state, giving the spring full control over when to respond to changes\n useLayoutEffect(() => {\n maxHeightRef.current = maxHeight\n maxSnapRef.current = maxSnap\n minSnapRef.current = minSnap\n findSnapRef.current = findSnap\n defaultSnapRef.current = findSnap(getDefaultSnap)\n }, [findSnap, getDefaultSnap, maxHeight, maxSnap, minSnap])\n\n // New utility for using events safely\n const asyncSet = useCallback<typeof set>(\n // @ts-expect-error\n ({ onRest, config: { velocity = 1, ...config } = {}, ...opts }) =>\n new Promise((resolve) =>\n set({\n ...opts,\n config: {\n velocity,\n ...config,\n // @see https://springs.pomb.us\n mass: 1,\n // \"stiffness\"\n tension,\n // \"damping\"\n friction: Math.max(\n friction,\n friction + (friction - friction * velocity)\n ),\n },\n onRest: (...args) => {\n resolve(...args)\n onRest?.(...args)\n },\n })\n ),\n [set]\n )\n const [current, send] = useMachine(overlayMachine, {\n devTools: debugging,\n actions: {\n onOpenCancel: useCallback(\n () => onSpringCancelRef.current?.({ type: 'OPEN' }),\n []\n ),\n onSnapCancel: useCallback(\n (context) =>\n onSpringCancelRef.current?.({\n type: 'SNAP',\n source: context.snapSource,\n }),\n []\n ),\n onCloseCancel: useCallback(\n () => onSpringCancelRef.current?.({ type: 'CLOSE' }),\n []\n ),\n onResizeCancel: useCallback(\n () =>\n onSpringCancelRef.current?.({\n type: 'RESIZE',\n source: resizeSourceRef.current,\n }),\n []\n ),\n onOpenEnd: useCallback(\n () => onSpringEndRef.current?.({ type: 'OPEN' }),\n []\n ),\n onSnapEnd: useCallback(\n (context, event) =>\n onSpringEndRef.current?.({\n type: 'SNAP',\n source: context.snapSource,\n }),\n []\n ),\n onResizeEnd: useCallback(\n () =>\n onSpringEndRef.current?.({\n type: 'RESIZE',\n source: resizeSourceRef.current,\n }),\n []\n ),\n },\n context: { initialState },\n services: {\n onSnapStart: useCallback(\n async (context, event) =>\n onSpringStartRef.current?.({\n type: 'SNAP',\n source: event.payload.source || 'custom',\n }),\n []\n ),\n onOpenStart: useCallback(\n async () => onSpringStartRef.current?.({ type: 'OPEN' }),\n []\n ),\n onCloseStart: useCallback(\n async () => onSpringStartRef.current?.({ type: 'CLOSE' }),\n []\n ),\n onResizeStart: useCallback(\n async () =>\n onSpringStartRef.current?.({\n type: 'RESIZE',\n source: resizeSourceRef.current,\n }),\n []\n ),\n onSnapEnd: useCallback(\n async (context, event) =>\n onSpringEndRef.current?.({\n type: 'SNAP',\n source: context.snapSource,\n }),\n []\n ),\n onOpenEnd: useCallback(\n async () => onSpringEndRef.current?.({ type: 'OPEN' }),\n []\n ),\n onCloseEnd: useCallback(\n async () => onSpringEndRef.current?.({ type: 'CLOSE' }),\n []\n ),\n onResizeEnd: useCallback(\n async () =>\n onSpringEndRef.current?.({\n type: 'RESIZE',\n source: resizeSourceRef.current,\n }),\n []\n ),\n renderVisuallyHidden: useCallback(\n async (context, event) => {\n await asyncSet({\n y: defaultSnapRef.current,\n ready: 0,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n // Using defaultSnapRef instead of minSnapRef to avoid animating `height` on open\n minSnap: defaultSnapRef.current,\n immediate: true,\n })\n },\n [asyncSet]\n ),\n activate: useCallback(\n async (context, event) => {\n canDragRef.current = true\n await Promise.all([\n scrollLockRef.current.activate(),\n focusTrapRef.current.activate(),\n ariaHiderRef.current.activate(),\n ])\n },\n [ariaHiderRef, focusTrapRef, scrollLockRef]\n ),\n deactivate: useCallback(async () => {\n scrollLockRef.current.deactivate()\n focusTrapRef.current.deactivate()\n ariaHiderRef.current.deactivate()\n canDragRef.current = false\n }, [ariaHiderRef, focusTrapRef, scrollLockRef]),\n openImmediately: useCallback(async () => {\n heightRef.current = defaultSnapRef.current\n await asyncSet({\n y: defaultSnapRef.current,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n // Using defaultSnapRef instead of minSnapRef to avoid animating `height` on open\n minSnap: defaultSnapRef.current,\n immediate: true,\n })\n }, [asyncSet]),\n openSmoothly: useCallback(async () => {\n await asyncSet({\n y: 0,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n // Using defaultSnapRef instead of minSnapRef to avoid animating `height` on open\n minSnap: defaultSnapRef.current,\n immediate: true,\n })\n\n heightRef.current = defaultSnapRef.current\n\n await asyncSet({\n y: defaultSnapRef.current,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n // Using defaultSnapRef instead of minSnapRef to avoid animating `height` on open\n minSnap: defaultSnapRef.current,\n immediate: prefersReducedMotion.current,\n })\n }, [asyncSet, prefersReducedMotion]),\n snapSmoothly: useCallback(\n async (context, event) => {\n const snap = findSnapRef.current(context.y)\n heightRef.current = snap\n lastSnapRef.current = snap\n await asyncSet({\n y: snap,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n minSnap: minSnapRef.current,\n immediate: prefersReducedMotion.current,\n config: { velocity: context.velocity },\n })\n },\n [asyncSet, lastSnapRef, prefersReducedMotion]\n ),\n resizeSmoothly: useCallback(async () => {\n const snap = findSnapRef.current(heightRef.current)\n heightRef.current = snap\n lastSnapRef.current = snap\n await asyncSet({\n y: snap,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n minSnap: minSnapRef.current,\n immediate:\n resizeSourceRef.current === 'element'\n ? prefersReducedMotion.current\n : true,\n })\n }, [asyncSet, lastSnapRef, prefersReducedMotion]),\n closeSmoothly: useCallback(\n async (context, event) => {\n // Avoid animating the height property on close and stay within FLIP bounds by upping the minSnap\n asyncSet({\n minSnap: heightRef.current,\n immediate: true,\n })\n\n heightRef.current = 0\n\n await asyncSet({\n y: 0,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n immediate: prefersReducedMotion.current,\n })\n\n await asyncSet({ ready: 0, immediate: true })\n },\n [asyncSet, prefersReducedMotion]\n ),\n },\n })\n\n useEffect(() => {\n if (!ready) return\n\n if (_open) {\n send('OPEN')\n } else {\n send('CLOSE')\n }\n }, [_open, send, ready])\n useLayoutEffect(() => {\n // Adjust the height whenever the snap points are changed due to resize events\n if (maxHeight || maxSnap || minSnap) {\n send('RESIZE')\n }\n }, [maxHeight, maxSnap, minSnap, send])\n useEffect(\n () => () => {\n // Ensure effects are cleaned up on unmount, in case they're not cleaned up otherwise\n scrollLockRef.current.deactivate()\n focusTrapRef.current.deactivate()\n ariaHiderRef.current.deactivate()\n },\n [ariaHiderRef, focusTrapRef, scrollLockRef]\n )\n\n useImperativeHandle(\n forwardRef,\n () => ({\n snapTo: (numberOrCallback, { velocity = 1, source = 'custom' } = {}) => {\n send('SNAP', {\n payload: {\n y: findSnapRef.current(numberOrCallback),\n velocity,\n source,\n },\n })\n },\n get height() {\n return heightRef.current\n },\n }),\n [send]\n )\n\n useEffect(() => {\n const elem = scrollRef.current\n\n const preventScrolling = e => {\n if (preventScrollingRef.current) {\n e.preventDefault()\n }\n }\n\n const preventSafariOverscroll = e => {\n if (elem.scrollTop < 0) {\n requestAnimationFrame(() => {\n elem.style.overflow = 'hidden'\n elem.scrollTop = 0\n elem.style.removeProperty('overflow')\n })\n e.preventDefault()\n }\n }\n\n if (expandOnContentDrag) {\n elem.addEventListener('scroll', preventScrolling)\n elem.addEventListener('touchmove', preventScrolling)\n elem.addEventListener('touchstart', preventSafariOverscroll)\n }\n return () => {\n elem.removeEventListener('scroll', preventScrolling)\n elem.removeEventListener('touchmove', preventScrolling)\n elem.removeEventListener('touchstart', preventSafariOverscroll)\n }\n }, [expandOnContentDrag, scrollRef])\n\n const handleDrag = ({\n args: [{ closeOnTap = false, isContentDragging = false } = {}] = [],\n cancel,\n direction: [, direction],\n down,\n first,\n last,\n memo = spring.y.getValue() as number,\n movement: [, _my],\n tap,\n velocity,\n }) => {\n const my = _my * -1\n\n // Cancel the drag operation if the canDrag state changed\n if (!canDragRef.current) {\n console.log('handleDrag cancelled dragging because canDragRef is false')\n cancel()\n return memo\n }\n\n if (onDismiss && closeOnTap && tap) {\n cancel()\n // Runs onDismiss in a timeout to avoid tap events on the backdrop from triggering click events on elements underneath\n setTimeout(() => onDismiss(), 0)\n return memo\n }\n\n // Filter out taps\n if (tap) {\n return memo\n }\n\n const rawY = memo + my\n const predictedDistance = my * velocity\n const predictedY = Math.max(\n minSnapRef.current,\n Math.min(maxSnapRef.current, rawY + predictedDistance * 2)\n )\n\n if (\n !down &&\n onDismiss &&\n direction > 0 &&\n rawY + predictedDistance < minSnapRef.current / 2\n ) {\n cancel()\n onDismiss()\n return memo\n }\n\n let newY = down\n ? // @TODO figure out a better way to deal with rubberband overshooting if min and max have the same value\n !onDismiss && minSnapRef.current === maxSnapRef.current\n ? rawY < minSnapRef.current\n ? rubberbandIfOutOfBounds(\n rawY,\n minSnapRef.current,\n maxSnapRef.current * 2,\n 0.55\n )\n : rubberbandIfOutOfBounds(\n rawY,\n minSnapRef.current / 2,\n maxSnapRef.current,\n 0.55\n )\n : rubberbandIfOutOfBounds(\n rawY,\n onDismiss ? 0 : minSnapRef.current,\n maxSnapRef.current,\n 0.55\n )\n : predictedY\n\n if (expandOnContentDrag && isContentDragging) {\n if (newY >= maxSnapRef.current) {\n newY = maxSnapRef.current\n }\n\n if (memo === maxSnapRef.current && scrollRef.current.scrollTop > 0) {\n newY = maxSnapRef.current\n }\n\n preventScrollingRef.current = newY < maxSnapRef.current;\n } else {\n preventScrollingRef.current = false\n }\n\n if (first) {\n send('DRAG')\n }\n\n if (last) {\n send('SNAP', {\n payload: {\n y: newY,\n velocity: velocity > 0.05 ? velocity : 1,\n source: 'dragging',\n },\n })\n\n return memo\n }\n\n // @TODO too many rerenders\n //send('DRAG', { y: newY, velocity })\n //*\n set({\n y: newY,\n ready: 1,\n maxHeight: maxHeightRef.current,\n maxSnap: maxSnapRef.current,\n minSnap: minSnapRef.current,\n immediate: true,\n config: { velocity },\n })\n // */\n\n return memo\n }\n\n const bind = useDrag(handleDrag, {\n filterTaps: true,\n })\n\n if (Number.isNaN(maxSnapRef.current)) {\n throw new TypeError('maxSnapRef is NaN!!')\n }\n if (Number.isNaN(minSnapRef.current)) {\n throw new TypeError('minSnapRef is NaN!!')\n }\n\n const interpolations = useSpringInterpolations({ spring })\n\n return (\n <animated.div\n {...props}\n data-rsbs-root\n data-rsbs-state={publicStates.find(current.matches)}\n data-rsbs-is-blocking={blocking}\n data-rsbs-is-dismissable={!!onDismiss}\n data-rsbs-has-header={!!header}\n data-rsbs-has-footer={!!footer}\n className={className}\n ref={containerRef}\n style={{\n // spread in the interpolations yeees\n ...interpolations,\n // but allow overriding them/disabling them\n ...style,\n // Not overridable as the \"focus lock with opacity 0\" trick rely on it\n // @TODO the line below only fails on TS <4\n // @ts-ignore\n opacity: spring.ready,\n }}\n >\n {sibling}\n {blocking && (\n <div\n // This component needs to be placed outside bottom-sheet, as bottom-sheet uses transform and thus creates a new context\n // that clips this element to the container, not allowing it to cover the full page.\n key=\"backdrop\"\n data-rsbs-backdrop\n {...bind({ closeOnTap: true })}\n />\n )}\n <div\n key=\"overlay\"\n aria-modal=\"true\"\n role=\"dialog\"\n data-rsbs-overlay\n tabIndex={-1}\n ref={overlayRef}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n // Always stop propagation, to avoid weirdness for bottom sheets inside other bottom sheets\n event.stopPropagation()\n if (onDismiss) onDismiss()\n }\n }}\n >\n {header !== false && (\n <div key=\"header\" data-rsbs-header ref={headerRef} {...bind()}>\n {header}\n </div>\n )}\n <div key=\"scroll\" data-rsbs-scroll ref={scrollRef} {...(expandOnContentDrag ? bind({ isContentDragging: true }) : {})}>\n <div data-rsbs-content ref={contentRef}>\n {children}\n </div>\n </div>\n {footer && (\n <div key=\"footer\" ref={footerRef} data-rsbs-footer {...bind()}>\n {footer}\n </div>\n )}\n </div>\n </animated.div>\n )\n})\n\n// Used for the data attribute, list over states available to CSS selectors\nconst publicStates = [\n 'closed',\n 'opening',\n 'open',\n 'closing',\n 'dragging',\n 'snapping',\n 'resizing',\n]\n\n// Default prop values that are callbacks, and it's nice to save some memory and reuse their instances since they're pure\nfunction _defaultSnap({ snapPoints, lastSnap }: defaultSnapProps) {\n return lastSnap ?? Math.min(...snapPoints)\n}\nfunction _snapPoints({ minHeight }: SnapPointProps) {\n return minHeight\n}\n","// Keeps track of wether everything is good to go or not, in the most efficient way possible\n\nimport { useCallback, useEffect, useState } from 'react'\n\nexport function useReady() {\n const [ready, setReady] = useState(false)\n const [readyMap, updateReadyMap] = useState<{ [key: string]: boolean }>({})\n\n const registerReady = useCallback((key: string) => {\n console.count(`registerReady:${key}`)\n // Register the check we're gonna wait for until it's ready\n updateReadyMap((ready) => ({ ...ready, [key]: false }))\n\n return () => {\n console.count(`setReady:${key}`)\n // Set it to ready\n updateReadyMap((ready) => ({ ...ready, [key]: true }))\n }\n }, [])\n\n useEffect(() => {\n const states = Object.values(readyMap)\n\n if (states.length === 0) {\n console.log('nope nothing registered yet')\n return\n }\n\n const isReady = states.every(Boolean)\n console.log('check if we are rready', readyMap, isReady)\n if (isReady) {\n console.warn('ready!')\n setReady(true)\n }\n }, [readyMap])\n\n return { ready, registerReady }\n}\n","import { useDebugValue, useEffect, useMemo, useRef } from 'react'\n\n// @TODO refactor to addEventListener\nexport function useReducedMotion() {\n const mql = useMemo(\n () =>\n typeof window !== 'undefined'\n ? window.matchMedia('(prefers-reduced-motion: reduce)')\n : null,\n []\n )\n const ref = useRef(mql?.matches)\n\n useDebugValue(ref.current ? 'reduce' : 'no-preference')\n\n useEffect(() => {\n const handler = (event) => {\n ref.current = event.matches\n }\n mql?.addListener(handler)\n\n return () => mql?.removeListener(handler)\n }, [mql])\n\n return ref\n}\n","import { useSpring as useReactSpring } from 'react-spring'\n\n// Behold, the engine of it all!\n// Put in this file befause it makes it easier to type and I'm lazy! :D\n\nexport function useSpring() {\n return useReactSpring(() => ({\n y: 0,\n ready: 0,\n maxHeight: 0,\n minSnap: 0,\n maxSnap: 0,\n }))\n}\n\nexport type Spring = ReturnType<typeof useSpring>[0]\nexport type SpringSet = ReturnType<typeof useSpring>[1]\n","import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'\nimport { useDebugValue, useEffect, useRef } from 'react'\n\n/**\n * Handle scroll locking to ensure a good dragging experience on Android and iOS.\n *\n * On iOS the following may happen if scroll isn't locked:\n * - When dragging the sheet the background gets dragged at the same time.\n * - When dragging the page scroll is also affected, causing the drag to feel buggy and \"slow\".\n *\n * On Android it causes the chrome toolbar to pop down as you drag down, and hide as you drag up.\n * When it's in between two toolbar states it causes the framerate to drop way below 60fps on\n * the bottom sheet drag interaction.\n */\nexport function useScrollLock({\n targetRef,\n enabled,\n reserveScrollBarGap,\n}: {\n targetRef: React.RefObject<Element>\n enabled: boolean\n reserveScrollBarGap: boolean\n}) {\n const ref = useRef<{ activate: () => void; deactivate: () => void }>({\n activate: () => {\n throw new TypeError('Tried to activate scroll lock too early')\n },\n deactivate: () => {},\n })\n\n useDebugValue(enabled ? 'Enabled' : 'Disabled')\n\n useEffect(() => {\n if (!enabled) {\n ref.current.deactivate()\n ref.current = { activate: () => {}, deactivate: () => {} }\n return\n }\n\n const target = targetRef.current\n let active = false\n\n ref.current = {\n activate: () => {\n if (active) return\n active = true\n disableBodyScroll(target, {\n allowTouchMove: (el) => el.closest('[data-body-scroll-lock-ignore]'),\n reserveScrollBarGap,\n })\n },\n deactivate: () => {\n if (!active) return\n active = false\n enableBodyScroll(target)\n },\n }\n }, [enabled, targetRef, reserveScrollBarGap])\n\n return ref\n}\n","import React, { useDebugValue, useEffect, useRef } from 'react'\n\n// Handle hiding and restoring aria-hidden attributes\nexport function useAriaHider({\n targetRef,\n enabled,\n}: {\n targetRef: React.RefObject<Element>\n enabled: boolean\n}) {\n const ref = useRef<{ activate: () => void; deactivate: () => void }>({\n activate: () => {\n throw new TypeError('Tried to activate aria hider too early')\n },\n deactivate: () => {},\n })\n\n useDebugValue(enabled ? 'Enabled' : 'Disabled')\n\n useEffect(() => {\n if (!enabled) {\n ref.current.deactivate()\n ref.current = { activate: () => {}, deactivate: () => {} }\n return\n }\n\n const target = targetRef.current\n let active = false\n let originalValues: (null | string)[] = []\n let rootNodes: Element[] = []\n\n ref.current = {\n activate: () => {\n if (active) return\n active = true\n\n const parentNode = target.parentNode\n\n document.querySelectorAll('body > *').forEach((node) => {\n if (node === parentNode) {\n return\n }\n let attr = node.getAttribute('aria-hidden')\n let alreadyHidden = attr !== null && attr !== 'false'\n if (alreadyHidden) {\n return\n }\n originalValues.push(attr)\n rootNodes.push(node)\n node.setAttribute('aria-hidden', 'true')\n })\n },\n deactivate: () => {\n if (!active) return\n active = false\n\n rootNodes.forEach((node, index) => {\n let originalValue = originalValues[index]\n if (originalValue === null) {\n node.removeAttribute('aria-hidden')\n } else {\n node.setAttribute('aria-hidden', originalValue)\n }\n })\n originalValues = []\n rootNodes = []\n },\n }\n }, [targetRef, enabled])\n\n return ref\n}\n","import { createFocusTrap } from 'focus-trap'\nimport { useDebugValue, useEffect, useRef } from 'react'\n\nexport function useFocusTrap({\n targetRef,\n fallbackRef,\n initialFocusRef,\n enabled,\n}: {\n targetRef: React.RefObject<HTMLElement>\n fallbackRef: React.RefObject<HTMLElement>\n initialFocusRef?: React.RefObject<HTMLElement>\n enabled: boolean\n}) {\n const ref = useRef<{ activate: () => void; deactivate: () => void }>({\n activate: () => {\n throw new TypeError('Tried to activate focus trap too early')\n },\n deactivate: () => {},\n })\n\n useDebugValue(enabled ? 'Enabled' : 'Disabled')\n\n useEffect(() => {\n if (!enabled) {\n ref.current.deactivate()\n ref.current = { activate: () => {}, deactivate: () => {} }\n return\n }\n\n const fallback = fallbackRef.current\n const trap = createFocusTrap(targetRef.current, {\n onActivate:\n process.env.NODE_ENV !== 'production'\n ? () => {\n console.log('focus activate')\n }\n : undefined,\n // If initialFocusRef is manually specified we don't want the first tabbable element to receive focus if initialFocusRef can't be found\n initialFocus: initialFocusRef\n ? () => initialFocusRef?.current || fallback\n : undefined,\n fallbackFocus: fallback,\n escapeDeactivates: false,\n clickOutsideDeactivates: false,\n })\n let active = false\n\n ref.current = {\n activate: async () => {\n if (active) return\n active = true\n\n await trap.activate()\n // it's difficult to know exactly when focus is udpated https://github.com/focus-trap/focus-trap/blob/036a72ec48b85414dda00ec0c40d631c8f0ae5ce/index.js#L369-L371\n // This timeout is attempting to compromise between a reasonable guess, as well as not delaying the open transition more than necessary\n await new Promise((resolve) => setTimeout(() => resolve(void 1), 0))\n },\n deactivate: () => {\n if (!active) return\n active = false\n\n trap.deactivate()\n },\n }\n }, [enabled, fallbackRef, initialFocusRef, targetRef])\n\n return ref\n}\n","import { interpolate } from 'react-spring'\nimport type { Spring } from './useSpring'\nimport { clamp } from '../utils'\n\n// It's a bit easier to ensure interpolations don't accidentally use the wrong variables by\n// putting them here, in their own closure with explicitly defined variables used\n\n// Note that the callbacks in the interpolation functions close over their scope every time react renders\n// so it's important that if anything can change outside of render that needs to be available\n// in the interpolation then a ref must be used\n\nexport function useSpringInterpolations({\n spring,\n}: {\n spring: Spring\n}): React.CSSProperties {\n // This effect is for removing rounded corners on phones when the sheet touches the top of the browser chrome\n // as it's really ugly with the gaps border radius creates. This ensures it looks sleek.\n // @TODO the ts-ignore comments are because the `extrapolate` param isn't in the TS defs for some reason\n const interpolateBorderRadius = interpolate(\n // @ts-expect-error\n [spring.y, spring.maxHeight],\n (y, maxHeight) => {\n return `${Math.round(clamp(maxHeight - y, 0, 16))}px`\n }\n )\n\n /*\n * Only animate the height when absolute necessary\n * @TODO currently it's only able to opt out of changing the height if there's just a single snapshot\n * but it should be possible to do it in other scenarios too, like on window resize,\n * or maybe even while dragging, but probably requires a more restrictive CSS.\n * As in now the sticky footer isn't overlapping the content, allowing `backdrop-filter: blur(8px)` effects.\n * A FLIP resize flow for content height would likely require the sticky elements to overlap the content area.\n * Could be done as a separat mode though, or a separate example CSS for max performance.\n */\n const interpolateHeight = interpolate(\n // @ts-ignore\n [spring.y, spring.minSnap, spring.maxSnap],\n (y, minSnap, maxSnap) => `${clamp(y, minSnap, maxSnap)}px`\n )\n\n const interpolateY = interpolate(\n // @ts-ignore\n [spring.y, spring.minSnap, spring.maxSnap],\n (y, minSnap, maxSnap) => {\n if (y < minSnap) {\n return `${minSnap - y}px`\n }\n if (y > maxSnap) {\n return `${maxSnap - y}px`\n }\n return '0px'\n }\n )\n\n const interpolateFiller = interpolate(\n // @ts-ignore\n [spring.y, spring.maxSnap],\n (y, maxSnap) => {\n if (y >= maxSnap) {\n return Math.ceil(y - maxSnap)\n }\n return 0\n }\n )\n\n const interpolateContentOpacity = interpolate(\n // @ts-ignore\n [spring.y, spring.minSnap],\n (y, minSnap) => {\n if (!minSnap) {\n return 0\n }\n const minX = Math.max(minSnap / 2 - 45, 0)\n const maxX = Math.min(minSnap / 2 + 45, minSnap)\n const minY = 0\n const maxY = 1\n\n const slope = (maxY - minY) / (maxX - minX)\n const res = (y - minX) * (slope + minY)\n return clamp(res, 0, 1)\n }\n )\n\n const interpolateBackdrop = interpolate(\n // @ts-ignore\n [spring.y, spring.minSnap],\n (y, minSnap) => (minSnap ? clamp(y / minSnap, 0, 1) : 0)\n )\n\n return {\n // Fancy content fade-in effect\n ['--rsbs-content-opacity' as any]: interpolateContentOpacity,\n // Fading in the backdrop\n ['--rsbs-backdrop-opacity' as any]: interpolateBackdrop,\n // Scaling the antigap in the bottom\n ['--rsbs-antigap-scale-y' as any]: interpolateFiller,\n // Shifts the position of the bottom sheet, used on open and close primarily as snap point changes usually only interpolate the height\n ['--rsbs-overlay-translate-y' as any]: interpolateY,\n // Remove rounded borders when full height, it looks much better this way\n ['--rsbs-overlay-rounded' as any]: interpolateBorderRadius,\n // Animates the height state, not the most performant way but it's the safest with regards to mobile browser and focus/scrolling that could happen while animating\n ['--rsbs-overlay-h' as any]: interpolateHeight,\n }\n}\n","/* eslint-disable react/jsx-pascal-case */\nimport Portal from '@reach/portal'\nimport React, { forwardRef, useRef, useState, useCallback } from 'react'\nimport { BottomSheet as _BottomSheet } from './BottomSheet'\nimport type { Props, RefHandles, SpringEvent } from './types'\nimport { useLayoutEffect } from './hooks'\n\nexport type {\n RefHandles as BottomSheetRef,\n Props as BottomSheetProps,\n} from './types'\n\n// Because SSR is annoying to deal with, and all the million complaints about window, navigator and dom elenents!\nexport const BottomSheet = forwardRef<RefHandles, Props>(function BottomSheet(\n { onSpringStart, onSpringEnd, skipInitialTransition, ...props },\n ref\n) {\n // Mounted state, helps SSR but also ensures you can't tab into the sheet while it's closed, or nav there in a screen reader\n const [mounted, setMounted] = useState(false)\n const timerRef = useRef<ReturnType<typeof requestAnimationFrame>>()\n // The last point that the user snapped to, useful for open/closed toggling and the user defined height is remembered\n const lastSnapRef = useRef(null)\n // @TODO refactor to an initialState: OPEN | CLOSED property as it's much easier to understand\n // And informs what we should animate from. If the sheet is mounted with open = true, then initialState = OPEN.\n // When initialState = CLOSED, then internal sheet must first render with open={false} before setting open={props.open}\n // It's only when initialState and props.open is mismatching that a intial transition should happen\n // If they match then transitions will only happen when a user interaction or resize event happen.\n const initialStateRef = useRef<'OPEN' | 'CLOSED'>(\n skipInitialTransition && props.open ? 'OPEN' : 'CLOSED'\n )\n\n // Using layout effect to support cases where the bottom sheet have to appear already open, no transition\n useLayoutEffect(() => {\n if (props.open) {\n cancelAnimationFrame(timerRef.current)\n setMounted(true)\n\n // Cleanup defaultOpen state on close\n return () => {\n initialStateRef.current = 'CLOSED'\n }\n }\n }, [props.open])\n\n const handleSpringStart = useCallback(\n async function handleSpringStart(event: SpringEvent) {\n // Forward the event\n await onSpringStart?.(event)\n\n if (event.type === 'OPEN') {\n // Ensures that when it's opening we abort any pending unmount action\n cancelAnimationFrame(timerRef.current)\n }\n },\n [onSpringStart]\n )\n\n const handleSpringEnd = useCallback(\n async function handleSpringEnd(event: SpringEvent) {\n // Forward the event\n await onSpringEnd?.(event)\n\n if (event.type === 'CLOSE') {\n // Unmount from the dom to avoid contents being tabbable or visible to screen readers while closed\n timerRef.current = requestAnimationFrame(() => setMounted(false))\n }\n },\n [onSpringEnd]\n )\n\n // This isn't just a performance optimization, it's also to avoid issues when running a non-browser env like SSR\n if (!mounted) {\n return null\n }\n\n return (\n <Portal data-rsbs-portal>\n <_BottomSheet\n {...props}\n lastSnapRef={lastSnapRef}\n ref={ref}\n initialState={initialStateRef.current}\n onSpringStart={handleSpringStart}\n onSpringEnd={handleSpringEnd}\n />\n </Portal>\n )\n})\n"],"names":["useLayoutEffect","window","useLayoutEffectSafely","useEffect","clamp","number","lower","upper","roundAndCheckForNaN","unrounded","rounded","Math","round","Number","isNaN","TypeError","observerOptions","box","useElementSizeObserver","ref","label","enabled","resizeSourceRef","useState","size","setSize","useDebugValue","handleResize","useCallback","entries","borderBoxSize","blockSize","current","resizeObserver","ResizeObserver","observe","disconnect","sleep","ms","Promise","resolve","setTimeout","openToDrag","DRAG","target","actions","openToResize","RESIZE","overlayMachine","Machine","id","initial","context","initialState","states","closed","on","OPEN","CLOSE","undefined","opening","start","invoke","src","onDone","transition","always","cond","immediately","open","activating","smoothly","visuallyHidden","end","done","type","SNAP","dragging","snapping","entry","assign","y","_","payload","velocity","snapSource","source","snappingSmoothly","resizing","resizingSmoothly","closing","deactivating","closingSmoothly","onOpenCancel","event","onSnapCancel","onResizeCancel","onCloseCancel","onOpenEnd","onSnapEnd","onRezizeEnd","services","onSnapStart","onOpenStart","onCloseStart","onResizeStart","onCloseEnd","onResizeEnd","renderVisuallyHidden","activate","deactivate","openSmoothly","openImmediately","snapSmoothly","resizeSmoothly","closeSmoothly","guards","initiallyClosed","initiallyOpen","config","default","tension","friction","BottomSheet","React","forwardRef","children","sibling","className","footer","header","_open","lastSnapRef","initialFocusRef","onDismiss","controlledMaxHeight","maxHeight","defaultSnap","getDefaultSnap","_defaultSnap","snapPoints","getSnapPoints","_snapPoints","blocking","scrollLocking","style","onSpringStart","onSpringCancel","onSpringEnd","reserveScrollBarGap","expandOnContentDrag","props","ready","setReady","readyMap","updateReadyMap","registerReady","key","Object","values","length","every","Boolean","useReady","canDragRef","useRef","onSpringStartRef","onSpringCancelRef","onSpringEndRef","mql","useReactSpring","minSnap","maxSnap","spring","set","containerRef","scrollRef","contentRef","headerRef","footerRef","overlayRef","heightRef","preventScrollingRef","prefersReducedMotion","useMemo","matchMedia","matches","handler","addListener","removeListener","scrollLockRef","targetRef","active","disableBodyScroll","allowTouchMove","el","closest","enableBodyScroll","useScrollLock","ariaHiderRef","originalValues","rootNodes","parentNode","document","querySelectorAll","forEach","node","attr","getAttribute","push","setAttribute","index","originalValue","removeAttribute","useAriaHider","focusTrapRef","fallbackRef","fallback","trap","createFocusTrap","onActivate","initialFocus","fallbackFocus","escapeDeactivates","clickOutsideDeactivates","useFocusTrap","footerEnabled","headerEnabled","innerHeight","setMaxHeight","raf","requestAnimationFrame","addEventListener","removeEventListener","cancelAnimationFrame","useMaxHeight","headerHeight","contentHeight","footerHeight","minHeight","min","useDimensions","unsafeSnaps","snapPointsDedupedSet","concat","map","reduce","acc","snapPoint","add","Set","Array","from","max","processSnapPoints","height","findSnap","numberOrCallback","querySnap","lastSnap","prev","curr","abs","useSnapPoints","maxHeightRef","minSnapRef","maxSnapRef","findSnapRef","defaultSnapRef","asyncSet","onRest","opts","mass","args","useMachine","devTools","immediate","all","snap","send","useImperativeHandle","snapTo","elem","preventScrolling","e","preventDefault","preventSafariOverscroll","scrollTop","overflow","removeProperty","bind","useDrag","closeOnTap","isContentDragging","cancel","direction","down","first","last","memo","getValue","tap","my","movement","rawY","predictedDistance","predictedY","newY","rubberbandIfOutOfBounds","filterTaps","interpolations","interpolateBorderRadius","interpolate","interpolateHeight","interpolateY","interpolateFiller","ceil","interpolateContentOpacity","minX","interpolateBackdrop","useSpringInterpolations","animated","div","publicStates","find","opacity","role","tabIndex","onKeyDown","stopPropagation","skipInitialTransition","mounted","setMounted","timerRef","initialStateRef","handleSpringStart","handleSpringEnd","Portal","_BottomSheet"],"mappings":"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"}
\No newline at end of file