UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

113 lines (104 loc) 4.12 kB
'use client'; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import * as React from 'react'; var defaultParseHash = function defaultParseHash(hash) { return hash.slice(1); }; // Remove the '#' var defaultFormatHash = function defaultFormatHash(value) { return value; }; /** * Hook for managing URL hash state with SSR support */ export function useUrlHashState() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _options$readOnMount = options.readOnMount, readOnMount = _options$readOnMount === void 0 ? true : _options$readOnMount, _options$watchChanges = options.watchChanges, watchChanges = _options$watchChanges === void 0 ? true : _options$watchChanges, _options$parseHash = options.parseHash, parseHash = _options$parseHash === void 0 ? defaultParseHash : _options$parseHash, _options$formatHash = options.formatHash, formatHash = _options$formatHash === void 0 ? defaultFormatHash : _options$formatHash; var _React$useState = React.useState(null), _React$useState2 = _slicedToArray(_React$useState, 2), hash = _React$useState2[0], setHashState = _React$useState2[1]; var _React$useState3 = React.useState(false), _React$useState4 = _slicedToArray(_React$useState3, 2), hasProcessedInitialHash = _React$useState4[0], setHasProcessedInitialHash = _React$useState4[1]; var _React$useState5 = React.useState(false), _React$useState6 = _slicedToArray(_React$useState5, 2), hasUserInteraction = _React$useState6[0], setHasUserInteraction = _React$useState6[1]; // Read hash from URL var readHash = React.useCallback(function () { if (typeof window === 'undefined') { return null; } var currentHash = window.location.hash; if (!currentHash) { return null; } return parseHash(currentHash); }, [parseHash]); // Set hash in URL and state var setHash = React.useCallback(function (value) { var replace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (typeof window === 'undefined') { return; } var formattedValue = value ? formatHash(value) : ''; var newUrl = formattedValue ? "".concat(window.location.pathname).concat(window.location.search, "#").concat(formattedValue) : "".concat(window.location.pathname).concat(window.location.search); // Special case: if value is an empty string (not null), include the hash if (value === '') { var newUrlWithEmptyHash = "".concat(window.location.pathname).concat(window.location.search, "#"); if (replace) { window.history.replaceState(null, '', newUrlWithEmptyHash); } else { window.history.pushState(null, '', newUrlWithEmptyHash); } } else if (replace) { window.history.replaceState(null, '', newUrl); } else { window.history.pushState(null, '', newUrl); } setHashState(value); }, [formatHash]); // Mark user interaction var markUserInteraction = React.useCallback(function () { setHasUserInteraction(true); }, []); // Handle hash changes from browser navigation var handleHashChange = React.useCallback(function () { var newHash = readHash(); setHashState(newHash); }, [readHash]); // Read initial hash on mount React.useEffect(function () { if (!readOnMount || hasProcessedInitialHash) { return; } var initialHash = readHash(); setHashState(initialHash); setHasProcessedInitialHash(true); }, [readOnMount, readHash, hasProcessedInitialHash]); // Watch for hash changes React.useEffect(function () { if (!watchChanges || typeof window === 'undefined') { return undefined; } window.addEventListener('hashchange', handleHashChange); return function () { window.removeEventListener('hashchange', handleHashChange); }; }, [watchChanges, handleHashChange]); return { hash: hash, setHash: setHash, hasProcessedInitialHash: hasProcessedInitialHash, hasUserInteraction: hasUserInteraction, markUserInteraction: markUserInteraction }; }