@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
135 lines (134 loc) • 4.54 kB
JavaScript
"use strict";
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useFilter = useFilter;
exports.useFilterAsync = useFilterAsync;
exports.useFilterContext = useFilterContext;
var _parse = _interopRequireDefault(require("core-js-pure/stable/json/parse.js"));
var _react = require("react");
var _useSharedState = require("../../../shared/helpers/useSharedState.js");
var _debounce = require("../../../shared/helpers/debounce.js");
var _FilterContext = require("../FilterContext.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const emptyState = {
search: '',
filters: {}
};
function useFilter(id) {
const {
data,
get,
extend
} = (0, _useSharedState.useSharedState)(id, emptyState);
const state = data !== null && data !== void 0 ? data : emptyState;
const resetFilters = (0, _react.useCallback)(() => {
extend({
search: '',
filters: {}
});
}, [extend]);
const removeFilter = (0, _react.useCallback)(filterKey => {
var _get;
const latest = (_get = get()) !== null && _get !== void 0 ? _get : emptyState;
const next = {
...latest.filters
};
delete next[filterKey];
extend({
filters: next
});
}, [extend, get]);
return {
filters: state.filters,
search: state.search,
hasActiveFilters: state.search.length > 0 || Object.keys(state.filters).length > 0,
resetFilters,
removeFilter
};
}
function useFilterContext() {
const context = (0, _react.useContext)(_FilterContext.FilterContext);
if (!context) {
throw new Error('Filter.useFilterContext() must be used inside a Filter.Root.');
}
return {
setFilter: context.setFilter,
getFilter: context.getFilter,
removeFilter: context.removeFilter,
resetFilters: context.resetFilters,
commitFilters: context.commitFilters,
revertFilters: context.revertFilters,
filters: context.state.filters,
search: context.state.search,
hasActiveFilters: context.hasActiveFilters
};
}
function useFilterAsync(id, fetcher, options) {
var _options$debounce, _state$resultLoading;
const {
data: filterData,
extend
} = (0, _useSharedState.useSharedState)(id, emptyState);
const state = filterData !== null && filterData !== void 0 ? filterData : emptyState;
const [result, setResult] = (0, _react.useState)(options?.initialData);
const [error, setError] = (0, _react.useState)(undefined);
const requestRef = (0, _react.useRef)(0);
const fetcherRef = (0, _react.useRef)(fetcher);
fetcherRef.current = fetcher;
const initialDataRef = (0, _react.useRef)(options?.initialData);
initialDataRef.current = options?.initialData;
const debounceMs = (_options$debounce = options?.debounce) !== null && _options$debounce !== void 0 ? _options$debounce : 0;
const debouncedFetcherRef = (0, _react.useRef)(undefined);
if (debounceMs > 0 && !debouncedFetcherRef.current) {
debouncedFetcherRef.current = (0, _debounce.debounceAsync)(params => fetcherRef.current(params), debounceMs);
}
const filtersKey = JSON.stringify(state.filters);
const search = state.search;
(0, _react.useEffect)(() => {
const filters = (0, _parse.default)(filtersKey);
const requestId = ++requestRef.current;
const isFirstRun = requestId === 1;
let cancelled = false;
if (!isFirstRun || !initialDataRef.current) {
extend({
resultLoading: true
});
}
setError(undefined);
const shouldDebounce = debounceMs > 0 && !isFirstRun;
const fetchFn = shouldDebounce ? debouncedFetcherRef.current : fetcherRef.current;
fetchFn({
filters,
search
}).then(data => {
if (!cancelled && requestId === requestRef.current) {
setResult(data);
extend({
resultLoading: false,
resultCount: Array.isArray(data) ? data.length : undefined
});
}
}).catch(err => {
if (!cancelled && requestId === requestRef.current) {
setError(err instanceof Error ? err : new Error(String(err)));
extend({
resultLoading: false
});
}
});
return () => {
cancelled = true;
if (shouldDebounce) {
debouncedFetcherRef.current?.cancel();
}
};
}, [filtersKey, search, extend, debounceMs]);
return {
data: result,
loading: (_state$resultLoading = state.resultLoading) !== null && _state$resultLoading !== void 0 ? _state$resultLoading : false,
error
};
}
//# sourceMappingURL=useFilter.js.map