UNPKG

nuqs

Version:

Type-safe search params state manager for React - Like useState, but stored in the URL query string

73 lines (70 loc) 3.16 kB
'use client'; import { r as createEmitter } from "../debounce-CmIkjWrj.js"; import { t as debug } from "../debug-C9V5O52N.js"; import { n as createAdapterProvider, o as renderQueryString } from "../context-CayRnDCw.js"; import { n as filterSearchParams } from "../key-isolation-CU0Wv_ai.js"; import { r as patchHistory, t as historyUpdateMarker } from "../patch-history-C6w4_G-g.js"; import { createContext, createElement, useContext, useMemo, useRef, useSyncExternalStore } from "react"; //#region src/adapters/react.ts const emitter = createEmitter(); function generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates) { return function updateUrl(search, options) { const url = new URL(location.href); url.search = renderQueryString(search); debug(20, "react", url); if (fullPageNavigationOnShallowFalseUpdates && options.shallow === false) (options.history === "push" ? location.assign : location.replace).call(location, url); else (options.history === "push" ? history.pushState : history.replaceState).call(history, history.state, historyUpdateMarker, url); emitter.emit("update", search); if (options.scroll === true) window.scrollTo({ top: 0 }); }; } const NuqsReactAdapterContext = createContext({ fullPageNavigationOnShallowFalseUpdates: false }); const emptySearchParams = new URLSearchParams(); function getServerSnapshot() { return emptySearchParams; } function subscribe(onStoreChange) { emitter.on("update", onStoreChange); window.addEventListener("popstate", onStoreChange); return () => { emitter.off("update", onStoreChange); window.removeEventListener("popstate", onStoreChange); }; } function useNuqsReactAdapter(watchKeys) { const { fullPageNavigationOnShallowFalseUpdates } = useContext(NuqsReactAdapterContext); const cache = useRef(null); return { searchParams: useSyncExternalStore(subscribe, () => { const filteredSearch = filterSearchParams(new URLSearchParams(location.search), watchKeys, false); const key = filteredSearch.toString(); if (cache.current?.key === key) return cache.current.search; cache.current = { key, search: filteredSearch }; return filteredSearch; }, getServerSnapshot), updateUrl: useMemo(() => generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates), [fullPageNavigationOnShallowFalseUpdates]) }; } const NuqsReactAdapter = createAdapterProvider(useNuqsReactAdapter); function NuqsAdapter({ children, fullPageNavigationOnShallowFalseUpdates = false, ...adapterProps }) { return createElement(NuqsReactAdapterContext.Provider, { value: { fullPageNavigationOnShallowFalseUpdates } }, createElement(NuqsReactAdapter, { ...adapterProps, children })); } /** * Opt-in to syncing shallow updates of the URL with the useOptimisticSearchParams hook. * * By default, the useOptimisticSearchParams hook will only react to internal nuqs updates. * If third party code updates the History API directly, use this function to * enable useOptimisticSearchParams to react to those changes. */ function enableHistorySync() { patchHistory(emitter, "react"); } //#endregion export { NuqsAdapter, enableHistorySync }; //# sourceMappingURL=react.js.map