@design-edito/tools 0.5.2 → 0.5.3
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/agnostic/html/deep-select/index.js +5 -3
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +8 -8
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +8 -8
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +2 -2
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +2 -2
- package/agnostic/html/index.d.ts +1 -1
- package/agnostic/html/index.js +1 -1
- package/agnostic/misc/index.d.ts +3 -3
- package/agnostic/misc/index.js +3 -3
- package/agnostic/numbers/index.d.ts +1 -1
- package/agnostic/numbers/index.js +1 -1
- package/agnostic/optim/index.d.ts +1 -1
- package/agnostic/optim/index.js +1 -1
- package/agnostic/strings/index.d.ts +1 -1
- package/agnostic/strings/index.js +1 -1
- package/agnostic/time/dates/format-date/index.d.ts +4 -2
- package/agnostic/time/dates/format-date/index.js +43 -94
- package/agnostic/time/dates/format-date/index.test.js +154 -0
- package/agnostic/time/dates/format-date/parts.d.ts +28 -0
- package/agnostic/time/dates/format-date/parts.js +136 -0
- package/agnostic/time/dates/format-date/types.d.ts +84 -0
- package/agnostic/time/dates/format-date/types.js +1 -0
- package/agnostic/time/duration/format-duration/index.d.ts +42 -0
- package/agnostic/time/duration/format-duration/index.js +94 -0
- package/agnostic/time/duration/format-duration/index.test.d.ts +1 -0
- package/agnostic/time/duration/format-duration/index.test.js +148 -0
- package/agnostic/time/duration/format-duration/parts.d.ts +32 -0
- package/agnostic/time/duration/format-duration/parts.js +107 -0
- package/agnostic/time/duration/format-duration/types.d.ts +93 -0
- package/agnostic/time/duration/format-duration/types.js +1 -0
- package/agnostic/time/duration/index.d.ts +6 -1
- package/agnostic/time/duration/index.js +2 -2
- package/agnostic/time/duration/index.test.d.ts +1 -0
- package/agnostic/time/duration/index.test.js +168 -0
- package/agnostic/time/index.d.ts +1 -1
- package/agnostic/time/index.js +1 -1
- package/components/BeforeAfter/index.controlled.d.ts +25 -25
- package/components/BeforeAfter/index.controlled.js +47 -53
- package/components/BeforeAfter/index.d.ts +20 -23
- package/components/BeforeAfter/index.js +48 -40
- package/components/Button/index.js +1 -1
- package/components/Clippable/index.d.ts +17 -26
- package/components/Clippable/index.js +21 -23
- package/components/Disclaimer/index.d.ts +29 -22
- package/components/Disclaimer/index.js +29 -24
- package/components/Drawer/index.d.ts +45 -25
- package/components/Drawer/index.js +61 -52
- package/components/EventListener/index.d.ts +4 -5
- package/components/Gallery/index.d.ts +14 -16
- package/components/Gallery/index.js +25 -30
- package/components/Iframe/index.js +2 -2
- package/components/Image/index.d.ts +5 -12
- package/components/Image/index.js +11 -32
- package/components/Input/index.d.ts +23 -19
- package/components/Input/index.js +30 -20
- package/components/JsonEditor/index.d.ts +177 -9
- package/components/JsonEditor/index.js +133 -77
- package/components/JsonEditor/types.d.ts +11 -0
- package/components/JsonEditor/types.js +1 -0
- package/components/JsonEditor/utils.d.ts +8 -0
- package/components/JsonEditor/utils.js +23 -0
- package/components/ListLoader/index.controlled.d.ts +5 -5
- package/components/ListLoader/index.controlled.js +4 -4
- package/components/ListLoader/index.d.ts +11 -11
- package/components/ListLoader/index.js +12 -12
- package/components/Overlayer/index.js +4 -4
- package/components/Paginator/index.d.ts +7 -12
- package/components/Paginator/index.js +7 -11
- package/components/ResizeObserver/index.d.ts +14 -3
- package/components/ResizeObserver/index.js +49 -24
- package/components/Scrllgngn/index.d.ts +17 -13
- package/components/Scrllgngn/index.js +25 -84
- package/components/Scrllgngn/utils.d.ts +52 -0
- package/components/Scrllgngn/utils.js +102 -0
- package/components/ScrollListener/index.d.ts +43 -28
- package/components/ScrollListener/index.js +59 -79
- package/components/ScrollListener/utils.d.ts +37 -16
- package/components/ScrollListener/utils.js +141 -28
- package/components/Select/index.d.ts +24 -20
- package/components/Select/index.js +30 -20
- package/components/Sequencer/index.controlled.d.ts +16 -26
- package/components/Sequencer/index.controlled.js +15 -12
- package/components/Sequencer/index.d.ts +25 -30
- package/components/Sequencer/index.js +20 -34
- package/components/Subtitles/index.d.ts +29 -5
- package/components/Subtitles/index.js +90 -12
- package/components/Textarea/index.d.ts +26 -20
- package/components/Textarea/index.js +40 -21
- package/components/Theatre/index.d.ts +35 -39
- package/components/Theatre/index.js +46 -58
- package/components/UIModule/index.d.ts +25 -29
- package/components/UIModule/index.js +81 -110
- package/components/Video/index.controlled.d.ts +51 -51
- package/components/Video/index.controlled.js +75 -72
- package/components/Video/index.d.ts +12 -14
- package/components/Video/index.js +41 -86
- package/components/Video/utils.d.ts +35 -3
- package/components/Video/utils.js +37 -14
- package/components/index.d.ts +1 -1
- package/components/index.js +1 -1
- package/components/utils/index.d.ts +22 -0
- package/components/utils/index.js +31 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/node/@aws-s3/storage/file/index.d.ts +1 -1
- package/node/@aws-s3/storage/file/index.js +1 -1
- package/node/@google-cloud/storage/index.d.ts +1 -1
- package/node/@google-cloud/storage/index.js +1 -1
- package/node/images/index.d.ts +1 -1
- package/node/images/index.js +1 -1
- package/node/images/transform/operations/index.d.ts +1 -1
- package/node/images/transform/operations/index.js +1 -1
- package/node/index.d.ts +1 -1
- package/node/index.js +1 -1
- package/package.json +20 -5
- package/TODO.md +0 -269
- package/components/BeforeAfter/utils.d.ts +0 -4
- package/components/BeforeAfter/utils.js +0 -9
- package/components/Input/index.controlled.d.ts +0 -42
- package/components/Input/index.controlled.js +0 -54
- package/components/Select/index.controlled.d.ts +0 -43
- package/components/Select/index.controlled.js +0 -54
- package/components/Subtitles/types.d.ts +0 -24
- package/components/Subtitles/utils.d.ts +0 -32
- package/components/Subtitles/utils.js +0 -107
- package/components/Textarea/index.controlled.d.ts +0 -50
- package/components/Textarea/index.controlled.js +0 -75
- /package/{components/Subtitles/types.js → agnostic/time/dates/format-date/index.test.d.ts} +0 -0
- /package/components/ResizeObserver/{style.module.css → styles.module.css} +0 -0
|
@@ -22,12 +22,12 @@ import { type Props as ControlledProps } from './index.controlled.js';
|
|
|
22
22
|
* from the DOM. Applies to load-button activations only, never to retries or
|
|
23
23
|
* stale reloads. Ignored when `pages` is provided.
|
|
24
24
|
* @property fetch - Fetches one page's items. Rejections are reported through
|
|
25
|
-
* `
|
|
25
|
+
* `onPageFetchFailed` and retried according to `fetchRetriesNb`.
|
|
26
26
|
* @property staleAfterMs - Delay after which a loaded page is refetched, counted
|
|
27
27
|
* from its own last successful load. When omitted, pages are never refreshed.
|
|
28
|
-
* @property
|
|
28
|
+
* @property onPageFetched - Called after a page's items have been stored. Not
|
|
29
29
|
* called for a page dropped while its request was in flight.
|
|
30
|
-
* @property
|
|
30
|
+
* @property onPageFetchFailed - Called on every failed attempt, not only once retries
|
|
31
31
|
* are exhausted. When omitted, failures are logged with `console.warn`.
|
|
32
32
|
* @property fetchRetriesNb - Number of retries after a failed fetch. Defaults to
|
|
33
33
|
* `Infinity`, so a page keeps retrying until it succeeds.
|
|
@@ -40,30 +40,30 @@ export type Props<T> = Omit<ControlledProps<T>, 'itemsPages' | 'loadingPages' |
|
|
|
40
40
|
dropPagesFurtherThan?: number;
|
|
41
41
|
fetch: (page: number) => Promise<T[]>;
|
|
42
42
|
staleAfterMs?: number;
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
onPageFetched?: (pagePos: number, items: T[]) => void;
|
|
44
|
+
onPageFetchFailed?: (pagePos: number, error: Error) => void;
|
|
45
45
|
fetchRetriesNb?: number;
|
|
46
46
|
fetchRetriesDelayMs?: number;
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
49
|
* Paginated list abstraction. Fetches the pages it is asked for, keeps them
|
|
50
|
-
* fresh, and drives a {@link
|
|
50
|
+
* fresh, and drives a {@link ControlledListLoader} with the result.
|
|
51
51
|
*
|
|
52
52
|
* @param props - Component properties.
|
|
53
53
|
* @see {@link Props}
|
|
54
|
-
* @see {@link
|
|
55
|
-
* @returns A {@link
|
|
54
|
+
* @see {@link ControlledListLoader} for the rendered markup and CSS elements.
|
|
55
|
+
* @returns A {@link ControlledListLoader} fed with the loaded pages.
|
|
56
56
|
*
|
|
57
57
|
* @remarks
|
|
58
58
|
* - In controlled mode (`pages` defined), the page set is entirely driven by the
|
|
59
59
|
* parent. `fillGaps` and `dropPagesFurtherThan` are inert, and load buttons only
|
|
60
|
-
* report through `
|
|
60
|
+
* report through `onLoadPageClicked`.
|
|
61
61
|
* - In uncontrolled mode, internal state is initialized from `defaultPage` and load
|
|
62
|
-
* buttons extend the set themselves. `
|
|
62
|
+
* buttons extend the set themselves. `onLoadPageClicked` still fires, after the
|
|
63
63
|
* internal state has been updated.
|
|
64
64
|
* - A page removed from the effective set is dropped from memory, and a request
|
|
65
65
|
* still in flight for it is discarded on arrival rather than re-inserted.
|
|
66
66
|
* - No page outside `firstPagePos`–`lastPagePos` is ever fetched, whichever mode
|
|
67
67
|
* is in use.
|
|
68
68
|
*/
|
|
69
|
-
export declare const ListLoader: <T>({ className, pages, defaultPage, fillGaps, dropPagesFurtherThan, autoLoadPrevWhenVisible, autoLoadNextWhenVisible, firstPagePos, lastPagePos, fetch, filter, display, getIdentifier,
|
|
69
|
+
export declare const ListLoader: <T>({ className, pages, defaultPage, fillGaps, dropPagesFurtherThan, autoLoadPrevWhenVisible, autoLoadNextWhenVisible, firstPagePos, lastPagePos, fetch, filter, display, getIdentifier, onLoadPageClicked, staleAfterMs, onPageFetched, onPageFetchFailed, fetchRetriesNb, fetchRetriesDelayMs }: Props<T>) => ReactNode;
|
|
@@ -2,30 +2,30 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { toError } from '../../agnostic/misc/cast/index.js';
|
|
4
4
|
import { clamp } from '../../agnostic/numbers/clamp/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { ControlledListLoader } from './index.controlled.js';
|
|
6
6
|
import { rangeBetween } from './utils.js';
|
|
7
7
|
/**
|
|
8
8
|
* Paginated list abstraction. Fetches the pages it is asked for, keeps them
|
|
9
|
-
* fresh, and drives a {@link
|
|
9
|
+
* fresh, and drives a {@link ControlledListLoader} with the result.
|
|
10
10
|
*
|
|
11
11
|
* @param props - Component properties.
|
|
12
12
|
* @see {@link Props}
|
|
13
|
-
* @see {@link
|
|
14
|
-
* @returns A {@link
|
|
13
|
+
* @see {@link ControlledListLoader} for the rendered markup and CSS elements.
|
|
14
|
+
* @returns A {@link ControlledListLoader} fed with the loaded pages.
|
|
15
15
|
*
|
|
16
16
|
* @remarks
|
|
17
17
|
* - In controlled mode (`pages` defined), the page set is entirely driven by the
|
|
18
18
|
* parent. `fillGaps` and `dropPagesFurtherThan` are inert, and load buttons only
|
|
19
|
-
* report through `
|
|
19
|
+
* report through `onLoadPageClicked`.
|
|
20
20
|
* - In uncontrolled mode, internal state is initialized from `defaultPage` and load
|
|
21
|
-
* buttons extend the set themselves. `
|
|
21
|
+
* buttons extend the set themselves. `onLoadPageClicked` still fires, after the
|
|
22
22
|
* internal state has been updated.
|
|
23
23
|
* - A page removed from the effective set is dropped from memory, and a request
|
|
24
24
|
* still in flight for it is discarded on arrival rather than re-inserted.
|
|
25
25
|
* - No page outside `firstPagePos`–`lastPagePos` is ever fetched, whichever mode
|
|
26
26
|
* is in use.
|
|
27
27
|
*/
|
|
28
|
-
export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dropPagesFurtherThan, autoLoadPrevWhenVisible, autoLoadNextWhenVisible, firstPagePos, lastPagePos, fetch, filter, display, getIdentifier,
|
|
28
|
+
export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dropPagesFurtherThan, autoLoadPrevWhenVisible, autoLoadNextWhenVisible, firstPagePos, lastPagePos, fetch, filter, display, getIdentifier, onLoadPageClicked, staleAfterMs, onPageFetched, onPageFetchFailed, fetchRetriesNb = Infinity, fetchRetriesDelayMs = 1000 }) => {
|
|
29
29
|
const [itemsPages, setItemsPages] = useState(new Map());
|
|
30
30
|
const [loadingPages, setLoadingPages] = useState(new Set());
|
|
31
31
|
const [internalPages, setInternalPages] = useState([
|
|
@@ -45,7 +45,7 @@ export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dro
|
|
|
45
45
|
return kept.length === next.length ? next : kept;
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
onLoadPageClicked?.(pagePos);
|
|
49
49
|
};
|
|
50
50
|
const storePage = (page, items) => setItemsPages(curr => {
|
|
51
51
|
const next = new Map(curr);
|
|
@@ -62,8 +62,8 @@ export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dro
|
|
|
62
62
|
});
|
|
63
63
|
const reportFetchError = (page, err) => {
|
|
64
64
|
const error = toError(err);
|
|
65
|
-
if (
|
|
66
|
-
return
|
|
65
|
+
if (onPageFetchFailed !== undefined)
|
|
66
|
+
return onPageFetchFailed(page, error);
|
|
67
67
|
// eslint-disable-next-line no-console
|
|
68
68
|
console.warn(`ListLoader failed to fetch page ${page}`, error);
|
|
69
69
|
};
|
|
@@ -78,7 +78,7 @@ export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dro
|
|
|
78
78
|
if (!requestedPages.current.has(page))
|
|
79
79
|
return;
|
|
80
80
|
storePage(page, items);
|
|
81
|
-
|
|
81
|
+
onPageFetched?.(page, items);
|
|
82
82
|
setPageLoading(page, false);
|
|
83
83
|
})
|
|
84
84
|
.catch((err) => {
|
|
@@ -142,5 +142,5 @@ export const ListLoader = ({ className, pages, defaultPage, fillGaps = true, dro
|
|
|
142
142
|
const controlledItemsPages = new Map(Array
|
|
143
143
|
.from(itemsPages)
|
|
144
144
|
.map(([page, { items }]) => [page, items]));
|
|
145
|
-
return _jsx(
|
|
145
|
+
return _jsx(ControlledListLoader, { className: className, pages: currentPages, firstPagePos: firstPagePos, lastPagePos: lastPagePos, itemsPages: controlledItemsPages, filter: filter, display: display, getIdentifier: getIdentifier, loadingPages: Array.from(loadingPages), onLoadPageClicked: handleLoadClick, autoLoadPrevWhenVisible: autoLoadPrevWhenVisible, autoLoadNextWhenVisible: autoLoadNextWhenVisible });
|
|
146
146
|
};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
3
3
|
import { isFalsy } from '../../agnostic/booleans/is-falsy/index.js';
|
|
4
4
|
import { mergeClassNames } from '../utils/index.js';
|
|
5
|
-
import { overlayer as
|
|
5
|
+
import { overlayer as publicClassName } from '../public-classnames.js';
|
|
6
6
|
import cssModule from './styles.module.css';
|
|
7
7
|
/**
|
|
8
8
|
* Absolute positioning overlay component. Renders a base content layer and
|
|
@@ -27,10 +27,10 @@ import cssModule from './styles.module.css';
|
|
|
27
27
|
* @returns A root `<div>` containing the base layer and all positioned overlay elements.
|
|
28
28
|
*/
|
|
29
29
|
export const Overlayer = ({ overlays, children, className }) => {
|
|
30
|
-
const c = clss(
|
|
30
|
+
const c = clss(publicClassName, { cssModule });
|
|
31
31
|
const rootClss = mergeClassNames(c(), className);
|
|
32
32
|
const baseClss = c('base');
|
|
33
|
-
return _jsxs("div", { className: rootClss, children: [_jsx("div", { className: baseClss, children: children }), overlays?.map(({ content, xPercent = 0, yPercent = 0, justify }) => {
|
|
33
|
+
return _jsxs("div", { className: rootClss, children: [_jsx("div", { className: baseClss, children: children }), overlays?.map(({ content, xPercent = 0, yPercent = 0, justify }, overlayPos) => {
|
|
34
34
|
const overlayClss = c('overlay');
|
|
35
35
|
let computedTranslateX;
|
|
36
36
|
if (typeof justify === 'number') {
|
|
@@ -55,6 +55,6 @@ export const Overlayer = ({ overlays, children, className }) => {
|
|
|
55
55
|
};
|
|
56
56
|
if (isFalsy(content))
|
|
57
57
|
return null;
|
|
58
|
-
return _jsx("div", { className: overlayClss, style: overlayCustomProps, children: content });
|
|
58
|
+
return _jsx("div", { className: overlayClss, style: overlayCustomProps, children: content }, overlayPos);
|
|
59
59
|
})] });
|
|
60
60
|
};
|
|
@@ -27,23 +27,18 @@ type DirectionState = 'forwards' | 'backwards' | null;
|
|
|
27
27
|
* the {@link IntersectionObserver} root margin. Determines how far into the viewport
|
|
28
28
|
* a page must be before it is considered `'curr'`. Defaults to `0`.
|
|
29
29
|
*
|
|
30
|
-
* @property
|
|
31
|
-
* @
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @property stateHandlers.pageChanged - Callback invoked whenever any page's {@link PageState}
|
|
36
|
-
* changes. Receives a flat array of all pages' states, ordered by position.
|
|
37
|
-
*
|
|
30
|
+
* @property onDirectionChanged - Called after the scroll direction changed, with
|
|
31
|
+
* the new {@link DirectionState}. Repeated scrolls in the same direction do not
|
|
32
|
+
* trigger it again.
|
|
33
|
+
* @property onPagesChanged - Called after any page's {@link PageState} changed,
|
|
34
|
+
* with a flat array of every page's state, ordered by position.
|
|
38
35
|
* @property className - Optional additional class name(s) applied to the root element.
|
|
39
36
|
* @property children - Each direct child is treated as an individual page slot.
|
|
40
37
|
*/
|
|
41
38
|
export type Props = PropsWithChildren<WithClassName<{
|
|
42
39
|
thresholdOffsetPercent?: number;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
pageChanged?: (pages: PageState[]) => void;
|
|
46
|
-
};
|
|
40
|
+
onDirectionChanged?: (direction: DirectionState) => void;
|
|
41
|
+
onPagesChanged?: (pages: PageState[]) => void;
|
|
47
42
|
}>>;
|
|
48
43
|
/**
|
|
49
44
|
* A scroll-driven pagination component that tracks which child page is currently
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, Children, useState } from 'react';
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import { mergeClassNames } from '../utils/index.js';
|
|
4
|
+
import { mergeClassNames, useChangeDispatch } from '../utils/index.js';
|
|
5
5
|
import { paginator as publicClassName } from '../public-classnames.js';
|
|
6
6
|
import cssModule from './styles.module.css';
|
|
7
7
|
/**
|
|
@@ -27,21 +27,17 @@ import cssModule from './styles.module.css';
|
|
|
27
27
|
* - `currCount` on each {@link PageState} increments each time a page transitions
|
|
28
28
|
* into the `'curr'` position, making it useful as a re-entry counter.
|
|
29
29
|
*/
|
|
30
|
-
export const Paginator = ({ thresholdOffsetPercent,
|
|
30
|
+
export const Paginator = ({ thresholdOffsetPercent, onDirectionChanged, onPagesChanged, className, children }) => {
|
|
31
31
|
// State, refs, effects
|
|
32
32
|
const [pagesState, setPagesState] = useState(new Map());
|
|
33
33
|
const [directionState, setDirectionState] = useState(null);
|
|
34
34
|
const pagesRef = useRef(null);
|
|
35
35
|
const directionRef = useRef(null);
|
|
36
|
-
// State
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}, [pagesState]);
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
stateHandlers?.directionChanged?.(directionState);
|
|
44
|
-
}, [directionState]);
|
|
36
|
+
// State dispatch
|
|
37
|
+
useChangeDispatch(pagesState, pages => onPagesChanged?.(Array
|
|
38
|
+
.from(pages)
|
|
39
|
+
.map(([, pageState]) => pageState)));
|
|
40
|
+
useChangeDispatch(directionState, onDirectionChanged);
|
|
45
41
|
// Catch scroll direction listening on scroll events
|
|
46
42
|
useEffect(() => {
|
|
47
43
|
let lastCall = 0;
|
|
@@ -16,9 +16,20 @@ export type Props = PropsWithChildren<WithClassName<{
|
|
|
16
16
|
onResized?: (entry: ROEntryWithBoundingRect) => void;
|
|
17
17
|
}>>;
|
|
18
18
|
/**
|
|
19
|
-
* Component that observes its own size changes and exposes the
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Component that observes its own size changes and exposes the measured content
|
|
20
|
+
* rect on its root element. Both sets stay absent until the first measurement
|
|
21
|
+
* lands.
|
|
22
|
+
*
|
|
23
|
+
* ### Data attributes
|
|
24
|
+
* `data-x`, `data-y`, `data-top`, `data-left`, `data-bottom`, `data-right`,
|
|
25
|
+
* `data-width` and `data-height` — the content rect, as plain numbers.
|
|
26
|
+
*
|
|
27
|
+
* ### CSS custom properties
|
|
28
|
+
* The same eight measurements, each exposed twice: `--lm-resize-observer-width`
|
|
29
|
+
* carries the ready-to-use `px` length, `--lm-resize-observer-width-raw` the
|
|
30
|
+
* plain number for `calc()`. Same pattern for `-x`, `-y`, `-top`, `-left`,
|
|
31
|
+
* `-bottom`, `-right` and `-height`.
|
|
32
|
+
*
|
|
22
33
|
* @param props - Component properties
|
|
23
34
|
* @see {@link Props}
|
|
24
35
|
* @returns A div wrapping `children`, with resize observation applied.
|
|
@@ -3,11 +3,22 @@ import { useRef, useEffect, useState } from 'react';
|
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
4
|
import { mergeClassNames } from '../utils/index.js';
|
|
5
5
|
import { resizeObserver as publicClassName } from '../public-classnames.js';
|
|
6
|
-
import cssModule from './
|
|
6
|
+
import cssModule from './styles.module.css';
|
|
7
7
|
/**
|
|
8
|
-
* Component that observes its own size changes and exposes the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Component that observes its own size changes and exposes the measured content
|
|
9
|
+
* rect on its root element. Both sets stay absent until the first measurement
|
|
10
|
+
* lands.
|
|
11
|
+
*
|
|
12
|
+
* ### Data attributes
|
|
13
|
+
* `data-x`, `data-y`, `data-top`, `data-left`, `data-bottom`, `data-right`,
|
|
14
|
+
* `data-width` and `data-height` — the content rect, as plain numbers.
|
|
15
|
+
*
|
|
16
|
+
* ### CSS custom properties
|
|
17
|
+
* The same eight measurements, each exposed twice: `--lm-resize-observer-width`
|
|
18
|
+
* carries the ready-to-use `px` length, `--lm-resize-observer-width-raw` the
|
|
19
|
+
* plain number for `calc()`. Same pattern for `-x`, `-y`, `-top`, `-left`,
|
|
20
|
+
* `-bottom`, `-right` and `-height`.
|
|
21
|
+
*
|
|
11
22
|
* @param props - Component properties
|
|
12
23
|
* @see {@link Props}
|
|
13
24
|
* @returns A div wrapping `children`, with resize observation applied.
|
|
@@ -43,27 +54,41 @@ export const ResizeObserverComponent = ({ className, onResized, children }) => {
|
|
|
43
54
|
return () => observerRef.current?.disconnect();
|
|
44
55
|
}, [onResized]);
|
|
45
56
|
// Data attributes, CSS custom props & Rendering
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
...acc,
|
|
62
|
-
[`--${publicClassName}-${key}`]: val.toString(),
|
|
63
|
-
[`--${publicClassName}-${key}-px`]: `${val.toString()}px`
|
|
57
|
+
const contentRect = roEntry?.entry.contentRect;
|
|
58
|
+
let dataAttributes = {};
|
|
59
|
+
let cssCustomProps = {};
|
|
60
|
+
if (contentRect !== undefined) {
|
|
61
|
+
const { x, y, top, left, bottom, right, width, height } = contentRect;
|
|
62
|
+
dataAttributes = {
|
|
63
|
+
'data-x': `${x}`,
|
|
64
|
+
'data-y': `${y}`,
|
|
65
|
+
'data-top': `${top}`,
|
|
66
|
+
'data-left': `${left}`,
|
|
67
|
+
'data-bottom': `${bottom}`,
|
|
68
|
+
'data-right': `${right}`,
|
|
69
|
+
'data-width': `${width}`,
|
|
70
|
+
'data-height': `${height}`
|
|
64
71
|
};
|
|
65
|
-
|
|
72
|
+
cssCustomProps = {
|
|
73
|
+
'--lm-resize-observer-x': `${x}px`,
|
|
74
|
+
'--lm-resize-observer-x-raw': `${x}`,
|
|
75
|
+
'--lm-resize-observer-y': `${y}px`,
|
|
76
|
+
'--lm-resize-observer-y-raw': `${y}`,
|
|
77
|
+
'--lm-resize-observer-top': `${top}px`,
|
|
78
|
+
'--lm-resize-observer-top-raw': `${top}`,
|
|
79
|
+
'--lm-resize-observer-left': `${left}px`,
|
|
80
|
+
'--lm-resize-observer-left-raw': `${left}`,
|
|
81
|
+
'--lm-resize-observer-bottom': `${bottom}px`,
|
|
82
|
+
'--lm-resize-observer-bottom-raw': `${bottom}`,
|
|
83
|
+
'--lm-resize-observer-right': `${right}px`,
|
|
84
|
+
'--lm-resize-observer-right-raw': `${right}`,
|
|
85
|
+
'--lm-resize-observer-width': `${width}px`,
|
|
86
|
+
'--lm-resize-observer-width-raw': `${width}`,
|
|
87
|
+
'--lm-resize-observer-height': `${height}px`,
|
|
88
|
+
'--lm-resize-observer-height-raw': `${height}`
|
|
89
|
+
};
|
|
90
|
+
}
|
|
66
91
|
const c = clss(publicClassName, { cssModule });
|
|
67
|
-
const rootClss = mergeClassNames(c(
|
|
92
|
+
const rootClss = mergeClassNames(c(), className);
|
|
68
93
|
return _jsx("div", { ...dataAttributes, className: rootClss, ref: rootRef, style: { ...cssCustomProps }, children: children });
|
|
69
94
|
};
|
|
@@ -71,10 +71,8 @@ export type PropsPage = {
|
|
|
71
71
|
* - `'after'` — forces blocks from pages after the current one.
|
|
72
72
|
* - `'both'` — forces blocks on both sides.
|
|
73
73
|
* - `'none'` — no forcing (default behaviour).
|
|
74
|
-
* @property
|
|
75
|
-
*
|
|
76
|
-
* @property stateHandlers.pageChanged - Called whenever the current page
|
|
77
|
-
* changes. Receives the zero-based index of the current page and the
|
|
74
|
+
* @property onPageChanged - Called once the current page has changed, never on
|
|
75
|
+
* mount. Receives the zero-based index of the new current page and the
|
|
78
76
|
* corresponding page definition, if available.
|
|
79
77
|
* @property className - Optional additional class name(s) applied to the root
|
|
80
78
|
* element.
|
|
@@ -84,9 +82,7 @@ export type Props = WithClassName<{
|
|
|
84
82
|
thresholdOffsetPercent?: number;
|
|
85
83
|
stickyBlocksLazyLoadDistance?: number;
|
|
86
84
|
forceStickBlocks?: 'before' | 'after' | 'both' | 'none';
|
|
87
|
-
|
|
88
|
-
pageChanged?: (currentPagePos: number, pageData?: PropsPage) => void;
|
|
89
|
-
};
|
|
85
|
+
onPageChanged?: (currentPagePos: number, pageData?: PropsPage) => void;
|
|
90
86
|
}>;
|
|
91
87
|
/**
|
|
92
88
|
* Scrollytelling engine component. Orchestrates layered sticky blocks (`back`
|
|
@@ -104,16 +100,24 @@ export type Props = WithClassName<{
|
|
|
104
100
|
* - `--force-stick-blocks-both` — when `forceStickBlocks === 'both'`.
|
|
105
101
|
*
|
|
106
102
|
* ### Data attributes
|
|
107
|
-
*
|
|
108
|
-
*
|
|
103
|
+
* Both are updated on every page change reported by the internal
|
|
104
|
+
* {@link Paginator}.
|
|
105
|
+
* - `data-current-page-pos` — zero-based index of the page currently in view.
|
|
106
|
+
* - `data-current-page-id` — that page's {@link PropsPage.id}. Absent while the
|
|
107
|
+
* current page carries no id, since the id is optional.
|
|
109
108
|
*
|
|
110
109
|
* ### CSS custom properties
|
|
111
110
|
* Exposed on the root element and updated on resize via the internal
|
|
112
111
|
* {@link ResizeObserverComponent}:
|
|
113
|
-
* - `--scrllgngn-screen-left` / `--
|
|
114
|
-
*
|
|
115
|
-
* - `--scrllgngn-screen-
|
|
116
|
-
* - `--scrllgngn-screen-
|
|
112
|
+
* - `--lm-scrllgngn-screen-left` / `--lm-scrllgngn-screen-left-raw` — left edge
|
|
113
|
+
* of the bounding rect.
|
|
114
|
+
* - `--lm-scrllgngn-screen-right` / `--lm-scrllgngn-screen-right-raw` — right edge.
|
|
115
|
+
* - `--lm-scrllgngn-screen-width` / `--lm-scrllgngn-screen-width-raw` — total width.
|
|
116
|
+
* - `--lm-scrllgngn-screen-height` / `--lm-scrllgngn-screen-height-raw` — total height.
|
|
117
|
+
*
|
|
118
|
+
* The same four measurements are also exposed as `--PRIVATE-left`, `-right`,
|
|
119
|
+
* `-width` and `-height` for the component's own stylesheet. They are internal:
|
|
120
|
+
* do not read or override them.
|
|
117
121
|
*
|
|
118
122
|
* ### Sticky block elements
|
|
119
123
|
* Each lazy-loaded sticky block receives:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import { randomHash } from '../../agnostic/random/uuid/index.js';
|
|
5
4
|
import { IntersectionObserverComponent } from '../IntersectionObserver/index.js';
|
|
6
5
|
import { Paginator } from '../Paginator/index.js';
|
|
7
6
|
import { ResizeObserverComponent } from '../ResizeObserver/index.js';
|
|
8
|
-
import { mergeClassNames } from '../utils/index.js';
|
|
7
|
+
import { mergeClassNames, useChangeDispatch } from '../utils/index.js';
|
|
9
8
|
import { scrllgngn as publicClassName } from '../public-classnames.js';
|
|
9
|
+
import { consolidateStickyBlocks, lazyLoadedBlocks, toScreenCssProps } from './utils.js';
|
|
10
10
|
import cssModule from './styles.module.css';
|
|
11
11
|
/**
|
|
12
12
|
* Scrollytelling engine component. Orchestrates layered sticky blocks (`back`
|
|
@@ -24,16 +24,24 @@ import cssModule from './styles.module.css';
|
|
|
24
24
|
* - `--force-stick-blocks-both` — when `forceStickBlocks === 'both'`.
|
|
25
25
|
*
|
|
26
26
|
* ### Data attributes
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* Both are updated on every page change reported by the internal
|
|
28
|
+
* {@link Paginator}.
|
|
29
|
+
* - `data-current-page-pos` — zero-based index of the page currently in view.
|
|
30
|
+
* - `data-current-page-id` — that page's {@link PropsPage.id}. Absent while the
|
|
31
|
+
* current page carries no id, since the id is optional.
|
|
29
32
|
*
|
|
30
33
|
* ### CSS custom properties
|
|
31
34
|
* Exposed on the root element and updated on resize via the internal
|
|
32
35
|
* {@link ResizeObserverComponent}:
|
|
33
|
-
* - `--scrllgngn-screen-left` / `--
|
|
34
|
-
*
|
|
35
|
-
* - `--scrllgngn-screen-
|
|
36
|
-
* - `--scrllgngn-screen-
|
|
36
|
+
* - `--lm-scrllgngn-screen-left` / `--lm-scrllgngn-screen-left-raw` — left edge
|
|
37
|
+
* of the bounding rect.
|
|
38
|
+
* - `--lm-scrllgngn-screen-right` / `--lm-scrllgngn-screen-right-raw` — right edge.
|
|
39
|
+
* - `--lm-scrllgngn-screen-width` / `--lm-scrllgngn-screen-width-raw` — total width.
|
|
40
|
+
* - `--lm-scrllgngn-screen-height` / `--lm-scrllgngn-screen-height-raw` — total height.
|
|
41
|
+
*
|
|
42
|
+
* The same four measurements are also exposed as `--PRIVATE-left`, `-right`,
|
|
43
|
+
* `-width` and `-height` for the component's own stylesheet. They are internal:
|
|
44
|
+
* do not read or override them.
|
|
37
45
|
*
|
|
38
46
|
* ### Sticky block elements
|
|
39
47
|
* Each lazy-loaded sticky block receives:
|
|
@@ -48,7 +56,7 @@ import cssModule from './styles.module.css';
|
|
|
48
56
|
* back-blocks layer, front-blocks layer, paginated scrolling content, and
|
|
49
57
|
* bottom-bound sentinel.
|
|
50
58
|
*/
|
|
51
|
-
export const Scrllgngn = ({ pages, thresholdOffsetPercent, stickyBlocksLazyLoadDistance = 2, forceStickBlocks,
|
|
59
|
+
export const Scrllgngn = ({ pages, thresholdOffsetPercent, stickyBlocksLazyLoadDistance = 2, forceStickBlocks, onPageChanged, className }) => {
|
|
52
60
|
// State
|
|
53
61
|
const [topVisible, setTopVis] = useState(false);
|
|
54
62
|
const [contentVisible, setCntVis] = useState(false);
|
|
@@ -58,69 +66,20 @@ export const Scrllgngn = ({ pages, thresholdOffsetPercent, stickyBlocksLazyLoadD
|
|
|
58
66
|
const [partialBoundingRect, setPartialBoundingRect] = useState();
|
|
59
67
|
// Sticky blocks calculations
|
|
60
68
|
useEffect(() => {
|
|
61
|
-
|
|
62
|
-
for (const page of pages ?? []) {
|
|
63
|
-
const pageIndex = pages?.indexOf(page) ?? -1;
|
|
64
|
-
for (const block of page.blocks ?? []) {
|
|
65
|
-
const blockId = block.id ?? randomHash(12);
|
|
66
|
-
const found = consolidatedBlocks.get(blockId);
|
|
67
|
-
if (found !== undefined)
|
|
68
|
-
consolidatedBlocks.set(blockId, {
|
|
69
|
-
...found,
|
|
70
|
-
...block,
|
|
71
|
-
displayOnPages: [
|
|
72
|
-
...found.displayOnPages,
|
|
73
|
-
pageIndex
|
|
74
|
-
]
|
|
75
|
-
});
|
|
76
|
-
else
|
|
77
|
-
consolidatedBlocks.set(blockId, {
|
|
78
|
-
...block,
|
|
79
|
-
displayOnPages: [pageIndex]
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
const consolidatedStickyBlocks = new Map(Array
|
|
84
|
-
.from(consolidatedBlocks)
|
|
85
|
-
.filter((e) => {
|
|
86
|
-
const block = e[1];
|
|
87
|
-
return block.depth === 'back'
|
|
88
|
-
|| block.depth === 'front';
|
|
89
|
-
}));
|
|
90
|
-
setStickyBlocks(consolidatedStickyBlocks);
|
|
69
|
+
setStickyBlocks(consolidateStickyBlocks(pages));
|
|
91
70
|
}, [pages]);
|
|
92
|
-
const lazyLoadedBackBlocks =
|
|
93
|
-
|
|
94
|
-
.filter(([, block]) => block.depth === 'back'
|
|
95
|
-
&& block.displayOnPages.some(dispPage => {
|
|
96
|
-
const absDiff = Math.abs(dispPage - currentPagePos);
|
|
97
|
-
return absDiff <= stickyBlocksLazyLoadDistance;
|
|
98
|
-
})).map(([, block]) => block)
|
|
99
|
-
.sort((a, b) => {
|
|
100
|
-
return (a.zIndex ?? -Infinity) - (b.zIndex ?? -Infinity);
|
|
101
|
-
});
|
|
102
|
-
const lazyLoadedFrontBlocks = Array
|
|
103
|
-
.from(stickyBlocks)
|
|
104
|
-
.filter(([, block]) => block.depth === 'front'
|
|
105
|
-
&& block.displayOnPages.some(dispPage => {
|
|
106
|
-
const absDiff = Math.abs(dispPage - currentPagePos);
|
|
107
|
-
return absDiff <= stickyBlocksLazyLoadDistance;
|
|
108
|
-
})).map(([, block]) => block)
|
|
109
|
-
.sort((a, b) => {
|
|
110
|
-
return (a.zIndex ?? -Infinity) - (b.zIndex ?? -Infinity);
|
|
111
|
-
});
|
|
71
|
+
const lazyLoadedBackBlocks = lazyLoadedBlocks(stickyBlocks, 'back', currentPagePos, stickyBlocksLazyLoadDistance);
|
|
72
|
+
const lazyLoadedFrontBlocks = lazyLoadedBlocks(stickyBlocks, 'front', currentPagePos, stickyBlocksLazyLoadDistance);
|
|
112
73
|
// Handlers
|
|
74
|
+
useChangeDispatch(currentPagePos, pagePos => onPageChanged?.(pagePos, pages?.[pagePos]));
|
|
113
75
|
const handleTopBoundDetect = e => setTopVis(e.ioEntry?.isIntersecting ?? false);
|
|
114
76
|
const handleCntDetect = e => setCntVis(e.ioEntry?.isIntersecting ?? false);
|
|
115
77
|
const handleBtmBoundDetect = e => setBtmVis(e.ioEntry?.isIntersecting ?? false);
|
|
116
|
-
const
|
|
78
|
+
const handlePagesChanged = statePages => {
|
|
117
79
|
const curPagePos = statePages.findIndex(page => page.position === 'curr');
|
|
118
80
|
if (curPagePos === -1)
|
|
119
81
|
return;
|
|
120
|
-
if (curPagePos === currentPagePos)
|
|
121
|
-
return;
|
|
122
82
|
setCurrentPagePos(curPagePos);
|
|
123
|
-
stateHandlers?.pageChanged?.(curPagePos, pages?.[curPagePos]);
|
|
124
83
|
};
|
|
125
84
|
const handleResize = ({ boundingClientRect }) => {
|
|
126
85
|
if (partialBoundingRect === undefined
|
|
@@ -140,24 +99,8 @@ export const Scrllgngn = ({ pages, thresholdOffsetPercent, stickyBlocksLazyLoadD
|
|
|
140
99
|
'force-stick-blocks-after': forceStickBlocks === 'after',
|
|
141
100
|
'force-stick-blocks-both': forceStickBlocks === 'both'
|
|
142
101
|
}), className);
|
|
143
|
-
const customCssProps =
|
|
144
|
-
|
|
145
|
-
customCssProps[`--${publicClassName}-screen-left`] = `${partialBoundingRect.left}px`;
|
|
146
|
-
customCssProps['--PRIVATE-left'] = `${partialBoundingRect.left}px`;
|
|
147
|
-
}
|
|
148
|
-
if (partialBoundingRect?.right !== undefined) {
|
|
149
|
-
customCssProps[`--${publicClassName}-screen-right`] = `${partialBoundingRect.right}px`;
|
|
150
|
-
customCssProps['--PRIVATE-right'] = `${partialBoundingRect.right}px`;
|
|
151
|
-
}
|
|
152
|
-
if (partialBoundingRect?.width !== undefined) {
|
|
153
|
-
customCssProps[`--${publicClassName}-screen-width`] = `${partialBoundingRect.width}px`;
|
|
154
|
-
customCssProps['--PRIVATE-width'] = `${partialBoundingRect.width}px`;
|
|
155
|
-
}
|
|
156
|
-
if (partialBoundingRect?.height !== undefined) {
|
|
157
|
-
customCssProps[`--${publicClassName}-screen-height`] = `${partialBoundingRect.height}px`;
|
|
158
|
-
customCssProps['--PRIVATE-height'] = `${partialBoundingRect.height}px`;
|
|
159
|
-
}
|
|
160
|
-
return _jsx("div", { className: rootClss, "data-current-page-pos": currentPagePos, style: { ...customCssProps }, children: _jsxs(ResizeObserverComponent, { onResized: handleResize, children: [_jsx("div", { className: c('top-bound'), children: _jsx(IntersectionObserverComponent, { onIntersected: handleTopBoundDetect }) }), _jsx("div", { className: c('back-blocks'), children: lazyLoadedBackBlocks.map((block, blockPos) => {
|
|
102
|
+
const customCssProps = toScreenCssProps(partialBoundingRect);
|
|
103
|
+
return _jsx("div", { className: rootClss, "data-current-page-pos": currentPagePos, "data-current-page-id": pages?.[currentPagePos]?.id, style: { ...customCssProps }, children: _jsxs(ResizeObserverComponent, { onResized: handleResize, children: [_jsx("div", { className: c('top-bound'), children: _jsx(IntersectionObserverComponent, { onIntersected: handleTopBoundDetect }) }), _jsx("div", { className: c('back-blocks'), children: lazyLoadedBackBlocks.map((block, blockPos) => {
|
|
161
104
|
const isActive = block.displayOnPages.includes(currentPagePos);
|
|
162
105
|
const blockClss = c('back-block', {
|
|
163
106
|
active: isActive,
|
|
@@ -171,9 +114,7 @@ export const Scrllgngn = ({ pages, thresholdOffsetPercent, stickyBlocksLazyLoadD
|
|
|
171
114
|
'lazy-loaded': !isActive
|
|
172
115
|
});
|
|
173
116
|
return _jsx("div", { className: blockClss, style: { zIndex: blockPos }, children: block.children });
|
|
174
|
-
}) }), _jsx("div", { className: c('scrolling-content'), children: _jsx(IntersectionObserverComponent, { onIntersected: handleCntDetect, children: _jsx(Paginator, { thresholdOffsetPercent: thresholdOffsetPercent,
|
|
175
|
-
pageChanged: handlePageChange
|
|
176
|
-
}, children: pages?.map(page => {
|
|
117
|
+
}) }), _jsx("div", { className: c('scrolling-content'), children: _jsx(IntersectionObserverComponent, { onIntersected: handleCntDetect, children: _jsx(Paginator, { thresholdOffsetPercent: thresholdOffsetPercent, onPagesChanged: handlePagesChanged, children: pages?.map(page => {
|
|
177
118
|
const scrollBlocks = page.blocks
|
|
178
119
|
?.filter(b => b.depth === 'scroll' || b.depth === undefined) ?? [];
|
|
179
120
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { PropsPage, PropsStickyBlock } from './index.js';
|
|
2
|
+
/** The subset of a bounding rect a {@link Scrllgngn} tracks and exposes. */
|
|
3
|
+
export type ScreenRect = {
|
|
4
|
+
left: number;
|
|
5
|
+
right: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
/** Zero-based positions of the pages a consolidated block is displayed on. */
|
|
10
|
+
export type BlockConsolidatedData = {
|
|
11
|
+
displayOnPages: number[];
|
|
12
|
+
};
|
|
13
|
+
/** A sticky block, merged across every page it appears on. */
|
|
14
|
+
export type ConsolidatedStickyBlock = PropsStickyBlock & BlockConsolidatedData;
|
|
15
|
+
/**
|
|
16
|
+
* Merges the sticky blocks of every page into a single entry per block id.
|
|
17
|
+
*
|
|
18
|
+
* A block repeated across pages under the same `id` becomes one sticky block
|
|
19
|
+
* listing all the pages it shows on, so it stays mounted across them instead of
|
|
20
|
+
* being torn down and rebuilt at every page change. Blocks without an `id` get a
|
|
21
|
+
* random one and are therefore never merged.
|
|
22
|
+
*
|
|
23
|
+
* @param pages - The pages to walk, in order.
|
|
24
|
+
* @returns The sticky blocks, keyed by id. Scroll blocks are left out.
|
|
25
|
+
*/
|
|
26
|
+
export declare function consolidateStickyBlocks(pages?: PropsPage[]): Map<string, ConsolidatedStickyBlock>;
|
|
27
|
+
/**
|
|
28
|
+
* Picks the sticky blocks of one layer close enough to the current page to be
|
|
29
|
+
* worth mounting.
|
|
30
|
+
*
|
|
31
|
+
* @param blocks - Every consolidated sticky block.
|
|
32
|
+
* @param depth - The layer to pick from.
|
|
33
|
+
* @param currentPagePos - Zero-based position of the page in view.
|
|
34
|
+
* @param lazyLoadDistance - How many pages around the current one still mount
|
|
35
|
+
* their blocks.
|
|
36
|
+
* @returns The blocks to render, stacked by ascending `zIndex`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function lazyLoadedBlocks(blocks: Map<string, ConsolidatedStickyBlock>, depth: 'back' | 'front', currentPagePos: number, lazyLoadDistance: number): ConsolidatedStickyBlock[];
|
|
39
|
+
/**
|
|
40
|
+
* Builds the CSS custom properties exposed on a {@link Scrllgngn} root.
|
|
41
|
+
*
|
|
42
|
+
* The public `screen-*` set follows the usual convention and stays absent until
|
|
43
|
+
* the first measurement lands. The `--PRIVATE-*` set is what the component's own
|
|
44
|
+
* stylesheet positions its fixed layers with, and it is emitted from the very
|
|
45
|
+
* first render — as `initial`, the guaranteed-invalid value — so those layers can
|
|
46
|
+
* never inherit the same names from an ancestor component. `initial` leaves them
|
|
47
|
+
* behaving exactly as an unset variable would, without opening the hole.
|
|
48
|
+
*
|
|
49
|
+
* @param rect - The measured bounding rect, absent until the first resize lands.
|
|
50
|
+
* @returns The custom properties, keyed by their full name.
|
|
51
|
+
*/
|
|
52
|
+
export declare function toScreenCssProps(rect?: ScreenRect): Record<string, string>;
|