UNPKG

nuqs

Version:

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

75 lines (71 loc) 2.41 kB
'use client'; import { patchHistory } from '../chunk-TCMXVJZC.js'; import { createAdapterProvider, renderQueryString } from '../chunk-5WWTJYGR.js'; import mitt from 'mitt'; import { createContext, useContext, useState, useEffect, useMemo, createElement } from 'react'; var emitter = mitt(); function generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates) { return function updateUrl(search, options) { const url = new URL(location.href); url.search = renderQueryString(search); if (fullPageNavigationOnShallowFalseUpdates && options.shallow === false) { const method = options.history === "push" ? location.assign : location.replace; method.call(location, url); } else { const method = options.history === "push" ? history.pushState : history.replaceState; method.call(history, history.state, "", url); } emitter.emit("update", search); if (options.scroll === true) { window.scrollTo({ top: 0 }); } }; } var NuqsReactAdapterContext = createContext({ fullPageNavigationOnShallowFalseUpdates: false }); function useNuqsReactAdapter() { const { fullPageNavigationOnShallowFalseUpdates } = useContext( NuqsReactAdapterContext ); const [searchParams, setSearchParams] = useState(() => { if (typeof location === "undefined") { return new URLSearchParams(); } return new URLSearchParams(location.search); }); useEffect(() => { const onPopState = () => { setSearchParams(new URLSearchParams(location.search)); }; emitter.on("update", setSearchParams); window.addEventListener("popstate", onPopState); return () => { emitter.off("update", setSearchParams); window.removeEventListener("popstate", onPopState); }; }, []); const updateUrl = useMemo( () => generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates), [fullPageNavigationOnShallowFalseUpdates] ); return { searchParams, updateUrl }; } var NuqsReactAdapter = createAdapterProvider(useNuqsReactAdapter); function NuqsAdapter({ children, fullPageNavigationOnShallowFalseUpdates = false }) { return createElement( NuqsReactAdapterContext.Provider, { value: { fullPageNavigationOnShallowFalseUpdates } }, createElement(NuqsReactAdapter, null, children) ); } function enableHistorySync() { patchHistory(emitter, "react"); } export { NuqsAdapter, enableHistorySync };