@pallasoft/ps-core-components 2.42.0 → 2.44.0

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.
Files changed (90) hide show
  1. package/dist/components/ps-button.js +3 -1
  2. package/dist/components/ps-reflective-app-shell.d.ts +3 -1
  3. package/dist/components/ps-reflective-app-shell.js +10 -3
  4. package/dist/components/ps-scroll-restoration.d.ts +6 -0
  5. package/dist/components/ps-scroll-restoration.js +9 -0
  6. package/dist/components/ps-skeleton-table.d.ts +3 -1
  7. package/dist/components/ps-skeleton-table.js +15 -2
  8. package/dist/constants/ps-flag-param-value.d.ts +3 -0
  9. package/dist/constants/ps-flag-param-value.js +6 -0
  10. package/dist/constants/ps-query-param-config.d.ts +4 -0
  11. package/dist/constants/ps-query-param-config.js +6 -0
  12. package/dist/constants/ps-rerender-config.d.ts +3 -0
  13. package/dist/constants/ps-rerender-config.js +6 -0
  14. package/dist/constants/ps-scroll-restoration-config.d.ts +10 -0
  15. package/dist/constants/ps-scroll-restoration-config.js +13 -0
  16. package/dist/constants/ps-skeleton-config.d.ts +2 -0
  17. package/dist/constants/ps-skeleton-config.js +2 -0
  18. package/dist/esm/components/ps-button.js +3 -1
  19. package/dist/esm/components/ps-reflective-app-shell.js +10 -3
  20. package/dist/esm/components/ps-scroll-restoration.js +5 -0
  21. package/dist/esm/components/ps-skeleton-table.js +15 -2
  22. package/dist/esm/constants/ps-flag-param-value.js +3 -0
  23. package/dist/esm/constants/ps-query-param-config.js +3 -0
  24. package/dist/esm/constants/ps-rerender-config.js +3 -0
  25. package/dist/esm/constants/ps-scroll-restoration-config.js +10 -0
  26. package/dist/esm/constants/ps-skeleton-config.js +2 -0
  27. package/dist/esm/hooks/use-ps-browser-layout-effect.js +2 -0
  28. package/dist/esm/hooks/use-ps-choice-param.js +6 -0
  29. package/dist/esm/hooks/use-ps-flag-param.js +6 -0
  30. package/dist/esm/hooks/use-ps-rerender-at.js +21 -0
  31. package/dist/esm/hooks/use-ps-scroll-restoration.js +103 -0
  32. package/dist/esm/index.js +25 -0
  33. package/dist/esm/models/ps-choice-param-data.js +1 -0
  34. package/dist/esm/models/ps-choice-param-options.js +1 -0
  35. package/dist/esm/models/ps-flag-param-data.js +1 -0
  36. package/dist/esm/models/ps-flag-param-options.js +1 -0
  37. package/dist/esm/models/ps-scroll-offsets-data.js +1 -0
  38. package/dist/esm/models/ps-scroll-pending-save-data.js +1 -0
  39. package/dist/esm/models/ps-scroll-restoration-options.js +1 -0
  40. package/dist/esm/models/ps-search-params-set-options.js +1 -0
  41. package/dist/esm/models/ps-search-params-setter.js +1 -0
  42. package/dist/esm/models/ps-search-params-state.js +1 -0
  43. package/dist/esm/models/ps-skeleton-table-row.js +1 -0
  44. package/dist/esm/services/ps-query-param-service.js +32 -0
  45. package/dist/esm/services/ps-scroll-restore-service.js +52 -0
  46. package/dist/esm/services/ps-scroll-storage-service.js +66 -0
  47. package/dist/esm/services/ps-scroll-target-service.js +29 -0
  48. package/dist/hooks/use-ps-browser-layout-effect.d.ts +2 -0
  49. package/dist/hooks/use-ps-browser-layout-effect.js +5 -0
  50. package/dist/hooks/use-ps-choice-param.d.ts +4 -0
  51. package/dist/hooks/use-ps-choice-param.js +10 -0
  52. package/dist/hooks/use-ps-flag-param.d.ts +4 -0
  53. package/dist/hooks/use-ps-flag-param.js +10 -0
  54. package/dist/hooks/use-ps-rerender-at.d.ts +1 -0
  55. package/dist/hooks/use-ps-rerender-at.js +25 -0
  56. package/dist/hooks/use-ps-scroll-restoration.d.ts +2 -0
  57. package/dist/hooks/use-ps-scroll-restoration.js +107 -0
  58. package/dist/index.d.ts +25 -0
  59. package/dist/index.js +25 -0
  60. package/dist/models/ps-choice-param-data.d.ts +4 -0
  61. package/dist/models/ps-choice-param-data.js +2 -0
  62. package/dist/models/ps-choice-param-options.d.ts +6 -0
  63. package/dist/models/ps-choice-param-options.js +2 -0
  64. package/dist/models/ps-flag-param-data.d.ts +4 -0
  65. package/dist/models/ps-flag-param-data.js +2 -0
  66. package/dist/models/ps-flag-param-options.d.ts +4 -0
  67. package/dist/models/ps-flag-param-options.js +2 -0
  68. package/dist/models/ps-scroll-offsets-data.d.ts +1 -0
  69. package/dist/models/ps-scroll-offsets-data.js +2 -0
  70. package/dist/models/ps-scroll-pending-save-data.d.ts +4 -0
  71. package/dist/models/ps-scroll-pending-save-data.js +2 -0
  72. package/dist/models/ps-scroll-restoration-options.d.ts +7 -0
  73. package/dist/models/ps-scroll-restoration-options.js +2 -0
  74. package/dist/models/ps-search-params-set-options.d.ts +4 -0
  75. package/dist/models/ps-search-params-set-options.js +2 -0
  76. package/dist/models/ps-search-params-setter.d.ts +2 -0
  77. package/dist/models/ps-search-params-setter.js +2 -0
  78. package/dist/models/ps-search-params-state.d.ts +2 -0
  79. package/dist/models/ps-search-params-state.js +2 -0
  80. package/dist/models/ps-skeleton-table-row.d.ts +4 -0
  81. package/dist/models/ps-skeleton-table-row.js +2 -0
  82. package/dist/services/ps-query-param-service.d.ts +7 -0
  83. package/dist/services/ps-query-param-service.js +36 -0
  84. package/dist/services/ps-scroll-restore-service.d.ts +3 -0
  85. package/dist/services/ps-scroll-restore-service.js +56 -0
  86. package/dist/services/ps-scroll-storage-service.d.ts +11 -0
  87. package/dist/services/ps-scroll-storage-service.js +70 -0
  88. package/dist/services/ps-scroll-target-service.d.ts +8 -0
  89. package/dist/services/ps-scroll-target-service.js +33 -0
  90. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ import { PsScrollRestorationConfig } from '../constants/ps-scroll-restoration-config.js';
2
+ import { PsScrollTargetService } from './ps-scroll-target-service.js';
3
+ export class PsScrollRestoreService {
4
+ static start(element, top, onDone) {
5
+ let isDone = false;
6
+ let observer = null;
7
+ let mutations = null;
8
+ let timer = 0;
9
+ const finish = () => {
10
+ if (isDone)
11
+ return;
12
+ isDone = true;
13
+ window.clearTimeout(timer);
14
+ observer?.disconnect();
15
+ mutations?.disconnect();
16
+ for (const name of PsScrollRestorationConfig.inputEvents)
17
+ window.removeEventListener(name, onInput, true);
18
+ onDone();
19
+ };
20
+ const onInput = () => finish();
21
+ const attempt = () => {
22
+ if (isDone)
23
+ return;
24
+ if (PsScrollTargetService.maxTop(element) >= top - PsScrollRestorationConfig.tolerancePx) {
25
+ PsScrollTargetService.scrollTo(element, top);
26
+ finish();
27
+ }
28
+ };
29
+ for (const name of PsScrollRestorationConfig.inputEvents)
30
+ window.addEventListener(name, onInput, { capture: true, passive: true });
31
+ timer = window.setTimeout(() => {
32
+ if (isDone)
33
+ return;
34
+ PsScrollTargetService.scrollTo(element, top);
35
+ finish();
36
+ }, PsScrollRestorationConfig.restoreTimeoutMs);
37
+ attempt();
38
+ if (!isDone && typeof MutationObserver !== 'undefined') {
39
+ mutations = new MutationObserver(attempt);
40
+ mutations.observe(element === null ? document.body : element, {
41
+ childList: true,
42
+ subtree: true,
43
+ });
44
+ }
45
+ if (!isDone && typeof ResizeObserver !== 'undefined') {
46
+ observer = new ResizeObserver(attempt);
47
+ for (const node of PsScrollTargetService.observed(element))
48
+ observer.observe(node);
49
+ }
50
+ return finish;
51
+ }
52
+ }
@@ -0,0 +1,66 @@
1
+ import { PsScrollRestorationConfig } from '../constants/ps-scroll-restoration-config.js';
2
+ export class PsScrollStorageService {
3
+ static read(key) {
4
+ const offsets = PsScrollStorageService.memory();
5
+ return Object.prototype.hasOwnProperty.call(offsets, key) ? offsets[key] : undefined;
6
+ }
7
+ static write(key, top) {
8
+ const offsets = PsScrollStorageService.memory();
9
+ delete offsets[key];
10
+ offsets[key] = top;
11
+ const keys = Object.keys(offsets);
12
+ const overflow = keys.length - PsScrollRestorationConfig.maxEntries;
13
+ for (const oldest of keys.slice(0, overflow > 0 ? overflow : 0))
14
+ delete offsets[oldest];
15
+ if (PsScrollStorageService.timer !== 0 || typeof window === 'undefined')
16
+ return;
17
+ PsScrollStorageService.timer = window.setTimeout(PsScrollStorageService.flush, PsScrollRestorationConfig.persistThrottleMs);
18
+ }
19
+ static flush() {
20
+ if (typeof window === 'undefined')
21
+ return;
22
+ window.clearTimeout(PsScrollStorageService.timer);
23
+ PsScrollStorageService.timer = 0;
24
+ if (PsScrollStorageService.offsets === null)
25
+ return;
26
+ try {
27
+ window.sessionStorage.setItem(PsScrollRestorationConfig.storageKey, JSON.stringify(PsScrollStorageService.offsets));
28
+ }
29
+ catch {
30
+ return;
31
+ }
32
+ }
33
+ static reset() {
34
+ if (typeof window !== 'undefined')
35
+ window.clearTimeout(PsScrollStorageService.timer);
36
+ PsScrollStorageService.timer = 0;
37
+ PsScrollStorageService.offsets = null;
38
+ }
39
+ static memory() {
40
+ if (PsScrollStorageService.offsets === null)
41
+ PsScrollStorageService.offsets = PsScrollStorageService.load();
42
+ return PsScrollStorageService.offsets;
43
+ }
44
+ static load() {
45
+ if (typeof window === 'undefined')
46
+ return {};
47
+ try {
48
+ const raw = window.sessionStorage.getItem(PsScrollRestorationConfig.storageKey);
49
+ if (raw === null)
50
+ return {};
51
+ const parsed = JSON.parse(raw);
52
+ return PsScrollStorageService.isOffsets(parsed) ? parsed : {};
53
+ }
54
+ catch {
55
+ return {};
56
+ }
57
+ }
58
+ static isOffsets(value) {
59
+ return (typeof value === 'object' &&
60
+ value !== null &&
61
+ !Array.isArray(value) &&
62
+ Object.values(value).every((entry) => typeof entry === 'number' && Number.isFinite(entry)));
63
+ }
64
+ }
65
+ PsScrollStorageService.offsets = null;
66
+ PsScrollStorageService.timer = 0;
@@ -0,0 +1,29 @@
1
+ import { PsScrollRestorationConfig } from '../constants/ps-scroll-restoration-config.js';
2
+ export class PsScrollTargetService {
3
+ static storageKey(element, restoreKey) {
4
+ return `${element === null ? PsScrollRestorationConfig.windowScope : PsScrollRestorationConfig.elementScope}${restoreKey}`;
5
+ }
6
+ static top(element) {
7
+ return element === null ? window.scrollY : element.scrollTop;
8
+ }
9
+ static maxTop(element) {
10
+ if (element !== null)
11
+ return element.scrollHeight - element.clientHeight;
12
+ return document.documentElement.scrollHeight - window.innerHeight;
13
+ }
14
+ static scrollTo(element, top) {
15
+ if (element === null) {
16
+ window.scrollTo({ behavior: 'instant', left: 0, top });
17
+ return;
18
+ }
19
+ element.scrollTo({ behavior: 'instant', left: 0, top });
20
+ }
21
+ static eventTarget(element) {
22
+ return element === null ? window : element;
23
+ }
24
+ static observed(element) {
25
+ if (element === null)
26
+ return [document.documentElement, document.body];
27
+ return [element, ...Array.from(element.children)];
28
+ }
29
+ }
@@ -0,0 +1,2 @@
1
+ import { useEffect } from 'react';
2
+ export declare const usePsBrowserLayoutEffect: typeof useEffect;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsBrowserLayoutEffect = void 0;
4
+ const react_1 = require("react");
5
+ exports.usePsBrowserLayoutEffect = typeof window === 'undefined' ? react_1.useEffect : react_1.useLayoutEffect;
@@ -0,0 +1,4 @@
1
+ import type { PsChoiceParamData } from '../models/ps-choice-param-data';
2
+ import type { PsChoiceParamOptions } from '../models/ps-choice-param-options';
3
+ import type { PsSearchParamsState } from '../models/ps-search-params-state';
4
+ export declare const usePsChoiceParam: <Value extends string>([searchParams, setSearchParams]: PsSearchParamsState, { fallback, name, options, resetParams }: PsChoiceParamOptions<Value>) => PsChoiceParamData<Value>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsChoiceParam = void 0;
4
+ const ps_query_param_config_1 = require("../constants/ps-query-param-config");
5
+ const ps_query_param_service_1 = require("../services/ps-query-param-service");
6
+ const usePsChoiceParam = ([searchParams, setSearchParams], { fallback, name, options, resetParams }) => ({
7
+ onChange: (value) => setSearchParams((current) => ps_query_param_service_1.PsQueryParamService.withChoice(current, name, value, fallback, resetParams), ps_query_param_config_1.PsQueryParamConfig.setOptions),
8
+ value: ps_query_param_service_1.PsQueryParamService.choice(searchParams.get(name), options, fallback),
9
+ });
10
+ exports.usePsChoiceParam = usePsChoiceParam;
@@ -0,0 +1,4 @@
1
+ import type { PsFlagParamData } from '../models/ps-flag-param-data';
2
+ import type { PsFlagParamOptions } from '../models/ps-flag-param-options';
3
+ import type { PsSearchParamsState } from '../models/ps-search-params-state';
4
+ export declare const usePsFlagParam: ([searchParams, setSearchParams]: PsSearchParamsState, { name, resetParams }: PsFlagParamOptions) => PsFlagParamData;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsFlagParam = void 0;
4
+ const ps_query_param_config_1 = require("../constants/ps-query-param-config");
5
+ const ps_query_param_service_1 = require("../services/ps-query-param-service");
6
+ const usePsFlagParam = ([searchParams, setSearchParams], { name, resetParams }) => ({
7
+ isOn: ps_query_param_service_1.PsQueryParamService.flag(searchParams.get(name)),
8
+ onChange: (isOn) => setSearchParams((current) => ps_query_param_service_1.PsQueryParamService.withFlag(current, name, isOn, resetParams), ps_query_param_config_1.PsQueryParamConfig.setOptions),
9
+ });
10
+ exports.usePsFlagParam = usePsFlagParam;
@@ -0,0 +1 @@
1
+ export declare const usePsRerenderAt: (atMs: number | null) => number;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsRerenderAt = void 0;
4
+ const react_1 = require("react");
5
+ const ps_rerender_config_1 = require("../constants/ps-rerender-config");
6
+ const usePsRerenderAt = (atMs) => {
7
+ const [, setTick] = (0, react_1.useState)(0);
8
+ (0, react_1.useEffect)(() => {
9
+ if (atMs === null || typeof window === 'undefined')
10
+ return;
11
+ let timer = 0;
12
+ const arm = () => {
13
+ const remaining = atMs - Date.now();
14
+ if (remaining <= 0) {
15
+ setTick((tick) => tick + 1);
16
+ return;
17
+ }
18
+ timer = window.setTimeout(arm, Math.min(remaining, ps_rerender_config_1.PsRerenderConfig.maxTimerMs));
19
+ };
20
+ arm();
21
+ return () => window.clearTimeout(timer);
22
+ }, [atMs]);
23
+ return Date.now();
24
+ };
25
+ exports.usePsRerenderAt = usePsRerenderAt;
@@ -0,0 +1,2 @@
1
+ import type { PsScrollRestorationOptions } from '../models/ps-scroll-restoration-options';
2
+ export declare const usePsScrollRestoration: ({ elementRef, preventScrollReset, resetKey, restoreKey, }: PsScrollRestorationOptions) => void;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePsScrollRestoration = void 0;
4
+ const react_1 = require("react");
5
+ const ps_scroll_restore_service_1 = require("../services/ps-scroll-restore-service");
6
+ const ps_scroll_storage_service_1 = require("../services/ps-scroll-storage-service");
7
+ const ps_scroll_target_service_1 = require("../services/ps-scroll-target-service");
8
+ const use_ps_browser_layout_effect_1 = require("./use-ps-browser-layout-effect");
9
+ const usePsScrollRestoration = ({ elementRef, preventScrollReset, resetKey, restoreKey, }) => {
10
+ const keyRef = (0, react_1.useRef)(restoreKey);
11
+ const hasSavedRef = (0, react_1.useRef)(false);
12
+ const appliedKeyRef = (0, react_1.useRef)(undefined);
13
+ const appliedResetKeyRef = (0, react_1.useRef)(undefined);
14
+ const isRestoringRef = (0, react_1.useRef)(false);
15
+ const pendingRef = (0, react_1.useRef)(null);
16
+ const isEnabled = restoreKey !== undefined;
17
+ (0, react_1.useEffect)(() => {
18
+ if (!isEnabled ||
19
+ typeof window === 'undefined' ||
20
+ typeof history === 'undefined' ||
21
+ !('scrollRestoration' in history))
22
+ return;
23
+ const previous = history.scrollRestoration;
24
+ history.scrollRestoration = 'manual';
25
+ return () => {
26
+ history.scrollRestoration = previous;
27
+ };
28
+ }, [isEnabled]);
29
+ (0, use_ps_browser_layout_effect_1.usePsBrowserLayoutEffect)(() => {
30
+ keyRef.current = restoreKey;
31
+ if (typeof window === 'undefined')
32
+ return;
33
+ ps_scroll_storage_service_1.PsScrollStorageService.flush();
34
+ if (restoreKey === undefined)
35
+ return;
36
+ const element = elementRef === undefined ? null : elementRef.current;
37
+ const saved = ps_scroll_storage_service_1.PsScrollStorageService.read(ps_scroll_target_service_1.PsScrollTargetService.storageKey(element, restoreKey));
38
+ hasSavedRef.current = saved !== undefined;
39
+ if (saved === undefined)
40
+ return;
41
+ isRestoringRef.current = true;
42
+ const stop = ps_scroll_restore_service_1.PsScrollRestoreService.start(element, saved, () => {
43
+ isRestoringRef.current = false;
44
+ });
45
+ return () => {
46
+ stop();
47
+ isRestoringRef.current = false;
48
+ };
49
+ }, [restoreKey, elementRef]);
50
+ (0, use_ps_browser_layout_effect_1.usePsBrowserLayoutEffect)(() => {
51
+ const previousKey = appliedKeyRef.current;
52
+ const previousResetKey = appliedResetKeyRef.current;
53
+ appliedKeyRef.current = restoreKey;
54
+ appliedResetKeyRef.current = resetKey;
55
+ if (restoreKey === undefined || typeof window === 'undefined')
56
+ return;
57
+ const hasChanged = previousResetKey !== undefined && previousResetKey !== resetKey;
58
+ const isRestored = previousKey !== restoreKey && hasSavedRef.current;
59
+ if (!hasChanged || isRestored || preventScrollReset === true)
60
+ return;
61
+ ps_scroll_target_service_1.PsScrollTargetService.scrollTo(elementRef === undefined ? null : elementRef.current, 0);
62
+ }, [resetKey, restoreKey, elementRef, preventScrollReset]);
63
+ (0, react_1.useEffect)(() => {
64
+ if (!isEnabled || typeof window === 'undefined')
65
+ return;
66
+ const element = elementRef === undefined ? null : elementRef.current;
67
+ const target = ps_scroll_target_service_1.PsScrollTargetService.eventTarget(element);
68
+ let frame = 0;
69
+ const flushPending = () => {
70
+ const pending = pendingRef.current;
71
+ pendingRef.current = null;
72
+ if (pending !== null)
73
+ ps_scroll_storage_service_1.PsScrollStorageService.write(pending.key, pending.top);
74
+ };
75
+ const onScroll = () => {
76
+ const key = keyRef.current;
77
+ if (key === undefined || isRestoringRef.current)
78
+ return;
79
+ pendingRef.current = {
80
+ key: ps_scroll_target_service_1.PsScrollTargetService.storageKey(element, key),
81
+ top: ps_scroll_target_service_1.PsScrollTargetService.top(element),
82
+ };
83
+ if (frame !== 0)
84
+ return;
85
+ frame = window.requestAnimationFrame(() => {
86
+ frame = 0;
87
+ flushPending();
88
+ });
89
+ };
90
+ const onPageHide = () => {
91
+ const key = keyRef.current;
92
+ pendingRef.current = null;
93
+ if (key !== undefined && !isRestoringRef.current)
94
+ ps_scroll_storage_service_1.PsScrollStorageService.write(ps_scroll_target_service_1.PsScrollTargetService.storageKey(element, key), ps_scroll_target_service_1.PsScrollTargetService.top(element));
95
+ ps_scroll_storage_service_1.PsScrollStorageService.flush();
96
+ };
97
+ target.addEventListener('scroll', onScroll, { passive: true });
98
+ window.addEventListener('pagehide', onPageHide);
99
+ return () => {
100
+ target.removeEventListener('scroll', onScroll);
101
+ window.removeEventListener('pagehide', onPageHide);
102
+ window.cancelAnimationFrame(frame);
103
+ flushPending();
104
+ };
105
+ }, [isEnabled, elementRef]);
106
+ };
107
+ exports.usePsScrollRestoration = usePsScrollRestoration;
package/dist/index.d.ts CHANGED
@@ -59,6 +59,7 @@ export * from './components/ps-skeleton';
59
59
  export * from './services/ps-scroll-lock-service';
60
60
  export * from './services/ps-skeleton-class-service';
61
61
  export * from './models/ps-skeleton-size';
62
+ export * from './models/ps-skeleton-table-row';
62
63
  export * from './constants/ps-skeleton-shape';
63
64
  export * from './components/ps-skeleton-card';
64
65
  export * from './components/ps-skeleton-group';
@@ -192,3 +193,27 @@ export * from './components/ps-divider';
192
193
  export * from './models/ps-divider-orientation';
193
194
  export * from './components/ps-rating-display';
194
195
  export * from './constants/ps-rating-display-size';
196
+ export * from './constants/ps-scroll-restoration-config';
197
+ export * from './models/ps-scroll-offsets-data';
198
+ export * from './models/ps-scroll-restoration-options';
199
+ export * from './services/ps-scroll-storage-service';
200
+ export * from './services/ps-scroll-target-service';
201
+ export * from './services/ps-scroll-restore-service';
202
+ export * from './hooks/use-ps-scroll-restoration';
203
+ export * from './components/ps-scroll-restoration';
204
+ export * from './hooks/use-ps-browser-layout-effect';
205
+ export * from './models/ps-scroll-pending-save-data';
206
+ export * from './constants/ps-flag-param-value';
207
+ export * from './constants/ps-query-param-config';
208
+ export * from './models/ps-search-params-set-options';
209
+ export * from './models/ps-search-params-setter';
210
+ export * from './models/ps-search-params-state';
211
+ export * from './models/ps-choice-param-data';
212
+ export * from './models/ps-flag-param-data';
213
+ export * from './models/ps-choice-param-options';
214
+ export * from './models/ps-flag-param-options';
215
+ export * from './services/ps-query-param-service';
216
+ export * from './hooks/use-ps-choice-param';
217
+ export * from './hooks/use-ps-flag-param';
218
+ export * from './constants/ps-rerender-config';
219
+ export * from './hooks/use-ps-rerender-at';
package/dist/index.js CHANGED
@@ -75,6 +75,7 @@ __exportStar(require("./components/ps-skeleton"), exports);
75
75
  __exportStar(require("./services/ps-scroll-lock-service"), exports);
76
76
  __exportStar(require("./services/ps-skeleton-class-service"), exports);
77
77
  __exportStar(require("./models/ps-skeleton-size"), exports);
78
+ __exportStar(require("./models/ps-skeleton-table-row"), exports);
78
79
  __exportStar(require("./constants/ps-skeleton-shape"), exports);
79
80
  __exportStar(require("./components/ps-skeleton-card"), exports);
80
81
  __exportStar(require("./components/ps-skeleton-group"), exports);
@@ -208,3 +209,27 @@ __exportStar(require("./components/ps-divider"), exports);
208
209
  __exportStar(require("./models/ps-divider-orientation"), exports);
209
210
  __exportStar(require("./components/ps-rating-display"), exports);
210
211
  __exportStar(require("./constants/ps-rating-display-size"), exports);
212
+ __exportStar(require("./constants/ps-scroll-restoration-config"), exports);
213
+ __exportStar(require("./models/ps-scroll-offsets-data"), exports);
214
+ __exportStar(require("./models/ps-scroll-restoration-options"), exports);
215
+ __exportStar(require("./services/ps-scroll-storage-service"), exports);
216
+ __exportStar(require("./services/ps-scroll-target-service"), exports);
217
+ __exportStar(require("./services/ps-scroll-restore-service"), exports);
218
+ __exportStar(require("./hooks/use-ps-scroll-restoration"), exports);
219
+ __exportStar(require("./components/ps-scroll-restoration"), exports);
220
+ __exportStar(require("./hooks/use-ps-browser-layout-effect"), exports);
221
+ __exportStar(require("./models/ps-scroll-pending-save-data"), exports);
222
+ __exportStar(require("./constants/ps-flag-param-value"), exports);
223
+ __exportStar(require("./constants/ps-query-param-config"), exports);
224
+ __exportStar(require("./models/ps-search-params-set-options"), exports);
225
+ __exportStar(require("./models/ps-search-params-setter"), exports);
226
+ __exportStar(require("./models/ps-search-params-state"), exports);
227
+ __exportStar(require("./models/ps-choice-param-data"), exports);
228
+ __exportStar(require("./models/ps-flag-param-data"), exports);
229
+ __exportStar(require("./models/ps-choice-param-options"), exports);
230
+ __exportStar(require("./models/ps-flag-param-options"), exports);
231
+ __exportStar(require("./services/ps-query-param-service"), exports);
232
+ __exportStar(require("./hooks/use-ps-choice-param"), exports);
233
+ __exportStar(require("./hooks/use-ps-flag-param"), exports);
234
+ __exportStar(require("./constants/ps-rerender-config"), exports);
235
+ __exportStar(require("./hooks/use-ps-rerender-at"), exports);
@@ -0,0 +1,4 @@
1
+ export interface PsChoiceParamData<Value extends string> {
2
+ onChange: (value: Value) => void;
3
+ value: Value;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ export interface PsChoiceParamOptions<Value extends string> {
2
+ fallback: Value;
3
+ name: string;
4
+ options: readonly Value[];
5
+ resetParams?: readonly string[];
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsFlagParamData {
2
+ isOn: boolean;
3
+ onChange: (isOn: boolean) => void;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsFlagParamOptions {
2
+ name: string;
3
+ resetParams?: readonly string[];
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export type PsScrollOffsetsData = Record<string, number>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsScrollPendingSaveData {
2
+ key: string;
3
+ top: number;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ import type { RefObject } from 'react';
2
+ export interface PsScrollRestorationOptions {
3
+ elementRef?: RefObject<HTMLElement | null>;
4
+ preventScrollReset?: boolean;
5
+ resetKey?: string;
6
+ restoreKey?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsSearchParamsSetOptions {
2
+ preventScrollReset?: boolean;
3
+ replace?: boolean;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { PsSearchParamsSetOptions } from './ps-search-params-set-options';
2
+ export type PsSearchParamsSetter = (update: (current: URLSearchParams) => URLSearchParams, options?: PsSearchParamsSetOptions) => void;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { PsSearchParamsSetter } from './ps-search-params-setter';
2
+ export type PsSearchParamsState = readonly [URLSearchParams, PsSearchParamsSetter];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PsSkeletonTableRow {
2
+ depth?: number;
3
+ isSection?: boolean;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export declare class PsQueryParamService {
2
+ static choice<Value extends string>(value: string | null, options: readonly Value[], fallback: Value): Value;
3
+ static withChoice<Value extends string>(params: URLSearchParams, name: string, value: Value, fallback: Value, resetParams?: readonly string[]): URLSearchParams;
4
+ static flag(value: string | null): boolean;
5
+ static withFlag(params: URLSearchParams, name: string, isOn: boolean, resetParams?: readonly string[]): URLSearchParams;
6
+ private static cleared;
7
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsQueryParamService = void 0;
4
+ const ps_flag_param_value_1 = require("../constants/ps-flag-param-value");
5
+ class PsQueryParamService {
6
+ static choice(value, options, fallback) {
7
+ const match = options.find((option) => option === value);
8
+ return match === undefined ? fallback : match;
9
+ }
10
+ static withChoice(params, name, value, fallback, resetParams = []) {
11
+ const next = PsQueryParamService.cleared(params, resetParams);
12
+ if (value === fallback)
13
+ next.delete(name);
14
+ else
15
+ next.set(name, value);
16
+ return next;
17
+ }
18
+ static flag(value) {
19
+ return value === ps_flag_param_value_1.PsFlagParamValue.on;
20
+ }
21
+ static withFlag(params, name, isOn, resetParams = []) {
22
+ const next = PsQueryParamService.cleared(params, resetParams);
23
+ if (isOn)
24
+ next.set(name, ps_flag_param_value_1.PsFlagParamValue.on);
25
+ else
26
+ next.delete(name);
27
+ return next;
28
+ }
29
+ static cleared(params, resetParams) {
30
+ const next = new URLSearchParams(params);
31
+ for (const name of resetParams)
32
+ next.delete(name);
33
+ return next;
34
+ }
35
+ }
36
+ exports.PsQueryParamService = PsQueryParamService;
@@ -0,0 +1,3 @@
1
+ export declare class PsScrollRestoreService {
2
+ static start(element: HTMLElement | null, top: number, onDone: () => void): () => void;
3
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsScrollRestoreService = void 0;
4
+ const ps_scroll_restoration_config_1 = require("../constants/ps-scroll-restoration-config");
5
+ const ps_scroll_target_service_1 = require("./ps-scroll-target-service");
6
+ class PsScrollRestoreService {
7
+ static start(element, top, onDone) {
8
+ let isDone = false;
9
+ let observer = null;
10
+ let mutations = null;
11
+ let timer = 0;
12
+ const finish = () => {
13
+ if (isDone)
14
+ return;
15
+ isDone = true;
16
+ window.clearTimeout(timer);
17
+ observer?.disconnect();
18
+ mutations?.disconnect();
19
+ for (const name of ps_scroll_restoration_config_1.PsScrollRestorationConfig.inputEvents)
20
+ window.removeEventListener(name, onInput, true);
21
+ onDone();
22
+ };
23
+ const onInput = () => finish();
24
+ const attempt = () => {
25
+ if (isDone)
26
+ return;
27
+ if (ps_scroll_target_service_1.PsScrollTargetService.maxTop(element) >= top - ps_scroll_restoration_config_1.PsScrollRestorationConfig.tolerancePx) {
28
+ ps_scroll_target_service_1.PsScrollTargetService.scrollTo(element, top);
29
+ finish();
30
+ }
31
+ };
32
+ for (const name of ps_scroll_restoration_config_1.PsScrollRestorationConfig.inputEvents)
33
+ window.addEventListener(name, onInput, { capture: true, passive: true });
34
+ timer = window.setTimeout(() => {
35
+ if (isDone)
36
+ return;
37
+ ps_scroll_target_service_1.PsScrollTargetService.scrollTo(element, top);
38
+ finish();
39
+ }, ps_scroll_restoration_config_1.PsScrollRestorationConfig.restoreTimeoutMs);
40
+ attempt();
41
+ if (!isDone && typeof MutationObserver !== 'undefined') {
42
+ mutations = new MutationObserver(attempt);
43
+ mutations.observe(element === null ? document.body : element, {
44
+ childList: true,
45
+ subtree: true,
46
+ });
47
+ }
48
+ if (!isDone && typeof ResizeObserver !== 'undefined') {
49
+ observer = new ResizeObserver(attempt);
50
+ for (const node of ps_scroll_target_service_1.PsScrollTargetService.observed(element))
51
+ observer.observe(node);
52
+ }
53
+ return finish;
54
+ }
55
+ }
56
+ exports.PsScrollRestoreService = PsScrollRestoreService;
@@ -0,0 +1,11 @@
1
+ export declare class PsScrollStorageService {
2
+ private static offsets;
3
+ private static timer;
4
+ static read(key: string): number | undefined;
5
+ static write(key: string, top: number): void;
6
+ static flush(): void;
7
+ static reset(): void;
8
+ private static memory;
9
+ private static load;
10
+ private static isOffsets;
11
+ }