163 lines
5.9 KiB
JavaScript
163 lines
5.9 KiB
JavaScript
var __assign = (this && this.__assign) || function () {
|
|
__assign = Object.assign || function(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
/* eslint-disable no-restricted-syntax */
|
|
import { useEffect, useMemo, useState } from 'react';
|
|
/**
|
|
*
|
|
* @param {object} params
|
|
* @returns {URL}
|
|
*/
|
|
function setQueryToCurrentUrl(params) {
|
|
var _a;
|
|
var URL = (typeof window !== 'undefined' ? window : {}).URL;
|
|
var url = new URL((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.href);
|
|
Object.keys(params).forEach(function (key) {
|
|
var value = params[key];
|
|
if (value !== null && value !== undefined) {
|
|
if (Array.isArray(value)) {
|
|
url.searchParams.delete(key);
|
|
value.forEach(function (valueItem) {
|
|
url.searchParams.append(key, valueItem);
|
|
});
|
|
}
|
|
else if (value instanceof Date) {
|
|
if (!Number.isNaN(value.getTime())) {
|
|
url.searchParams.set(key, value.toISOString());
|
|
}
|
|
}
|
|
else if (typeof value === 'object') {
|
|
url.searchParams.set(key, JSON.stringify(value));
|
|
}
|
|
else {
|
|
url.searchParams.set(key, value);
|
|
}
|
|
}
|
|
else {
|
|
url.searchParams.delete(key);
|
|
}
|
|
});
|
|
return url;
|
|
}
|
|
export function useUrlSearchParams(initial, config) {
|
|
var _a;
|
|
if (initial === void 0) { initial = {}; }
|
|
if (config === void 0) { config = { disabled: false }; }
|
|
/**
|
|
* The main idea of this hook is to make things response to change of `window.location.search`,
|
|
* so no need for introducing new state (in the mean time).
|
|
* Whenever `window.location.search` is changed but not cause re-render, call `forceUpdate()`.
|
|
* Whenever the component - user of this hook - re-render, this hook should return
|
|
* the query object that corresponse to the current `window.location.search`
|
|
*/
|
|
var _b = useState(), forceUpdate = _b[1];
|
|
var locationSearch = typeof window !== 'undefined' && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.search);
|
|
/**
|
|
* @type {URLSearchParams}
|
|
*/
|
|
var urlSearchParams = useMemo(function () {
|
|
if (config.disabled)
|
|
return {};
|
|
return new URLSearchParams(locationSearch || {});
|
|
}, [config.disabled, locationSearch]);
|
|
var params = useMemo(function () {
|
|
if (config.disabled)
|
|
return {};
|
|
if (typeof window === 'undefined' || !window.URL)
|
|
return {};
|
|
var result = [];
|
|
// @ts-ignore
|
|
urlSearchParams.forEach(function (value, key) {
|
|
result.push({
|
|
key: key,
|
|
value: value,
|
|
});
|
|
});
|
|
// group by key
|
|
result = result.reduce(function (acc, val) {
|
|
(acc[val.key] = acc[val.key] || []).push(val);
|
|
return acc;
|
|
}, {});
|
|
result = Object.keys(result).map(function (key) {
|
|
var valueGroup = result[key];
|
|
if (valueGroup.length === 1) {
|
|
return [key, valueGroup[0].value];
|
|
}
|
|
return [key, valueGroup.map(function (_a) {
|
|
var value = _a.value;
|
|
return value;
|
|
})];
|
|
});
|
|
var newParams = __assign({}, initial);
|
|
result.forEach(function (_a) {
|
|
var key = _a[0], value = _a[1];
|
|
newParams[key] = parseValue(key, value, {}, initial);
|
|
});
|
|
return newParams;
|
|
}, [config.disabled, initial, urlSearchParams]);
|
|
function redirectToNewSearchParams(newParams) {
|
|
if (typeof window === 'undefined' || !window.URL)
|
|
return;
|
|
var url = setQueryToCurrentUrl(newParams);
|
|
if (window.location.search !== url.search) {
|
|
window.history.replaceState({}, '', url.toString());
|
|
}
|
|
if (urlSearchParams.toString() !== url.searchParams.toString()) {
|
|
forceUpdate({});
|
|
}
|
|
}
|
|
useEffect(function () {
|
|
if (config.disabled)
|
|
return;
|
|
if (typeof window === 'undefined' || !window.URL)
|
|
return;
|
|
redirectToNewSearchParams(__assign(__assign({}, initial), params));
|
|
}, [config.disabled, params]);
|
|
var setParams = function (newParams) {
|
|
redirectToNewSearchParams(newParams);
|
|
};
|
|
useEffect(function () {
|
|
if (config.disabled)
|
|
return function () { };
|
|
if (typeof window === 'undefined' || !window.URL)
|
|
return function () { };
|
|
var onPopState = function () {
|
|
forceUpdate({});
|
|
};
|
|
window.addEventListener('popstate', onPopState);
|
|
return function () {
|
|
window.removeEventListener('popstate', onPopState);
|
|
};
|
|
}, [config.disabled]);
|
|
return [params, setParams];
|
|
}
|
|
var booleanValues = {
|
|
true: true,
|
|
false: false,
|
|
};
|
|
function parseValue(key, _value, types, defaultParams) {
|
|
if (!types)
|
|
return _value;
|
|
var type = types[key];
|
|
var value = _value === undefined ? defaultParams[key] : _value;
|
|
if (type === Number) {
|
|
return Number(value);
|
|
}
|
|
if (type === Boolean || _value === 'true' || _value === 'false') {
|
|
return booleanValues[value];
|
|
}
|
|
if (Array.isArray(type)) {
|
|
// eslint-disable-next-line eqeqeq
|
|
return type.find(function (item) { return item == value; }) || defaultParams[key];
|
|
}
|
|
return value;
|
|
}
|