@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
108 lines (107 loc) • 3.5 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useFilterNextRouter;
var _parse = _interopRequireDefault(require("core-js-pure/stable/json/parse.js"));
var _react = require("react");
var _useFilter = require("./useFilter.js");
var _useSharedState = require("../../../shared/helpers/useSharedState.js");
var _useIsomorphicLayoutEffect = require("../../../shared/helpers/useIsomorphicLayoutEffect.js");
var _sanitizeUrlFilters = require("../utils/sanitizeUrlFilters.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const emptyState = {
search: '',
filters: {}
};
function useFilterNextRouter(id, {
useRouter,
usePathname,
useSearchParams,
excludeSearch = false
}) {
const searchParam = `${id}-search`;
const filtersParam = `${id}-filters`;
const {
extend
} = (0, _useSharedState.useSharedState)(id, emptyState);
const {
filters,
search
} = (0, _useFilter.useFilter)(id);
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const isRestoringRef = (0, _react.useRef)(false);
const writeToUrl = (0, _react.useCallback)((currentSearch, currentFilters) => {
if (isRestoringRef.current) {
return;
}
const params = new URLSearchParams(searchParams.toString());
if (!excludeSearch) {
if (currentSearch) {
params.set(searchParam, currentSearch);
} else {
params.delete(searchParam);
}
}
const filterKeys = Object.keys(currentFilters);
if (filterKeys.length > 0) {
params.set(filtersParam, JSON.stringify(currentFilters));
} else {
params.delete(filtersParam);
}
router.replace(`${pathname}?${params.toString()}`);
}, [searchParam, filtersParam, searchParams, pathname, router, excludeSearch]);
const readFromUrl = (0, _react.useCallback)(() => {
var _searchParams$get;
const urlSearch = excludeSearch ? '' : (_searchParams$get = searchParams.get(searchParam)) !== null && _searchParams$get !== void 0 ? _searchParams$get : '';
let urlFilters = {};
const filtersRaw = searchParams.get(filtersParam);
if (filtersRaw) {
try {
urlFilters = (0, _sanitizeUrlFilters.sanitizeUrlFilters)((0, _parse.default)(filtersRaw));
} catch {}
}
return {
search: urlSearch,
filters: urlFilters
};
}, [searchParams, searchParam, filtersParam, excludeSearch]);
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => {
const {
search: urlSearch,
filters: urlFilters
} = readFromUrl();
const hasState = urlSearch || Object.keys(urlFilters).length > 0;
if (hasState) {
isRestoringRef.current = true;
extend({
search: urlSearch,
filters: urlFilters
});
isRestoringRef.current = false;
}
}, [readFromUrl, extend]);
const prevRef = (0, _react.useRef)({
search: '',
filters: {}
});
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => {
const prev = prevRef.current;
const filtersChanged = JSON.stringify(prev.filters) !== JSON.stringify(filters);
const searchChanged = prev.search !== search;
if (filtersChanged || searchChanged) {
prevRef.current = {
search,
filters
};
writeToUrl(search, filters);
}
}, [search, filters, writeToUrl]);
return {
readFromUrl
};
}
//# sourceMappingURL=useNextRouter.js.map