@snack-uikit/utils 3.7.1-preview-d479ae3f.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +1 -6
- package/dist/cjs/hooks/index.d.ts +1 -2
- package/dist/cjs/hooks/index.js +1 -2
- package/dist/cjs/hooks/useDataPersist/index.d.ts +2 -0
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/index.js +1 -1
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/baseSource.d.ts +1 -1
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/baseSource.js +8 -4
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/localStorageSource.d.ts +1 -1
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/localStorageSource.js +1 -1
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/queryParamSource.d.ts +1 -1
- package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/queryParamSource.js +1 -1
- package/dist/cjs/hooks/{useSaveFilterState.d.ts → useDataPersist/useDataPersist.d.ts} +2 -2
- package/dist/cjs/hooks/{useSaveFilterState.js → useDataPersist/useDataPersist.js} +9 -8
- package/dist/cjs/hooks/{useSaveState/useSaveState.d.ts → useDataPersist/useSource.d.ts} +1 -1
- package/dist/cjs/hooks/{useSaveState/useSaveState.js → useDataPersist/useSource.js} +3 -3
- package/dist/cjs/hooks/useDebounce.js +3 -3
- package/dist/esm/hooks/index.d.ts +1 -2
- package/dist/esm/hooks/index.js +1 -2
- package/dist/esm/hooks/useDataPersist/index.d.ts +2 -0
- package/dist/esm/hooks/useDataPersist/index.js +2 -0
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/baseSource.d.ts +1 -1
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/baseSource.js +9 -4
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/localStorageSource.d.ts +1 -1
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/localStorageSource.js +1 -1
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/queryParamSource.d.ts +1 -1
- package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/queryParamSource.js +1 -1
- package/dist/esm/hooks/{useSaveFilterState.d.ts → useDataPersist/useDataPersist.d.ts} +2 -2
- package/dist/esm/hooks/{useSaveFilterState.js → useDataPersist/useDataPersist.js} +6 -7
- package/dist/esm/hooks/{useSaveState/useSaveState.d.ts → useDataPersist/useSource.d.ts} +1 -1
- package/dist/esm/hooks/{useSaveState/useSaveState.js → useDataPersist/useSource.js} +1 -1
- package/dist/esm/hooks/useDebounce.js +3 -3
- package/package.json +2 -2
- package/src/hooks/index.ts +1 -2
- package/src/hooks/useDataPersist/index.ts +2 -0
- package/src/hooks/{useSaveState → useDataPersist}/sources/baseSource.ts +9 -5
- package/src/hooks/{useSaveState → useDataPersist}/sources/localStorageSource.ts +1 -1
- package/src/hooks/{useSaveState → useDataPersist}/sources/queryParamSource.ts +1 -1
- package/src/hooks/{useSaveFilterState.ts → useDataPersist/useDataPersist.ts} +7 -9
- package/src/hooks/{useSaveState/useSaveState.ts → useDataPersist/useSource.ts} +1 -1
- package/src/hooks/useDebounce.ts +3 -3
- package/dist/cjs/hooks/useSaveState/index.d.ts +0 -2
- package/dist/esm/hooks/useSaveState/index.d.ts +0 -2
- package/dist/esm/hooks/useSaveState/index.js +0 -2
- package/src/hooks/useSaveState/index.ts +0 -2
- /package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/index.d.ts +0 -0
- /package/dist/cjs/hooks/{useSaveState → useDataPersist}/sources/index.js +0 -0
- /package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/index.d.ts +0 -0
- /package/dist/esm/hooks/{useSaveState → useDataPersist}/sources/index.js +0 -0
- /package/src/hooks/{useSaveState → useDataPersist}/sources/index.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 3.8.1 (2025-03-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **VMWDEV-2271:** fix timerId ([14fa135](https://github.com/cloud-ru-tech/snack-uikit/commit/14fa1351d12b76912b696aeaa6fcc7ce8d62d1b1))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# 3.8.0 (2025-03-04)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **PDS-681:** add save filter ([1406c6c](https://github.com/cloud-ru-tech/snack-uikit/commit/1406c6c447f337b5140135f8741b52ed1a0dfbf0))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# 3.7.0 (2025-01-23)
|
|
7
29
|
|
|
8
30
|
|
package/README.md
CHANGED
|
@@ -71,12 +71,7 @@
|
|
|
71
71
|
| value | `TValue` | - | Значение состояния |
|
|
72
72
|
| defaultValue | `TValue` | - | Значение по умолчанию |
|
|
73
73
|
| onChange | `(value: TValue) => void` | - | Колбек, вызываемый на смену состояния |
|
|
74
|
-
##
|
|
75
|
-
### Props
|
|
76
|
-
| name | type | default value | description |
|
|
77
|
-
|------|------|---------------|-------------|
|
|
78
|
-
| source | `BaseSource<T>` | - | |
|
|
79
|
-
## useSaveFilterState
|
|
74
|
+
## useDataPersist
|
|
80
75
|
### Props
|
|
81
76
|
| name | type | default value | description |
|
|
82
77
|
|------|------|---------------|-------------|
|
package/dist/cjs/hooks/index.js
CHANGED
|
@@ -29,5 +29,4 @@ __exportStar(require("./useIsomorphicLayoutEffect"), exports);
|
|
|
29
29
|
__exportStar(require("./useSwipeable"), exports);
|
|
30
30
|
__exportStar(require("./useThemeConfig"), exports);
|
|
31
31
|
__exportStar(require("./useValueControl"), exports);
|
|
32
|
-
__exportStar(require("./
|
|
33
|
-
__exportStar(require("./useSaveFilterState"), exports);
|
|
32
|
+
__exportStar(require("./useDataPersist"), exports);
|
|
@@ -22,5 +22,5 @@ var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
|
|
|
22
22
|
Object.defineProperty(exports, "__esModule", {
|
|
23
23
|
value: true
|
|
24
24
|
});
|
|
25
|
-
__exportStar(require("./
|
|
25
|
+
__exportStar(require("./useDataPersist"), exports);
|
|
26
26
|
__exportStar(require("./sources"), exports);
|
|
@@ -3,7 +3,7 @@ export declare abstract class BaseSource<TFilter> {
|
|
|
3
3
|
private validate;
|
|
4
4
|
protected parser: (value: string) => TFilter;
|
|
5
5
|
protected serializer: (value: TFilter) => string;
|
|
6
|
-
protected abstract
|
|
6
|
+
protected abstract getFromSource(): string;
|
|
7
7
|
protected abstract setToSource(value: string): void;
|
|
8
8
|
constructor(filterKey: string, validate: (value: unknown) => value is TFilter, parser?: (value: string) => TFilter, serializer?: (value: TFilter) => string);
|
|
9
9
|
getFilter: () => NonNullable<TFilter> | null;
|
|
@@ -11,10 +11,14 @@ class BaseSource {
|
|
|
11
11
|
this.parser = JSON.parse;
|
|
12
12
|
this.serializer = JSON.stringify;
|
|
13
13
|
this.getFilter = () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
try {
|
|
15
|
+
const filterFromQueryParams = this.getFromSource();
|
|
16
|
+
const parsedValue = filterFromQueryParams ? this.parser(filterFromQueryParams) : null;
|
|
17
|
+
const isValid = parsedValue && this.validate(parsedValue);
|
|
18
|
+
return isValid ? parsedValue : null;
|
|
19
|
+
} catch (_a) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
18
22
|
};
|
|
19
23
|
this.setFilter = filter => {
|
|
20
24
|
const encodedValue = this.serializer(filter);
|
|
@@ -7,7 +7,7 @@ exports.LocalStorageSource = void 0;
|
|
|
7
7
|
const utils_1 = require("../../../utils");
|
|
8
8
|
const baseSource_1 = require("./baseSource");
|
|
9
9
|
class LocalStorageSource extends baseSource_1.BaseSource {
|
|
10
|
-
|
|
10
|
+
getFromSource() {
|
|
11
11
|
if ((0, utils_1.isBrowser)()) {
|
|
12
12
|
return localStorage.getItem(this.filterKey) || '';
|
|
13
13
|
}
|
|
@@ -7,7 +7,7 @@ exports.QueryParamSource = void 0;
|
|
|
7
7
|
const utils_1 = require("../../../utils");
|
|
8
8
|
const baseSource_1 = require("./baseSource");
|
|
9
9
|
class QueryParamSource extends baseSource_1.BaseSource {
|
|
10
|
-
|
|
10
|
+
getFromSource() {
|
|
11
11
|
if ((0, utils_1.isBrowser)()) {
|
|
12
12
|
return new URL(window.location.href).searchParams.get(this.filterKey) || '';
|
|
13
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateProps } from './
|
|
1
|
+
import { StateProps } from './useSource';
|
|
2
2
|
export type FilterStateOptions<T> = {
|
|
3
3
|
filterQueryKey: string;
|
|
4
4
|
filterLocalStorageKey: string;
|
|
@@ -9,7 +9,7 @@ type FilterStateProps<TFilter> = Omit<StateProps<TFilter>, 'source'> & {
|
|
|
9
9
|
parser?(jsonFilter: string): TFilter;
|
|
10
10
|
serializer?(filter: TFilter): string;
|
|
11
11
|
};
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const useDataPersist: <TFilter>({ options, parser, serializer }: FilterStateProps<TFilter>) => {
|
|
13
13
|
getDefaultFilter: () => NonNullable<TFilter> | null | undefined;
|
|
14
14
|
setDataToStorages: (data: TFilter) => void;
|
|
15
15
|
};
|
|
@@ -3,27 +3,28 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.useDataPersist = void 0;
|
|
7
7
|
const react_1 = require("react");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const sources_1 = require("./sources");
|
|
9
|
+
const useSource_1 = require("./useSource");
|
|
10
|
+
const useDataPersist = _ref => {
|
|
10
11
|
let {
|
|
11
12
|
options,
|
|
12
13
|
parser,
|
|
13
14
|
serializer
|
|
14
15
|
} = _ref;
|
|
15
|
-
const querySource = (0, react_1.useMemo)(() => options ? new
|
|
16
|
-
const localStorageSource = (0, react_1.useMemo)(() => options ? new
|
|
16
|
+
const querySource = (0, react_1.useMemo)(() => options ? new sources_1.QueryParamSource(options.filterQueryKey, options.validateData, parser, serializer) : undefined, [options, parser, serializer]);
|
|
17
|
+
const localStorageSource = (0, react_1.useMemo)(() => options ? new sources_1.LocalStorageSource(options.filterLocalStorageKey, options.validateData) : undefined, [options]);
|
|
17
18
|
const {
|
|
18
19
|
getData: getLocalStorageData,
|
|
19
20
|
setData: setLocalStorageData
|
|
20
|
-
} = (0,
|
|
21
|
+
} = (0, useSource_1.useSource)({
|
|
21
22
|
source: querySource
|
|
22
23
|
});
|
|
23
24
|
const {
|
|
24
25
|
getData: getQueryParamsData,
|
|
25
26
|
setData: setQueryParamsData
|
|
26
|
-
} = (0,
|
|
27
|
+
} = (0, useSource_1.useSource)({
|
|
27
28
|
source: localStorageSource
|
|
28
29
|
});
|
|
29
30
|
const setDataToStorages = (0, react_1.useCallback)(data => {
|
|
@@ -39,4 +40,4 @@ const useSaveFilterState = _ref => {
|
|
|
39
40
|
setDataToStorages
|
|
40
41
|
};
|
|
41
42
|
};
|
|
42
|
-
exports.
|
|
43
|
+
exports.useDataPersist = useDataPersist;
|
|
@@ -2,7 +2,7 @@ import { BaseSource } from './sources/baseSource';
|
|
|
2
2
|
export type StateProps<T> = {
|
|
3
3
|
source?: BaseSource<T>;
|
|
4
4
|
};
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const useSource: <T>({ source }: StateProps<T>) => {
|
|
6
6
|
getData: () => NonNullable<T> | null | undefined;
|
|
7
7
|
setData: (filter: T) => void;
|
|
8
8
|
};
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.useSource = void 0;
|
|
7
7
|
const react_1 = require("react");
|
|
8
|
-
const
|
|
8
|
+
const useSource = _ref => {
|
|
9
9
|
let {
|
|
10
10
|
source
|
|
11
11
|
} = _ref;
|
|
@@ -21,4 +21,4 @@ const useSaveState = _ref => {
|
|
|
21
21
|
setData
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
|
-
exports.
|
|
24
|
+
exports.useSource = useSource;
|
|
@@ -15,13 +15,13 @@ const useEventHandler_1 = require("./useEventHandler");
|
|
|
15
15
|
function useDebounce(callback) {
|
|
16
16
|
let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
17
17
|
const timeStampRef = (0, react_1.useRef)(0);
|
|
18
|
-
|
|
18
|
+
const timerIdRef = (0, react_1.useRef)(-1);
|
|
19
19
|
return (0, useEventHandler_1.useEventHandler)(() => {
|
|
20
20
|
(0, utils_1.isBrowser)() && requestAnimationFrame(timestamp => {
|
|
21
21
|
if (timestamp < timeStampRef.current) {
|
|
22
|
-
clearTimeout(
|
|
22
|
+
clearTimeout(timerIdRef.current);
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
timerIdRef.current = setTimeout(callback, timeout);
|
|
25
25
|
timeStampRef.current = timestamp + timeout;
|
|
26
26
|
});
|
|
27
27
|
});
|
package/dist/esm/hooks/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export declare abstract class BaseSource<TFilter> {
|
|
|
3
3
|
private validate;
|
|
4
4
|
protected parser: (value: string) => TFilter;
|
|
5
5
|
protected serializer: (value: TFilter) => string;
|
|
6
|
-
protected abstract
|
|
6
|
+
protected abstract getFromSource(): string;
|
|
7
7
|
protected abstract setToSource(value: string): void;
|
|
8
8
|
constructor(filterKey: string, validate: (value: unknown) => value is TFilter, parser?: (value: string) => TFilter, serializer?: (value: TFilter) => string);
|
|
9
9
|
getFilter: () => NonNullable<TFilter> | null;
|
|
@@ -5,10 +5,15 @@ export class BaseSource {
|
|
|
5
5
|
this.parser = JSON.parse;
|
|
6
6
|
this.serializer = JSON.stringify;
|
|
7
7
|
this.getFilter = () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
try {
|
|
9
|
+
const filterFromQueryParams = this.getFromSource();
|
|
10
|
+
const parsedValue = filterFromQueryParams ? this.parser(filterFromQueryParams) : null;
|
|
11
|
+
const isValid = parsedValue && this.validate(parsedValue);
|
|
12
|
+
return isValid ? parsedValue : null;
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
12
17
|
};
|
|
13
18
|
this.setFilter = (filter) => {
|
|
14
19
|
const encodedValue = this.serializer(filter);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isBrowser } from '../../../utils';
|
|
2
2
|
import { BaseSource } from './baseSource';
|
|
3
3
|
export class QueryParamSource extends BaseSource {
|
|
4
|
-
|
|
4
|
+
getFromSource() {
|
|
5
5
|
if (isBrowser()) {
|
|
6
6
|
return new URL(window.location.href).searchParams.get(this.filterKey) || '';
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateProps } from './
|
|
1
|
+
import { StateProps } from './useSource';
|
|
2
2
|
export type FilterStateOptions<T> = {
|
|
3
3
|
filterQueryKey: string;
|
|
4
4
|
filterLocalStorageKey: string;
|
|
@@ -9,7 +9,7 @@ type FilterStateProps<TFilter> = Omit<StateProps<TFilter>, 'source'> & {
|
|
|
9
9
|
parser?(jsonFilter: string): TFilter;
|
|
10
10
|
serializer?(filter: TFilter): string;
|
|
11
11
|
};
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const useDataPersist: <TFilter>({ options, parser, serializer }: FilterStateProps<TFilter>) => {
|
|
13
13
|
getDefaultFilter: () => NonNullable<TFilter> | null | undefined;
|
|
14
14
|
setDataToStorages: (data: TFilter) => void;
|
|
15
15
|
};
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { LocalStorageSource, QueryParamSource
|
|
3
|
-
|
|
2
|
+
import { LocalStorageSource, QueryParamSource } from './sources';
|
|
3
|
+
import { useSource } from './useSource';
|
|
4
|
+
export const useDataPersist = ({ options, parser, serializer }) => {
|
|
4
5
|
const querySource = useMemo(() => options
|
|
5
6
|
? new QueryParamSource(options.filterQueryKey, options.validateData, parser, serializer)
|
|
6
7
|
: undefined, [options, parser, serializer]);
|
|
7
|
-
const localStorageSource = useMemo(() => options
|
|
8
|
-
|
|
9
|
-
: undefined, [options, parser, serializer]);
|
|
10
|
-
const { getData: getLocalStorageData, setData: setLocalStorageData } = useSaveState({
|
|
8
|
+
const localStorageSource = useMemo(() => (options ? new LocalStorageSource(options.filterLocalStorageKey, options.validateData) : undefined), [options]);
|
|
9
|
+
const { getData: getLocalStorageData, setData: setLocalStorageData } = useSource({
|
|
11
10
|
source: querySource,
|
|
12
11
|
});
|
|
13
|
-
const { getData: getQueryParamsData, setData: setQueryParamsData } =
|
|
12
|
+
const { getData: getQueryParamsData, setData: setQueryParamsData } = useSource({
|
|
14
13
|
source: localStorageSource,
|
|
15
14
|
});
|
|
16
15
|
const setDataToStorages = useCallback((data) => {
|
|
@@ -2,7 +2,7 @@ import { BaseSource } from './sources/baseSource';
|
|
|
2
2
|
export type StateProps<T> = {
|
|
3
3
|
source?: BaseSource<T>;
|
|
4
4
|
};
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const useSource: <T>({ source }: StateProps<T>) => {
|
|
6
6
|
getData: () => NonNullable<T> | null | undefined;
|
|
7
7
|
setData: (filter: T) => void;
|
|
8
8
|
};
|
|
@@ -8,14 +8,14 @@ import { useEventHandler } from './useEventHandler';
|
|
|
8
8
|
*/
|
|
9
9
|
export function useDebounce(callback, timeout = 0) {
|
|
10
10
|
const timeStampRef = useRef(0);
|
|
11
|
-
|
|
11
|
+
const timerIdRef = useRef(-1);
|
|
12
12
|
return useEventHandler(() => {
|
|
13
13
|
isBrowser() &&
|
|
14
14
|
requestAnimationFrame(timestamp => {
|
|
15
15
|
if (timestamp < timeStampRef.current) {
|
|
16
|
-
clearTimeout(
|
|
16
|
+
clearTimeout(timerIdRef.current);
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
timerIdRef.current = setTimeout(callback, timeout);
|
|
19
19
|
timeStampRef.current = timestamp + timeout;
|
|
20
20
|
});
|
|
21
21
|
});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Utils",
|
|
7
|
-
"version": "3.
|
|
7
|
+
"version": "3.8.1",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"react-swipeable": "7.0.2",
|
|
40
40
|
"uncontrollable": "8.0.4"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "d12776ae6b32233f12df33facc32de6a8758706a"
|
|
43
43
|
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export abstract class BaseSource<TFilter> {
|
|
2
2
|
protected parser: (value: string) => TFilter = JSON.parse;
|
|
3
3
|
protected serializer: (value: TFilter) => string = JSON.stringify;
|
|
4
|
-
protected abstract
|
|
4
|
+
protected abstract getFromSource(): string;
|
|
5
5
|
protected abstract setToSource(value: string): void;
|
|
6
6
|
|
|
7
7
|
constructor(
|
|
@@ -19,10 +19,14 @@ export abstract class BaseSource<TFilter> {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
getFilter = () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
try {
|
|
23
|
+
const filterFromQueryParams = this.getFromSource();
|
|
24
|
+
const parsedValue = filterFromQueryParams ? (this.parser(filterFromQueryParams) as TFilter) : null;
|
|
25
|
+
const isValid = parsedValue && this.validate(parsedValue);
|
|
26
|
+
return isValid ? parsedValue : null;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
setFilter = (filter: TFilter) => {
|
|
@@ -2,7 +2,7 @@ import { isBrowser } from '../../../utils';
|
|
|
2
2
|
import { BaseSource } from './baseSource';
|
|
3
3
|
|
|
4
4
|
export class LocalStorageSource<TFilter> extends BaseSource<TFilter> {
|
|
5
|
-
|
|
5
|
+
getFromSource(): string {
|
|
6
6
|
if (isBrowser()) {
|
|
7
7
|
return localStorage.getItem(this.filterKey) || '';
|
|
8
8
|
}
|
|
@@ -2,7 +2,7 @@ import { isBrowser } from '../../../utils';
|
|
|
2
2
|
import { BaseSource } from './baseSource';
|
|
3
3
|
|
|
4
4
|
export class QueryParamSource<TFilter> extends BaseSource<TFilter> {
|
|
5
|
-
|
|
5
|
+
getFromSource(): string {
|
|
6
6
|
if (isBrowser()) {
|
|
7
7
|
return new URL(window.location.href).searchParams.get(this.filterKey) || '';
|
|
8
8
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
import { LocalStorageSource, QueryParamSource
|
|
3
|
+
import { LocalStorageSource, QueryParamSource } from './sources';
|
|
4
|
+
import { StateProps, useSource } from './useSource';
|
|
4
5
|
|
|
5
6
|
export type FilterStateOptions<T> = {
|
|
6
7
|
filterQueryKey: string;
|
|
@@ -14,7 +15,7 @@ type FilterStateProps<TFilter> = Omit<StateProps<TFilter>, 'source'> & {
|
|
|
14
15
|
serializer?(filter: TFilter): string;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
export const
|
|
18
|
+
export const useDataPersist = <TFilter>({ options, parser, serializer }: FilterStateProps<TFilter>) => {
|
|
18
19
|
const querySource = useMemo(
|
|
19
20
|
() =>
|
|
20
21
|
options
|
|
@@ -23,17 +24,14 @@ export const useSaveFilterState = <TFilter>({ options, parser, serializer }: Fil
|
|
|
23
24
|
[options, parser, serializer],
|
|
24
25
|
);
|
|
25
26
|
const localStorageSource = useMemo(
|
|
26
|
-
() =>
|
|
27
|
-
|
|
28
|
-
? new LocalStorageSource<TFilter>(options.filterLocalStorageKey, options.validateData, parser, serializer)
|
|
29
|
-
: undefined,
|
|
30
|
-
[options, parser, serializer],
|
|
27
|
+
() => (options ? new LocalStorageSource<TFilter>(options.filterLocalStorageKey, options.validateData) : undefined),
|
|
28
|
+
[options],
|
|
31
29
|
);
|
|
32
30
|
|
|
33
|
-
const { getData: getLocalStorageData, setData: setLocalStorageData } =
|
|
31
|
+
const { getData: getLocalStorageData, setData: setLocalStorageData } = useSource<TFilter>({
|
|
34
32
|
source: querySource,
|
|
35
33
|
});
|
|
36
|
-
const { getData: getQueryParamsData, setData: setQueryParamsData } =
|
|
34
|
+
const { getData: getQueryParamsData, setData: setQueryParamsData } = useSource<TFilter>({
|
|
37
35
|
source: localStorageSource,
|
|
38
36
|
});
|
|
39
37
|
|
package/src/hooks/useDebounce.ts
CHANGED
|
@@ -10,15 +10,15 @@ import { useEventHandler } from './useEventHandler';
|
|
|
10
10
|
*/
|
|
11
11
|
export function useDebounce(callback: () => void, timeout = 0) {
|
|
12
12
|
const timeStampRef = useRef<number>(0);
|
|
13
|
-
|
|
13
|
+
const timerIdRef = useRef<NodeJS.Timeout | number>(-1);
|
|
14
14
|
|
|
15
15
|
return useEventHandler(() => {
|
|
16
16
|
isBrowser() &&
|
|
17
17
|
requestAnimationFrame(timestamp => {
|
|
18
18
|
if (timestamp < timeStampRef.current) {
|
|
19
|
-
clearTimeout(
|
|
19
|
+
clearTimeout(timerIdRef.current);
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
timerIdRef.current = setTimeout(callback, timeout);
|
|
22
22
|
timeStampRef.current = timestamp + timeout;
|
|
23
23
|
});
|
|
24
24
|
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|