UNPKG

@bottom-sheet/react-hooks

Version:

The hooks that power `@bottom-sheet/react-spring`

1 lines 5.32 kB
{"mappings":";;AAeA;IACE,aAAa,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAA;IACzC,UAAU,CAAC,EAAE,aAAa,CAAA;IAC1B,+BAA+B,CAAC,EAAE,OAAO,CAAA;CAC1C;AAuED,OAAO,MAAM,gCACJ,uBAAuB;;;;;;;;;sBAPZ,gBAAgB;;;;CA6DnC,CAAA;AAED,qCAAqC,UAAU,CAAC,4BAA4B,CAAC,CAAA","sources":["src/src/index.ts","src/index.ts"],"sourcesContent":[null,"import {\n type BottomSheetEvent,\n BottomSheetMachine,\n} from '@bottom-sheet/state-machine'\nimport {\n assignInitialHeight,\n assignSnapPoints,\n defaultInitialHeight,\n defaultSnapPoints,\n} from '@bottom-sheet/state-machine'\nimport type { GetInitialHeight, GetSnapPoints } from '@bottom-sheet/types'\nimport { useMemo, useState } from 'react'\nimport { useSyncExternalStore } from 'use-sync-external-store/shim'\nimport { interpret } from 'xstate'\n\nexport interface BottomSheetMachineProps {\n initialHeight?: number | GetInitialHeight\n snapPoints?: GetSnapPoints\n unstable__requestAnimationFrame?: boolean\n}\n\nfunction createStore({\n initialHeight = defaultInitialHeight,\n snapPoints = defaultSnapPoints,\n unstable__requestAnimationFrame = false,\n}: BottomSheetMachineProps = {}) {\n console.debug('createStore')\n const service = interpret(\n BottomSheetMachine.withConfig({\n actions: {\n setInitialHeight: assignInitialHeight(\n typeof initialHeight === 'function'\n ? initialHeight\n : () => initialHeight\n ),\n setSnapPoints: assignSnapPoints(snapPoints),\n },\n })\n )\n let snapshot = service.initialState\n // transient is updated more frequently than the snapshot, outside of react render cycles\n let transient = snapshot\n let rAF = 0\n\n return {\n subscribe: (onStoreChange: () => void) => {\n console.debug('store.subscribe')\n service.onTransition((state) => {\n // @TODO: flesh out the logic for when to notify react of state changes or not (as state updates can be expensive and we should be transient when possible)\n // @TODO: put updateSnapshot actions in the state machine as declared events\n // for now just re-render on every change and map out events in userland before abstracting them to the state machine\n console.groupCollapsed('service.onTransition')\n transient = state\n console.log(state.value, state.context)\n if (state.changed) {\n if (unstable__requestAnimationFrame) {\n cancelAnimationFrame(rAF)\n rAF = requestAnimationFrame(() => {\n console.group('onStoreChange')\n console.log(state.value, state.context)\n transient = snapshot = state\n onStoreChange()\n console.groupEnd()\n })\n } else {\n console.group('onStoreChange')\n console.log(state.value, state.context)\n transient = snapshot = state\n onStoreChange()\n console.groupEnd()\n }\n }\n console.groupEnd()\n })\n console.debug('service.start')\n service.start()\n // return () => void service.stop()\n return () => {\n console.debug('service.stop')\n service.stop()\n }\n },\n getSnapshot: () => snapshot,\n getTransientSnapshot: () => transient,\n dispatch(event: BottomSheetEvent) {\n return service.send(event)\n },\n }\n}\n\nexport const useBottomSheetMachine = function useBottomSheetMachine(\n props: BottomSheetMachineProps = {}\n) {\n const [store] = useState(() => createStore(props))\n /*\n // useState lets us create the store exactly once, which is a guarantee that useMemo doesn't provide\n const [store] = useState(() => {\n const service = interpret(BottomSheetMachine)\n const matches: typeof service.state.matches = (parentStateValue) =>\n service.initialized\n ? service.state.matches(parentStateValue)\n : service.initialState.matches(parentStateValue)\n\n return {\n subscribe: (onStoreChange: () => void) => {\n console.log('subscribe called!')\n service.onTransition((state) => {\n // @TODO: flesh out the logic for when to notify react of state changes or not (as state updates can be expensive and we should be transient when possible)\n if (state.changed) {\n onStoreChange()\n }\n })\n service.start()\n return () => void service.stop()\n },\n getInitialized() {\n return service.initialized\n },\n getSnapshot: () =>\n service.initialized ? service.state : service.initialState,\n matches,\n dispatch(event: BottomSheetEvent) {\n return service.send(event)\n },\n }\n })\n // */\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot)\n\n /*\n const [inc, tick] = useState(0)\n useEffect(() => {\n const unsubscribe = store.subscribe(() => tick((inc) => ++inc))\n return () => unsubscribe()\n }, [])\n // */\n\n return useMemo(\n () => ({\n state,\n getTransientSnapshot: store.getTransientSnapshot,\n dispatch: store.dispatch,\n }),\n [state, store.dispatch, store.getTransientSnapshot]\n )\n}\n\nexport type BottomSheetMachineHook = ReturnType<typeof useBottomSheetMachine>\n"],"names":[],"version":3,"file":"index.d.ts.map"}