CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
use-hash-location.js60 linesDownload Raw Back to src
1import { useSyncExternalStore } from "./react-deps.js";2 3// array of callback subscribed to hash updates4const listeners = {5  v: [],6};7 8const onHashChange = () => listeners.v.forEach((cb) => cb());9 10// we subscribe to `hashchange` only once when needed to guarantee that11// all listeners are called synchronously12const subscribeToHashUpdates = (callback) => {13  if (listeners.v.push(callback) === 1)14    addEventListener("hashchange", onHashChange);15 16  return () => {17    listeners.v = listeners.v.filter((i) => i !== callback);18    if (!listeners.v.length) removeEventListener("hashchange", onHashChange);19  };20};21 22// leading '#' is ignored, leading '/' is optional23const currentHashLocation = () => "/" + location.hash.replace(/^#?\/?/, "");24 25export const navigate = (to, { state = null, replace = false } = {}) => {26  const oldURL = location.href;27 28  const [hash, search] = to.replace(/^#?\/?/, "").split("?");29 30  // Works for ALL protocols including data:31  const url = new URL(location.href);32  url.hash = `/${hash}`;33  if (search) url.search = search;34  const newURL = url.href;35 36  if (replace) {37    history.replaceState(state, "", newURL);38  } else {39    history.pushState(state, "", newURL);40  }41 42  const event =43    typeof HashChangeEvent !== "undefined"44      ? new HashChangeEvent("hashchange", { oldURL, newURL })45      : new Event("hashchange", { detail: { oldURL, newURL } });46 47  dispatchEvent(event);48};49 50export const useHashLocation = ({ ssrPath = "/" } = {}) => [51  useSyncExternalStore(52    subscribeToHashUpdates,53    currentHashLocation,54    () => ssrPath55  ),56  navigate,57];58 59useHashLocation.hrefs = (href) => "#" + href;60