@olenbetong/synergi-react 0.6.7 → 0.6.9
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/LICENSE +21 -0
- package/dist/esm/ob.react.js +15 -120
- package/dist/esm/ob.react.min.js +1 -1
- package/dist/esm/ob.react.min.js.map +4 -4
- package/dist/iife/ob.react.js +12 -120
- package/dist/iife/ob.react.min.js +1 -1
- package/dist/iife/ob.react.min.js.map +4 -4
- package/es/synergi-react/src/index.d.ts +1 -3
- package/es/synergi-react/src/index.js +1 -3
- package/package.json +5 -3
- package/src/index.ts +1 -3
- package/es/synergi-react/src/useDebounce.d.ts +0 -9
- package/es/synergi-react/src/useDebounce.js +0 -17
- package/es/synergi-react/src/usePersistedSetting.d.ts +0 -7
- package/es/synergi-react/src/usePersistedSetting.js +0 -53
- package/es/synergi-react/src/useSearchParamState.d.ts +0 -13
- package/es/synergi-react/src/useSearchParamState.js +0 -42
- package/src/useDebounce.ts +0 -21
- package/src/usePersistedSetting.ts +0 -78
- package/src/useSearchParamState.ts +0 -78
|
@@ -10,6 +10,4 @@ export { Spinner, SpinnerProps } from "./Spinner/index.js";
|
|
|
10
10
|
export { SplitContainer, SplitContainerProps } from "./SplitContainer/index.js";
|
|
11
11
|
export { useTranslation } from "./useTranslation/index.js";
|
|
12
12
|
export { ValueToggle, ValueToggleProps } from "./ValueToggle/index.js";
|
|
13
|
-
export { useDebounce } from "
|
|
14
|
-
export { usePersistedSetting } from "./usePersistedSetting.js";
|
|
15
|
-
export { useSearchParamState } from "./useSearchParamState.js";
|
|
13
|
+
export { useDebounce, usePersistedSetting, useSearchParamState } from "@olenbetong/appframe-react";
|
|
@@ -10,6 +10,4 @@ export { Spinner } from "./Spinner/index.js";
|
|
|
10
10
|
export { SplitContainer } from "./SplitContainer/index.js";
|
|
11
11
|
export { useTranslation } from "./useTranslation/index.js";
|
|
12
12
|
export { ValueToggle } from "./ValueToggle/index.js";
|
|
13
|
-
export { useDebounce } from "
|
|
14
|
-
export { usePersistedSetting } from "./usePersistedSetting.js";
|
|
15
|
-
export { useSearchParamState } from "./useSearchParamState.js";
|
|
13
|
+
export { useDebounce, usePersistedSetting, useSearchParamState } from "@olenbetong/appframe-react";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olenbetong/synergi-react",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "Standalone React component for SynergiWeb and Partner Portal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./es/index.d.ts",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"sideEffects": false,
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"@olenbetong/appframe-core": "^2.0.4",
|
|
72
|
+
"@olenbetong/appframe-react": "^1.7.0",
|
|
72
73
|
"clsx": "^1.1.1",
|
|
73
74
|
"localforage": "^1.10.0",
|
|
74
75
|
"mitt": "^3.0.0"
|
|
@@ -86,5 +87,6 @@
|
|
|
86
87
|
},
|
|
87
88
|
"devDependencies": {
|
|
88
89
|
"replace-in-files": "^3.0.0"
|
|
89
|
-
}
|
|
90
|
-
|
|
90
|
+
},
|
|
91
|
+
"gitHead": "9775143adfa26db32b03a1ce62808db408c51933"
|
|
92
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,4 @@ export { SplitContainer, SplitContainerProps } from "./SplitContainer/index.js";
|
|
|
22
22
|
|
|
23
23
|
export { useTranslation } from "./useTranslation/index.js";
|
|
24
24
|
export { ValueToggle, ValueToggleProps } from "./ValueToggle/index.js";
|
|
25
|
-
export { useDebounce } from "
|
|
26
|
-
export { usePersistedSetting } from "./usePersistedSetting.js";
|
|
27
|
-
export { useSearchParamState } from "./useSearchParamState.js";
|
|
25
|
+
export { useDebounce, usePersistedSetting, useSearchParamState } from "@olenbetong/appframe-react";
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Returns a debounced version of the given value.
|
|
4
|
-
*
|
|
5
|
-
* @param value
|
|
6
|
-
* @param delay
|
|
7
|
-
* @returns
|
|
8
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
9
|
-
*/
|
|
10
|
-
export function useDebounce(value, delay = 300) {
|
|
11
|
-
let [debouncedValue, setValue] = useState(value);
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
let timeout = setTimeout(() => setValue(value), delay);
|
|
14
|
-
return () => clearTimeout(timeout);
|
|
15
|
-
}, [delay, value]);
|
|
16
|
-
return debouncedValue;
|
|
17
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* On mount, load the persisted state from Indexed DB, and if the persisted
|
|
3
|
-
* layout version matches, restore the layout. Then listen to changes to the
|
|
4
|
-
* state, and store the latest version in Indexed DB.
|
|
5
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
6
|
-
*/
|
|
7
|
-
export declare function usePersistedSetting<T = unknown>(key: string, defaultValue: T): [T, (newValue: T) => void];
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import mitt from "mitt";
|
|
2
|
-
import localforage from "localforage";
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
4
|
-
const settingsStore = localforage.createInstance({
|
|
5
|
-
name: `AfUserSettings.${af.userSession.login}`,
|
|
6
|
-
});
|
|
7
|
-
class SettingsCache {
|
|
8
|
-
#mitt;
|
|
9
|
-
#cache = {};
|
|
10
|
-
constructor() {
|
|
11
|
-
this.#mitt = mitt();
|
|
12
|
-
// Load all article user settings even if the setting is not needed yet.
|
|
13
|
-
// This ways the persisted state can be restored faster after the initial
|
|
14
|
-
// page load.'
|
|
15
|
-
settingsStore.keys().then((keys) => Promise.allSettled(keys
|
|
16
|
-
.filter((key) => key.startsWith(af.article.id))
|
|
17
|
-
.map((storeKey) => settingsStore.getItem(storeKey).then((storedValue) => {
|
|
18
|
-
let key = storeKey.replace(`${af.article.id}.`, "");
|
|
19
|
-
if (storedValue !== undefined && this.#cache[key] === undefined) {
|
|
20
|
-
this.setItem(key, storedValue);
|
|
21
|
-
}
|
|
22
|
-
}))));
|
|
23
|
-
}
|
|
24
|
-
setItem(key, value) {
|
|
25
|
-
this.#cache[key] = value;
|
|
26
|
-
this.#mitt.emit("change", { key, value });
|
|
27
|
-
let storeKey = `${af.article.id}.${key}`;
|
|
28
|
-
settingsStore.setItem(storeKey, value);
|
|
29
|
-
}
|
|
30
|
-
getItem(key) {
|
|
31
|
-
return this.#cache[key];
|
|
32
|
-
}
|
|
33
|
-
listen(setting, callback) {
|
|
34
|
-
function handler({ key, value }) {
|
|
35
|
-
if (setting === key) {
|
|
36
|
-
callback(value);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
this.#mitt.on("change", handler);
|
|
40
|
-
return () => this.#mitt.off("change", handler);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const settingsCache = new SettingsCache();
|
|
44
|
-
/**
|
|
45
|
-
* On mount, load the persisted state from Indexed DB, and if the persisted
|
|
46
|
-
* layout version matches, restore the layout. Then listen to changes to the
|
|
47
|
-
* state, and store the latest version in Indexed DB.
|
|
48
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
49
|
-
*/
|
|
50
|
-
export function usePersistedSetting(key, defaultValue) {
|
|
51
|
-
let value = useSyncExternalStore((onChange) => settingsCache.listen(key, () => onChange()), () => settingsCache.getItem(key) ?? defaultValue);
|
|
52
|
-
return [value, (newValue) => settingsCache.setItem(key, newValue)];
|
|
53
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
declare type SearchParamValue = string | null;
|
|
3
|
-
/**
|
|
4
|
-
* A hook that wraps useState, and keeps the state value synced with
|
|
5
|
-
* a search parameter.
|
|
6
|
-
*
|
|
7
|
-
* @param {string} key They key used to store the value in the search parameters
|
|
8
|
-
* @param {SearchParamValue} fallbackValue Default value for the state. Only used if the search parameters do not contains a value for the key parameter
|
|
9
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
10
|
-
*/
|
|
11
|
-
export declare function useSearchParamState(key: string, fallbackValue?: SearchParamValue | (() => SearchParamValue), multiple?: false): [SearchParamValue, React.Dispatch<React.SetStateAction<SearchParamValue>>];
|
|
12
|
-
export declare function useSearchParamState(key: string, fallbackValue: string[] | (() => string[]), multiple: true): [string[], React.Dispatch<React.SetStateAction<string[]>>];
|
|
13
|
-
export {};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
export function useSearchParamState(key, fallbackValue, multiple = false) {
|
|
3
|
-
let defaultRef = useRef(multiple ? [] : null);
|
|
4
|
-
let [value, setValue] = useState(() => {
|
|
5
|
-
let params = new URLSearchParams(window.location.search);
|
|
6
|
-
let value = multiple ? params.getAll(key) : params.get(key);
|
|
7
|
-
// Even if we don't use the default value here, we want to keep it for later
|
|
8
|
-
// so we can see if the default value is the active value. If that's the case,
|
|
9
|
-
// we remove the parameter from the search parameters.
|
|
10
|
-
if (typeof fallbackValue === "function") {
|
|
11
|
-
defaultRef.current = fallbackValue();
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
defaultRef.current = fallbackValue ?? (multiple ? [] : null);
|
|
15
|
-
}
|
|
16
|
-
if (!value) {
|
|
17
|
-
return defaultRef.current;
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
});
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
let params = new URLSearchParams(window.location.search);
|
|
23
|
-
if (multiple) {
|
|
24
|
-
params.delete(key);
|
|
25
|
-
value.forEach((v) => params.append(key, v));
|
|
26
|
-
}
|
|
27
|
-
else if (value && value !== defaultRef.current) {
|
|
28
|
-
params.set(key, String(value));
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
params.delete(key);
|
|
32
|
-
}
|
|
33
|
-
let newPath = window.location.pathname;
|
|
34
|
-
let paramString = params.toString();
|
|
35
|
-
if (paramString.length) {
|
|
36
|
-
newPath += "?" + paramString;
|
|
37
|
-
}
|
|
38
|
-
window.history.replaceState({ path: newPath }, "", newPath);
|
|
39
|
-
}, [key, value]);
|
|
40
|
-
// @ts-ignore i give up
|
|
41
|
-
return [value, setValue];
|
|
42
|
-
}
|
package/src/useDebounce.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Returns a debounced version of the given value.
|
|
5
|
-
*
|
|
6
|
-
* @param value
|
|
7
|
-
* @param delay
|
|
8
|
-
* @returns
|
|
9
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
10
|
-
*/
|
|
11
|
-
export function useDebounce<T>(value: T, delay = 300) {
|
|
12
|
-
let [debouncedValue, setValue] = useState(value);
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
let timeout = setTimeout(() => setValue(value), delay);
|
|
16
|
-
|
|
17
|
-
return () => clearTimeout(timeout);
|
|
18
|
-
}, [delay, value]);
|
|
19
|
-
|
|
20
|
-
return debouncedValue;
|
|
21
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import mitt, { Emitter, Handler } from "mitt";
|
|
2
|
-
import localforage from "localforage";
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
4
|
-
|
|
5
|
-
const settingsStore = localforage.createInstance({
|
|
6
|
-
name: `AfUserSettings.${af.userSession.login}`,
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
class SettingsCache {
|
|
10
|
-
#mitt: Emitter<{ change: { key: string; value: unknown } }>;
|
|
11
|
-
#cache: Record<string, unknown> = {};
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
this.#mitt = mitt();
|
|
15
|
-
// Load all article user settings even if the setting is not needed yet.
|
|
16
|
-
// This ways the persisted state can be restored faster after the initial
|
|
17
|
-
// page load.'
|
|
18
|
-
settingsStore.keys().then((keys) =>
|
|
19
|
-
Promise.allSettled(
|
|
20
|
-
keys
|
|
21
|
-
.filter((key) => key.startsWith(af.article.id))
|
|
22
|
-
.map((storeKey) =>
|
|
23
|
-
settingsStore.getItem(storeKey).then((storedValue) => {
|
|
24
|
-
let key = storeKey.replace(`${af.article.id}.`, "");
|
|
25
|
-
|
|
26
|
-
if (storedValue !== undefined && this.#cache[key] === undefined) {
|
|
27
|
-
this.setItem(key, storedValue);
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
setItem(key: string, value: unknown) {
|
|
36
|
-
this.#cache[key] = value;
|
|
37
|
-
this.#mitt.emit("change", { key, value });
|
|
38
|
-
|
|
39
|
-
let storeKey = `${af.article.id}.${key}`;
|
|
40
|
-
settingsStore.setItem(storeKey, value);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getItem(key: string): unknown {
|
|
44
|
-
return this.#cache[key];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
listen(setting: string, callback: Handler<unknown>) {
|
|
48
|
-
function handler({ key, value }: { key: string; value: unknown }) {
|
|
49
|
-
if (setting === key) {
|
|
50
|
-
callback(value);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
this.#mitt.on("change", handler);
|
|
55
|
-
|
|
56
|
-
return () => this.#mitt.off("change", handler);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const settingsCache = new SettingsCache();
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* On mount, load the persisted state from Indexed DB, and if the persisted
|
|
64
|
-
* layout version matches, restore the layout. Then listen to changes to the
|
|
65
|
-
* state, and store the latest version in Indexed DB.
|
|
66
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
67
|
-
*/
|
|
68
|
-
export function usePersistedSetting<T = unknown>(
|
|
69
|
-
key: string,
|
|
70
|
-
defaultValue: T
|
|
71
|
-
): [T, (newValue: T) => void] {
|
|
72
|
-
let value = useSyncExternalStore(
|
|
73
|
-
(onChange) => settingsCache.listen(key, () => onChange()),
|
|
74
|
-
() => (settingsCache.getItem(key) as T) ?? defaultValue
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
return [value, (newValue: T) => settingsCache.setItem(key, newValue)];
|
|
78
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
|
|
3
|
-
type SearchParamValue = string | null;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A hook that wraps useState, and keeps the state value synced with
|
|
7
|
-
* a search parameter.
|
|
8
|
-
*
|
|
9
|
-
* @param {string} key They key used to store the value in the search parameters
|
|
10
|
-
* @param {SearchParamValue} fallbackValue Default value for the state. Only used if the search parameters do not contains a value for the key parameter
|
|
11
|
-
* @deprecated Use equivalent hook in @olenbetong/appframe-react instead
|
|
12
|
-
*/
|
|
13
|
-
export function useSearchParamState(
|
|
14
|
-
key: string,
|
|
15
|
-
fallbackValue?: SearchParamValue | (() => SearchParamValue),
|
|
16
|
-
multiple?: false
|
|
17
|
-
): [SearchParamValue, React.Dispatch<React.SetStateAction<SearchParamValue>>];
|
|
18
|
-
export function useSearchParamState(
|
|
19
|
-
key: string,
|
|
20
|
-
fallbackValue: string[] | (() => string[]),
|
|
21
|
-
multiple: true
|
|
22
|
-
): [string[], React.Dispatch<React.SetStateAction<string[]>>];
|
|
23
|
-
export function useSearchParamState(
|
|
24
|
-
key: string,
|
|
25
|
-
fallbackValue?:
|
|
26
|
-
| string[]
|
|
27
|
-
| SearchParamValue
|
|
28
|
-
| (() => SearchParamValue)
|
|
29
|
-
| (() => string[]),
|
|
30
|
-
multiple: boolean = false
|
|
31
|
-
):
|
|
32
|
-
| [SearchParamValue, React.Dispatch<React.SetStateAction<SearchParamValue>>]
|
|
33
|
-
| [string[], React.Dispatch<React.SetStateAction<string[]>>] {
|
|
34
|
-
let defaultRef = useRef<SearchParamValue | string[]>(multiple ? [] : null);
|
|
35
|
-
let [value, setValue] = useState<SearchParamValue | string[]>(() => {
|
|
36
|
-
let params = new URLSearchParams(window.location.search);
|
|
37
|
-
let value = multiple ? params.getAll(key) : params.get(key);
|
|
38
|
-
|
|
39
|
-
// Even if we don't use the default value here, we want to keep it for later
|
|
40
|
-
// so we can see if the default value is the active value. If that's the case,
|
|
41
|
-
// we remove the parameter from the search parameters.
|
|
42
|
-
if (typeof fallbackValue === "function") {
|
|
43
|
-
defaultRef.current = fallbackValue();
|
|
44
|
-
} else {
|
|
45
|
-
defaultRef.current = fallbackValue ?? (multiple ? [] : null);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!value) {
|
|
49
|
-
return defaultRef.current;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return value;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
let params = new URLSearchParams(window.location.search);
|
|
57
|
-
|
|
58
|
-
if (multiple) {
|
|
59
|
-
params.delete(key);
|
|
60
|
-
(value as string[]).forEach((v) => params.append(key, v));
|
|
61
|
-
} else if (value && value !== defaultRef.current) {
|
|
62
|
-
params.set(key, String(value));
|
|
63
|
-
} else {
|
|
64
|
-
params.delete(key);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let newPath = window.location.pathname;
|
|
68
|
-
let paramString = params.toString();
|
|
69
|
-
if (paramString.length) {
|
|
70
|
-
newPath += "?" + paramString;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
window.history.replaceState({ path: newPath }, "", newPath);
|
|
74
|
-
}, [key, value]);
|
|
75
|
-
|
|
76
|
-
// @ts-ignore i give up
|
|
77
|
-
return [value, setValue];
|
|
78
|
-
}
|