@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
113 lines (104 loc) • 4.12 kB
JavaScript
'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
};
}