UNPKG

82.2 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.modern.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/useSpring.tsx","../src/hooks/useReducedMotion.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 { 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 { 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 { 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","size","setSize","useState","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","async","onOpenStart","onCloseStart","onResizeStart","onCloseEnd","onResizeEnd","renderVisuallyHidden","activate","deactivate","openSmoothly","openImmediately","snapSmoothly","resizeSmoothly","closeSmoothly","guards","initiallyClosed","initiallyOpen","tension","friction","config","default","BottomSheet","React","forwardRef","children","sibling","className","footer","header","_open","lastSnapRef","initialFocusRef","onDismiss","maxHeight","controlledMaxHeight","defaultSnap","getDefaultSnap","_defaultSnap","snapPoints","getSnapPoints","_snapPoints","blocking","scrollLocking","style","onSpringStart","onSpringCancel","onSpringEnd","reserveScrollBarGap","expandOnContentDrag","props","ready","registerReady","setReady","readyMap","updateReadyMap","key","Object","values","length","every","Boolean","useReady","canDragRef","useRef","onSpringStartRef","onSpringCancelRef","onSpringEndRef","spring","set","useReactSpring","minSnap","maxSnap","containerRef","scrollRef","contentRef","headerRef","footerRef","overlayRef","heightRef","preventScrollingRef","prefersReducedMotion","mql","useMemo","matchMedia","matches","handler","addListener","removeListener","useReducedMotion","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","findSnap","footerEnabled","headerEnabled","minHeight","headerHeight","footerHeight","setMaxHeight","innerHeight","raf","requestAnimationFrame","addEventListener","removeEventListener","cancelAnimationFrame","useMaxHeight","contentHeight","min","useDimensions","unsafeSnaps","snapPointsDedupedSet","concat","map","reduce","acc","snapPoint","add","Set","Array","from","max","processSnapPoints","height","numberOrCallback","unsafeSearch","lastSnap","querySnap","prev","curr","abs","useSnapPoints","maxHeightRef","minSnapRef","maxSnapRef","findSnapRef","defaultSnapRef","asyncSet","_ref2","onRest","opts","mass","args","send","useMachine","devTools","immediate","all","snap","useImperativeHandle","snapTo","elem","preventScrolling","e","preventDefault","preventSafariOverscroll","scrollTop","overflow","removeProperty","bind","useDrag","closeOnTap","isContentDragging","cancel","direction","down","first","last","memo","getValue","movement","_my","tap","my","rawY","predictedDistance","predictedY","newY","rubberbandIfOutOfBounds","filterTaps","interpolations","interpolateBorderRadius","interpolate","interpolateHeight","interpolateY","interpolateFiller","ceil","minX","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