@design-edito/tools 0.5.1 → 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/arrays/index.d.ts +1 -1
- package/agnostic/arrays/index.js +1 -1
- package/agnostic/colors/index.d.ts +1 -1
- package/agnostic/colors/index.js +1 -1
- package/agnostic/css/index.d.ts +1 -1
- package/agnostic/css/index.js +1 -1
- package/agnostic/html/deep-select/index.js +5 -3
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +9 -9
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +9 -9
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +1 -1
- package/agnostic/html/index.d.ts +3 -3
- package/agnostic/html/index.js +3 -3
- package/agnostic/index.d.ts +3 -3
- package/agnostic/index.js +3 -3
- package/agnostic/misc/index.d.ts +1 -1
- package/agnostic/misc/index.js +1 -1
- package/agnostic/misc/logs/index.d.ts +1 -1
- package/agnostic/misc/logs/index.js +1 -1
- package/agnostic/numbers/index.d.ts +3 -3
- package/agnostic/numbers/index.js +3 -3
- package/agnostic/objects/index.d.ts +3 -3
- package/agnostic/objects/index.js +3 -3
- package/agnostic/random/index.d.ts +1 -1
- package/agnostic/random/index.js +1 -1
- package/agnostic/strings/index.d.ts +3 -3
- package/agnostic/strings/index.js +3 -3
- 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/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 -75
- 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 +78 -0
- package/components/ListLoader/index.controlled.js +99 -0
- package/components/ListLoader/index.d.ts +69 -0
- package/components/ListLoader/index.js +146 -0
- package/components/ListLoader/utils.d.ts +8 -0
- package/components/ListLoader/utils.js +10 -0
- 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/ResizeObserver/styles.module.css +0 -0
- 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 +5 -4
- package/components/index.js +5 -4
- package/components/public-classnames.d.ts +1 -0
- package/components/public-classnames.js +1 -0
- package/components/utils/index.d.ts +22 -0
- package/components/utils/index.js +31 -0
- package/node/@google-cloud/storage/directory/index.d.ts +2 -2
- package/node/@google-cloud/storage/directory/index.js +2 -2
- package/node/@google-cloud/storage/file/index.d.ts +2 -2
- package/node/@google-cloud/storage/file/index.js +2 -2
- package/node/@google-cloud/storage/index.d.ts +1 -1
- package/node/@google-cloud/storage/index.js +1 -1
- package/node/cloud-storage/operations/index.d.ts +2 -2
- package/node/cloud-storage/operations/index.js +2 -2
- package/node/ftps/directory/index.d.ts +1 -1
- package/node/ftps/directory/index.js +1 -1
- package/node/ftps/file/index.d.ts +2 -2
- package/node/ftps/file/index.js +2 -2
- package/node/images/index.d.ts +1 -1
- package/node/images/index.js +1 -1
- package/node/images/transform/operations/index.d.ts +3 -3
- package/node/images/transform/operations/index.js +3 -3
- package/node/index.d.ts +2 -2
- package/node/index.js +2 -2
- package/node/process/index.d.ts +1 -1
- package/node/process/index.js +1 -1
- package/node/sftp/directory/index.d.ts +1 -1
- package/node/sftp/directory/index.js +1 -1
- package/node/sftp/file/index.d.ts +1 -1
- package/node/sftp/file/index.js +1 -1
- package/package.json +27 -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 → ListLoader/styles.module.css} +0 -0
|
@@ -1,45 +1,65 @@
|
|
|
1
1
|
import { type PropsWithChildren, type FunctionComponent, type ReactNode } from 'react';
|
|
2
2
|
import type { WithClassName } from '../utils/types.js';
|
|
3
3
|
/**
|
|
4
|
-
* Props for the Drawer component.
|
|
4
|
+
* Props for the {@link Drawer} component.
|
|
5
5
|
*
|
|
6
6
|
* @property openerContent - Content rendered inside the opener control.
|
|
7
7
|
* @property closerContent - Content rendered inside the closer control.
|
|
8
|
-
* @property
|
|
9
|
-
* Ignored when `isOpened` is provided.
|
|
8
|
+
* @property defaultIsOpened - Initial open state in uncontrolled mode.
|
|
9
|
+
* Ignored when `isOpened` is provided. Defaults to `false`.
|
|
10
10
|
* @property isOpened - Controlled open state. When defined, the component
|
|
11
|
-
* behaves as a controlled component and internal state is
|
|
12
|
-
* @property
|
|
13
|
-
*
|
|
11
|
+
* behaves as a controlled component and internal state is never updated.
|
|
12
|
+
* @property onOpenerClicked - Called when the opener is clicked, before the
|
|
13
|
+
* drawer reacts, with the open state as it was.
|
|
14
|
+
* @property onCloserClicked - Called when the closer is clicked, before the
|
|
15
|
+
* drawer reacts, with the open state as it was.
|
|
16
|
+
* @property onIsOpenedChanged - Called after the open state changed, with the
|
|
17
|
+
* new value.
|
|
14
18
|
* @property className - Additional class name(s) applied to the root element.
|
|
15
19
|
* @property children - Drawer content.
|
|
16
20
|
*/
|
|
17
21
|
export type Props = PropsWithChildren<WithClassName<{
|
|
18
22
|
openerContent?: ReactNode;
|
|
19
23
|
closerContent?: ReactNode;
|
|
20
|
-
|
|
24
|
+
defaultIsOpened?: boolean;
|
|
21
25
|
isOpened?: boolean;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
onOpenerClicked?: (isOpened: boolean) => void;
|
|
27
|
+
onCloserClicked?: (isOpened: boolean) => void;
|
|
28
|
+
onIsOpenedChanged?: (isOpened: boolean) => void;
|
|
25
29
|
}>>;
|
|
26
30
|
/**
|
|
27
|
-
* Drawer component
|
|
31
|
+
* Drawer component supporting controlled and uncontrolled usage.
|
|
32
|
+
*
|
|
33
|
+
* The content is measured through a {@link ResizeObserverComponent} so its
|
|
34
|
+
* dimensions can drive the open/close transition from CSS alone.
|
|
35
|
+
*
|
|
36
|
+
* ### CSS modifiers
|
|
37
|
+
* - `opened` — the drawer is open.
|
|
38
|
+
* - `closed` — the drawer is closed.
|
|
39
|
+
*
|
|
40
|
+
* ### CSS elements
|
|
41
|
+
* - `opener`
|
|
42
|
+
* - `closer`
|
|
43
|
+
* - `content`
|
|
44
|
+
*
|
|
45
|
+
* ### CSS custom properties on the root element
|
|
46
|
+
* - `--lm-drawer-content-width` / `--lm-drawer-content-width-raw`
|
|
47
|
+
* - `--lm-drawer-content-height` / `--lm-drawer-content-height-raw`
|
|
48
|
+
* Absent until the first measurement lands.
|
|
49
|
+
*
|
|
50
|
+
* ### Data attributes on the root element
|
|
51
|
+
* - `data-content-width`, `data-content-height` — the measured content size.
|
|
52
|
+
* Absent until the first measurement lands.
|
|
53
|
+
*
|
|
54
|
+
* @param props - Component properties.
|
|
55
|
+
* @see {@link Props}
|
|
56
|
+
* @returns A root `<div>` holding the opener, the closer and the measured content.
|
|
28
57
|
*
|
|
29
58
|
* @remarks
|
|
30
|
-
* - In controlled mode (`isOpened` defined),
|
|
31
|
-
*
|
|
32
|
-
* -
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* --{prefix}-content-height
|
|
36
|
-
* --{prefix}-content-height-px
|
|
37
|
-
* --{prefix}-content-width
|
|
38
|
-
* --{prefix}-content-width-px
|
|
39
|
-
* - As `data-content-width` and `data-content-height` attributes.
|
|
40
|
-
*
|
|
41
|
-
* CSS modifier classes:
|
|
42
|
-
* - `opened` when open
|
|
43
|
-
* - `closed` when closed
|
|
59
|
+
* - In controlled mode (`isOpened` defined), the open state is fully driven by
|
|
60
|
+
* the parent and internal state is never updated.
|
|
61
|
+
* - `onOpenerClicked` and `onCloserClicked` fire in both modes — a controlled
|
|
62
|
+
* parent needs them to know a click happened at all.
|
|
63
|
+
* - `onIsOpenedChanged` fires in both modes too, and never on mount.
|
|
44
64
|
*/
|
|
45
65
|
export declare const Drawer: FunctionComponent<Props>;
|
|
@@ -1,54 +1,67 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ResizeObserverComponent } from '../ResizeObserver/index.js';
|
|
5
|
+
import { mergeClassNames, useChangeDispatch } from '../utils/index.js';
|
|
5
6
|
import { drawer as publicClassName } from '../public-classnames.js';
|
|
6
7
|
import cssModule from './styles.module.css';
|
|
7
|
-
import { ResizeObserverComponent } from '../ResizeObserver/index.js';
|
|
8
8
|
/**
|
|
9
|
-
* Drawer component
|
|
9
|
+
* Drawer component supporting controlled and uncontrolled usage.
|
|
10
10
|
*
|
|
11
|
-
* @
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
11
|
+
* The content is measured through a {@link ResizeObserverComponent} so its
|
|
12
|
+
* dimensions can drive the open/close transition from CSS alone.
|
|
13
|
+
*
|
|
14
|
+
* ### CSS modifiers
|
|
15
|
+
* - `opened` — the drawer is open.
|
|
16
|
+
* - `closed` — the drawer is closed.
|
|
17
|
+
*
|
|
18
|
+
* ### CSS elements
|
|
19
|
+
* - `opener`
|
|
20
|
+
* - `closer`
|
|
21
|
+
* - `content`
|
|
22
|
+
*
|
|
23
|
+
* ### CSS custom properties on the root element
|
|
24
|
+
* - `--lm-drawer-content-width` / `--lm-drawer-content-width-raw`
|
|
25
|
+
* - `--lm-drawer-content-height` / `--lm-drawer-content-height-raw`
|
|
26
|
+
* Absent until the first measurement lands.
|
|
22
27
|
*
|
|
23
|
-
*
|
|
24
|
-
* - `
|
|
25
|
-
*
|
|
28
|
+
* ### Data attributes on the root element
|
|
29
|
+
* - `data-content-width`, `data-content-height` — the measured content size.
|
|
30
|
+
* Absent until the first measurement lands.
|
|
31
|
+
*
|
|
32
|
+
* @param props - Component properties.
|
|
33
|
+
* @see {@link Props}
|
|
34
|
+
* @returns A root `<div>` holding the opener, the closer and the measured content.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* - In controlled mode (`isOpened` defined), the open state is fully driven by
|
|
38
|
+
* the parent and internal state is never updated.
|
|
39
|
+
* - `onOpenerClicked` and `onCloserClicked` fire in both modes — a controlled
|
|
40
|
+
* parent needs them to know a click happened at all.
|
|
41
|
+
* - `onIsOpenedChanged` fires in both modes too, and never on mount.
|
|
26
42
|
*/
|
|
27
|
-
export const Drawer = ({ openerContent, closerContent,
|
|
28
|
-
// State
|
|
29
|
-
const [internalIsOpened, setInternalIsOpened] = useState(
|
|
43
|
+
export const Drawer = ({ openerContent, closerContent, defaultIsOpened = false, isOpened: isOpenedProp, onOpenerClicked, onCloserClicked, onIsOpenedChanged, className, children }) => {
|
|
44
|
+
// State
|
|
45
|
+
const [internalIsOpened, setInternalIsOpened] = useState(defaultIsOpened);
|
|
46
|
+
const [contentDimensions, setContentDimensions] = useState();
|
|
47
|
+
const isControlled = isOpenedProp !== undefined;
|
|
30
48
|
const isOpened = isOpenedProp ?? internalIsOpened;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// State change handlers
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (pIsOpened.current === isOpened)
|
|
36
|
-
return;
|
|
37
|
-
pIsOpened.current = isOpened;
|
|
38
|
-
stateHandlers?.toggled?.(isOpened);
|
|
39
|
-
}, [isOpened]);
|
|
49
|
+
// State dispatch
|
|
50
|
+
useChangeDispatch(isOpened, onIsOpenedChanged);
|
|
40
51
|
// User action handlers
|
|
41
52
|
const handleOpenerClick = () => {
|
|
42
|
-
|
|
53
|
+
onOpenerClicked?.(isOpened);
|
|
54
|
+
if (isControlled)
|
|
43
55
|
return;
|
|
44
56
|
setInternalIsOpened(true);
|
|
45
57
|
};
|
|
46
58
|
const handleCloserClick = () => {
|
|
47
|
-
|
|
59
|
+
onCloserClicked?.(isOpened);
|
|
60
|
+
if (isControlled)
|
|
48
61
|
return;
|
|
49
62
|
setInternalIsOpened(false);
|
|
50
63
|
};
|
|
51
|
-
const
|
|
64
|
+
const handleContentResized = ({ entry }) => {
|
|
52
65
|
const { width, height } = entry.contentRect;
|
|
53
66
|
setContentDimensions({ width, height });
|
|
54
67
|
};
|
|
@@ -61,24 +74,20 @@ export const Drawer = ({ openerContent, closerContent, initialIsOpened = false,
|
|
|
61
74
|
const openerClss = c('opener');
|
|
62
75
|
const closerClss = c('closer');
|
|
63
76
|
const contentClss = c('content');
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
let dataAttributes = {};
|
|
78
|
+
let customCssProps = {};
|
|
79
|
+
if (contentDimensions !== undefined) {
|
|
80
|
+
const { width, height } = contentDimensions;
|
|
81
|
+
dataAttributes = {
|
|
82
|
+
'data-content-width': `${width}`,
|
|
83
|
+
'data-content-height': `${height}`
|
|
84
|
+
};
|
|
85
|
+
customCssProps = {
|
|
86
|
+
'--lm-drawer-content-width': `${width}px`,
|
|
87
|
+
'--lm-drawer-content-width-raw': `${width}`,
|
|
88
|
+
'--lm-drawer-content-height': `${height}px`,
|
|
89
|
+
'--lm-drawer-content-height-raw': `${height}`
|
|
74
90
|
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.entries(dimensions)
|
|
78
|
-
.reduce((acc, [key, val]) => {
|
|
79
|
-
if (val === undefined)
|
|
80
|
-
return acc;
|
|
81
|
-
return { ...acc, [`data-content-${key}`]: `${val}` };
|
|
82
|
-
}, {});
|
|
83
|
-
return _jsxs("div", { className: rootClss, ...dataAttributes, style: { ...customCssProps }, children: [_jsx("div", { className: openerClss, onClick: handleOpenerClick, children: openerContent }), _jsx("div", { className: closerClss, onClick: handleCloserClick, children: closerContent }), _jsx("div", { className: contentClss, children: _jsx(ResizeObserverComponent, { onResized: handleROCompResize, children: children }) })] });
|
|
91
|
+
}
|
|
92
|
+
return _jsxs("div", { className: rootClss, ...dataAttributes, style: { ...customCssProps }, children: [_jsx("div", { className: openerClss, onClick: handleOpenerClick, children: openerContent }), _jsx("div", { className: closerClss, onClick: handleCloserClick, children: closerContent }), _jsx("div", { className: contentClss, children: _jsx(ResizeObserverComponent, { onResized: handleContentResized, children: children }) })] });
|
|
84
93
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PropsWithChildren, type FunctionComponent } from 'react';
|
|
2
|
+
import type { WithClassName } from '../utils/types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Props for the EventListenerComponent.
|
|
4
5
|
*
|
|
@@ -10,13 +11,11 @@ import { type ReactNode, type FunctionComponent } from 'react';
|
|
|
10
11
|
* Receives the native DOM Event object.
|
|
11
12
|
* @property children - React children rendered inside the root element.
|
|
12
13
|
*/
|
|
13
|
-
export type Props = {
|
|
14
|
-
className?: string;
|
|
14
|
+
export type Props = PropsWithChildren<WithClassName<{
|
|
15
15
|
type?: string | string[];
|
|
16
16
|
targetSelector?: string;
|
|
17
17
|
onEvent?: (e: Event) => void;
|
|
18
|
-
|
|
19
|
-
};
|
|
18
|
+
}>>;
|
|
20
19
|
/**
|
|
21
20
|
* Component that attaches one or multiple DOM event listeners to its root element
|
|
22
21
|
* or to matching descendants.
|
|
@@ -18,17 +18,19 @@ import type { WithClassName } from '../utils/types.js';
|
|
|
18
18
|
* - A ReactNode used for all pages,
|
|
19
19
|
* - A function receiving the page index and returning a ReactNode,
|
|
20
20
|
* - Undefined, in which case the page index is displayed.
|
|
21
|
-
* @property
|
|
21
|
+
* @property defaultActive - Optional. When uncontrolled mode, sets the default active slot at mount
|
|
22
22
|
* @property active - Optional controlled index. When provided, the active slot is driven by this
|
|
23
23
|
* value instead of internal scroll-derived state. When omitted, the component manages its own
|
|
24
24
|
* active index based on scroll position.
|
|
25
25
|
* @property noSnap - Optional, defines if scroll is free in side the scroller or not (defaults to false)
|
|
26
|
-
* @property
|
|
27
|
-
*
|
|
28
|
-
* @property
|
|
29
|
-
*
|
|
30
|
-
* @property
|
|
31
|
-
*
|
|
26
|
+
* @property onPrevClicked - Called when the "previous" control is clicked,
|
|
27
|
+
* before the gallery reacts, with the active index as it was.
|
|
28
|
+
* @property onNextClicked - Called when the "next" control is clicked, before
|
|
29
|
+
* the gallery reacts, with the active index as it was.
|
|
30
|
+
* @property onPaginationClicked - Called when a pagination item is clicked,
|
|
31
|
+
* before the gallery reacts, with the active index as it was and the target index.
|
|
32
|
+
* @property onActiveSlotChanged - Called after the active slot changed, with
|
|
33
|
+
* the new index.
|
|
32
34
|
* @property className - Optional additional class name(s) applied to the root element.
|
|
33
35
|
* @property children - Elements rendered as gallery slots. Each child is wrapped in a slot container.
|
|
34
36
|
*/
|
|
@@ -39,17 +41,13 @@ export type Props = PropsWithChildren<WithClassName<{
|
|
|
39
41
|
prevButtonContent?: ReactNode;
|
|
40
42
|
nextButtonContent?: ReactNode;
|
|
41
43
|
paginationContent?: ReactNode | ((page: number) => ReactNode);
|
|
42
|
-
|
|
44
|
+
defaultActive?: number;
|
|
43
45
|
active?: number;
|
|
44
46
|
noSnap?: boolean;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
prevClick?: (activePos: number) => void;
|
|
50
|
-
nextClick?: (activePos: number) => void;
|
|
51
|
-
paginationClick?: (activePos: number, targetPos: number) => void;
|
|
52
|
-
};
|
|
47
|
+
onPrevClicked?: (activePos: number) => void;
|
|
48
|
+
onNextClicked?: (activePos: number) => void;
|
|
49
|
+
onPaginationClicked?: (activePos: number, targetPos: number) => void;
|
|
50
|
+
onActiveSlotChanged?: (activePos: number) => void;
|
|
53
51
|
}>>;
|
|
54
52
|
/**
|
|
55
53
|
* Horizontally scrollable gallery component with navigation controls and pagination.
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Children, useEffect, useState, useRef } 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 { gallery as publicClassName } from '../public-classnames.js';
|
|
6
6
|
import { forceActivateSlot } from './utils.js';
|
|
7
7
|
import cssModule from './styles.module.css';
|
|
8
|
+
/** Resolves one side's padding to a CSS length, falling back to the shorthand then to `0px`. */
|
|
9
|
+
function resolvePadding(side, shorthand) {
|
|
10
|
+
const value = side ?? shorthand ?? 0;
|
|
11
|
+
return typeof value === 'number' ? `${value}px` : value;
|
|
12
|
+
}
|
|
8
13
|
/**
|
|
9
14
|
* Horizontally scrollable gallery component with navigation controls and pagination.
|
|
10
15
|
*
|
|
@@ -18,32 +23,34 @@ import cssModule from './styles.module.css';
|
|
|
18
23
|
* - Previous/next navigation controls,
|
|
19
24
|
* - Pagination controls allowing direct slot activation.
|
|
20
25
|
*/
|
|
21
|
-
export const Gallery = ({ paddingLeft, paddingRight, padding, prevButtonContent, nextButtonContent, paginationContent,
|
|
26
|
+
export const Gallery = ({ paddingLeft, paddingRight, padding, prevButtonContent, nextButtonContent, paginationContent, defaultActive, active, noSnap, onPrevClicked, onNextClicked, onPaginationClicked, onActiveSlotChanged, children, className }) => {
|
|
22
27
|
// State & refs
|
|
23
28
|
const scrollerRef = useRef(null);
|
|
24
29
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
25
30
|
const [canGoLeft, setCanGoLeft] = useState(false);
|
|
26
31
|
const [canGoRight, setCanGoRight] = useState(false);
|
|
27
32
|
const childrenCount = Children.count(children);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}, [activeIndex]);
|
|
33
|
+
const isControlled = active !== undefined;
|
|
34
|
+
// State dispatch
|
|
35
|
+
useChangeDispatch(activeIndex, onActiveSlotChanged);
|
|
32
36
|
// User actions handlers
|
|
33
37
|
const handlePrevClick = () => {
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
38
|
+
onPrevClicked?.(activeIndex);
|
|
39
|
+
if (isControlled)
|
|
40
|
+
return;
|
|
41
|
+
forceActivateSlot(scrollerRef.current, activeIndex - 1);
|
|
37
42
|
};
|
|
38
43
|
const handleNextClick = () => {
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
44
|
+
onNextClicked?.(activeIndex);
|
|
45
|
+
if (isControlled)
|
|
46
|
+
return;
|
|
47
|
+
forceActivateSlot(scrollerRef.current, activeIndex + 1);
|
|
42
48
|
};
|
|
43
49
|
const handlePaginationClick = (pos) => {
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
50
|
+
onPaginationClicked?.(activeIndex, pos);
|
|
51
|
+
if (isControlled)
|
|
52
|
+
return;
|
|
53
|
+
forceActivateSlot(scrollerRef.current, pos);
|
|
47
54
|
};
|
|
48
55
|
// Scroll position calculation
|
|
49
56
|
useEffect(() => {
|
|
@@ -87,7 +94,7 @@ export const Gallery = ({ paddingLeft, paddingRight, padding, prevButtonContent,
|
|
|
87
94
|
}, []);
|
|
88
95
|
// Sync scroll position to 'active' prop at mount time
|
|
89
96
|
useEffect(() => {
|
|
90
|
-
const toActivate = active ??
|
|
97
|
+
const toActivate = active ?? defaultActive;
|
|
91
98
|
if (toActivate === undefined)
|
|
92
99
|
return;
|
|
93
100
|
const id = setTimeout(() => forceActivateSlot(scrollerRef.current, toActivate, false), 50);
|
|
@@ -115,20 +122,8 @@ export const Gallery = ({ paddingLeft, paddingRight, padding, prevButtonContent,
|
|
|
115
122
|
const nextBtnClss = c('next');
|
|
116
123
|
const paginationClss = c('pagination');
|
|
117
124
|
const dataAttributes = { 'data-active': `${activeIndex}` };
|
|
118
|
-
const actualPaddingLeft =
|
|
119
|
-
|
|
120
|
-
: typeof paddingLeft === 'string'
|
|
121
|
-
? paddingLeft
|
|
122
|
-
: typeof padding === 'number'
|
|
123
|
-
? `${padding}px`
|
|
124
|
-
: padding ?? '0px';
|
|
125
|
-
const actualPaddingRight = typeof paddingRight === 'number'
|
|
126
|
-
? `${paddingRight}px`
|
|
127
|
-
: typeof paddingRight === 'string'
|
|
128
|
-
? paddingRight
|
|
129
|
-
: typeof padding === 'number'
|
|
130
|
-
? `${padding}px`
|
|
131
|
-
: padding ?? '0px';
|
|
125
|
+
const actualPaddingLeft = resolvePadding(paddingLeft, padding);
|
|
126
|
+
const actualPaddingRight = resolvePadding(paddingRight, padding);
|
|
132
127
|
return _jsxs("div", { className: rootClss, ...dataAttributes, children: [_jsx("div", { className: scrollerClss, ref: scrollerRef, children: Children.map(children, (child, pos) => {
|
|
133
128
|
const slotClss = c('slot', { active: pos === activeIndex });
|
|
134
129
|
const style = {
|
|
@@ -5,7 +5,7 @@ import { randomHash } from '../../agnostic/random/uuid/index.js';
|
|
|
5
5
|
import { mergeClassNames } from '../utils/index.js';
|
|
6
6
|
import { iframe as publicClassName } from '../public-classnames.js';
|
|
7
7
|
import cssModule from './styles.module.css';
|
|
8
|
-
const
|
|
8
|
+
const innerAutoHeightNotifier = (messageType) => `<script>
|
|
9
9
|
(() => {
|
|
10
10
|
const notify = () => {
|
|
11
11
|
const height = Math.max(
|
|
@@ -71,7 +71,7 @@ export const Iframe = ({ autoHeight = false, className, srcDoc, style, ...iframe
|
|
|
71
71
|
const rootClss = mergeClassNames(c(), className);
|
|
72
72
|
const html = useMemo(() => {
|
|
73
73
|
const autoHeightScript = autoHeight
|
|
74
|
-
?
|
|
74
|
+
? innerAutoHeightNotifier(innerMessageType)
|
|
75
75
|
: '';
|
|
76
76
|
return `<!doctype html>
|
|
77
77
|
<html>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type FunctionComponent, type ImgHTMLAttributes } from 'react';
|
|
2
|
-
import { type Props as DisclaimerProps } from '../Disclaimer/index.js';
|
|
3
2
|
import { type Props as TheatreProps } from '../Theatre/index.js';
|
|
4
3
|
import type { WithClassName } from '../utils/types.js';
|
|
5
4
|
/**
|
|
@@ -28,31 +27,25 @@ type SourceData = {
|
|
|
28
27
|
* - a single srcSet string,
|
|
29
28
|
* - an array of srcSet strings,
|
|
30
29
|
* - an array of {@link SourceData} objects for full `<source>` control.
|
|
31
|
-
* @property disclaimer - Props forwarded to the internal {@link Disclaimer} component.
|
|
32
|
-
* While the disclaimer is active the `<img>` is hidden.
|
|
33
30
|
* @property theatre - Props forwarded to the internal {@link Theatre} component.
|
|
34
31
|
* @property className - Optional additional class name(s) applied to the root element.
|
|
35
32
|
*/
|
|
36
33
|
export type Props = WithClassName<{
|
|
37
34
|
sources?: string | string[] | SourceData[];
|
|
38
|
-
disclaimer?: DisclaimerProps;
|
|
39
35
|
theatre?: TheatreProps;
|
|
40
36
|
}> & ImgHTMLAttributes<HTMLImageElement>;
|
|
41
37
|
/**
|
|
42
38
|
* Image component. Wraps a native `<img>` (or `<picture>`) element with
|
|
43
|
-
* optional responsive sources
|
|
44
|
-
* viewport-driven visibility tracking.
|
|
39
|
+
* optional responsive sources and an optional theatre mode.
|
|
45
40
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* - `__picture` — wrapping `<picture>` element, always rendered. Contains the
|
|
41
|
+
* ### CSS elements
|
|
42
|
+
* - `picture` — wrapping `<picture>` element, always rendered. Contains the
|
|
49
43
|
* `<source>` elements (if any) and the `<img>`.
|
|
50
|
-
* - `
|
|
44
|
+
* - `image` — the native `<img>` element.
|
|
51
45
|
*
|
|
52
46
|
* @param props - Component properties.
|
|
53
47
|
* @see {@link Props}
|
|
54
|
-
* @returns A `<figure>` element containing a `<picture>` with the image
|
|
55
|
-
* and an optional disclaimer overlay.
|
|
48
|
+
* @returns A `<figure>` element containing a `<picture>` with the image.
|
|
56
49
|
*/
|
|
57
50
|
export declare const Image: FunctionComponent<Props>;
|
|
58
51
|
export {};
|
|
@@ -1,37 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import { Disclaimer } from '../Disclaimer/index.js';
|
|
5
4
|
import { Theatre } from '../Theatre/index.js';
|
|
6
5
|
import { mergeClassNames } from '../utils/index.js';
|
|
7
6
|
import { image as publicClassName } from '../public-classnames.js';
|
|
8
7
|
import cssModule from './styles.module.css';
|
|
9
8
|
/**
|
|
10
9
|
* Image component. Wraps a native `<img>` (or `<picture>`) element with
|
|
11
|
-
* optional responsive sources
|
|
12
|
-
* viewport-driven visibility tracking.
|
|
10
|
+
* optional responsive sources and an optional theatre mode.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* - `__picture` — wrapping `<picture>` element, always rendered. Contains the
|
|
12
|
+
* ### CSS elements
|
|
13
|
+
* - `picture` — wrapping `<picture>` element, always rendered. Contains the
|
|
17
14
|
* `<source>` elements (if any) and the `<img>`.
|
|
18
|
-
* - `
|
|
15
|
+
* - `image` — the native `<img>` element.
|
|
19
16
|
*
|
|
20
17
|
* @param props - Component properties.
|
|
21
18
|
* @see {@link Props}
|
|
22
|
-
* @returns A `<figure>` element containing a `<picture>` with the image
|
|
23
|
-
* and an optional disclaimer overlay.
|
|
19
|
+
* @returns A `<figure>` element containing a `<picture>` with the image.
|
|
24
20
|
*/
|
|
25
|
-
export const Image = ({ sources,
|
|
21
|
+
export const Image = ({ sources, theatre, className, ...intrinsicImgAttributes }) => {
|
|
26
22
|
// State
|
|
27
|
-
const [isDisclaimerOn, setIsDisclaimerOn] = useState(disclaimer?.isOn === true
|
|
28
|
-
|| disclaimer?.defaultIsOn === true
|
|
29
|
-
|| (disclaimer !== undefined && disclaimer.defaultIsOn === undefined));
|
|
30
|
-
let shouldDisclaimerBeOn = isDisclaimerOn;
|
|
31
|
-
if (disclaimer?.isOn === true)
|
|
32
|
-
shouldDisclaimerBeOn = true;
|
|
33
|
-
if (disclaimer?.isOn === false)
|
|
34
|
-
shouldDisclaimerBeOn = false;
|
|
35
23
|
const parsedSources = useMemo(() => {
|
|
36
24
|
if (sources === undefined)
|
|
37
25
|
return [];
|
|
@@ -48,23 +36,14 @@ export const Image = ({ sources, disclaimer, theatre, className, ...intrinsicImg
|
|
|
48
36
|
}
|
|
49
37
|
return [];
|
|
50
38
|
}, [sources]);
|
|
51
|
-
// User actions handlers
|
|
52
|
-
const handleDisclaimerDismissClick = useCallback(() => {
|
|
53
|
-
disclaimer?.actionHandlers?.dismissClick?.(isDisclaimerOn);
|
|
54
|
-
setIsDisclaimerOn(false);
|
|
55
|
-
}, []);
|
|
56
39
|
// Rendering
|
|
57
40
|
const c = clss(publicClassName, { cssModule });
|
|
58
41
|
const rootClss = mergeClassNames(c(), className);
|
|
59
|
-
const rootAttributes = {};
|
|
60
42
|
const pictureClss = c('picture');
|
|
61
43
|
const imgClss = c('image');
|
|
62
|
-
const
|
|
44
|
+
const pictureContent = _jsxs("picture", { className: pictureClss, children: [parsedSources.map((source, index) => _jsx("source", { srcSet: typeof source === 'string' ? source : source.srcSet, type: typeof source === 'string' ? undefined : source.type, media: typeof source === 'string' ? undefined : source.media, sizes: typeof source === 'string' ? undefined : source.sizes }, index)), _jsx("img", { className: imgClss, ...intrinsicImgAttributes })] });
|
|
63
45
|
const theatricalContent = theatre !== undefined
|
|
64
|
-
? _jsx(Theatre, { defaultIsOn: false, ...theatre, children:
|
|
65
|
-
:
|
|
66
|
-
|
|
67
|
-
? _jsx(Disclaimer, { ...disclaimer, isOn: shouldDisclaimerBeOn, actionHandlers: { dismissClick: handleDisclaimerDismissClick }, children: theatricalContent })
|
|
68
|
-
: theatricalContent;
|
|
69
|
-
return _jsx("figure", { className: rootClss, ...rootAttributes, children: disclaimedContent });
|
|
46
|
+
? _jsx(Theatre, { defaultIsOn: false, ...theatre, children: pictureContent })
|
|
47
|
+
: pictureContent;
|
|
48
|
+
return _jsx("figure", { className: rootClss, children: theatricalContent });
|
|
70
49
|
};
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
import { type FunctionComponent } from 'react';
|
|
2
|
-
import
|
|
1
|
+
import { type FunctionComponent, type InputHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import type { WithClassName } from '../utils/types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Props for the {@link Input} component.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Extends all native {@link InputHTMLAttributes} and {@link WithClassName}
|
|
7
|
+
* with optional label and error content.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* @property label - Content rendered as an associated `<label>`. When omitted, no label is rendered.
|
|
10
|
+
* @property error - Content rendered as an error message below the input. When omitted, no error is rendered.
|
|
11
|
+
* @property className - Additional class name(s) applied to the input element.
|
|
11
12
|
*/
|
|
12
|
-
export type Props =
|
|
13
|
+
export type Props = InputHTMLAttributes<HTMLInputElement> & WithClassName<{
|
|
14
|
+
label?: ReactNode;
|
|
15
|
+
error?: ReactNode;
|
|
16
|
+
}>;
|
|
13
17
|
/**
|
|
14
|
-
* Input field
|
|
18
|
+
* Input field supporting controlled and uncontrolled usage.
|
|
15
19
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
20
|
+
* Renders a native `<input>` with optional label and error feedback. All
|
|
21
|
+
* standard input attributes are forwarded to the underlying element.
|
|
22
|
+
*
|
|
23
|
+
* A stable auto-generated `id` is created on mount and used to associate the
|
|
24
|
+
* rendered label through the `htmlFor` attribute.
|
|
18
25
|
*
|
|
19
26
|
* ### CSS elements
|
|
20
27
|
* - `label`
|
|
@@ -22,16 +29,13 @@ export type Props = ControlledProps;
|
|
|
22
29
|
*
|
|
23
30
|
* @param props - Component properties.
|
|
24
31
|
* @see {@link Props}
|
|
25
|
-
*
|
|
26
|
-
* @returns A labelled input with optional internal value management.
|
|
32
|
+
* @returns A labelled input with optional error feedback.
|
|
27
33
|
*
|
|
28
34
|
* @remarks
|
|
29
|
-
* -
|
|
30
|
-
*
|
|
31
|
-
* -
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* - In hybrid mode, the internal value is updated before forwarding
|
|
35
|
-
* the `onChange` callback.
|
|
35
|
+
* - In controlled mode (`value` defined), the displayed value is fully driven
|
|
36
|
+
* by the parent and internal state is never updated.
|
|
37
|
+
* - In uncontrolled mode, internal state is initialized from `defaultValue` and
|
|
38
|
+
* updated before `onChange` is forwarded.
|
|
39
|
+
* - `onChange` fires in both modes.
|
|
36
40
|
*/
|
|
37
41
|
export declare const Input: FunctionComponent<Props>;
|