@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
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'react';
|
|
2
|
-
import { type Props as DisclaimerProps } from '../Disclaimer/index.js';
|
|
3
2
|
import { type Props as ControlledProps } from './index.controlled.js';
|
|
4
3
|
/**
|
|
5
4
|
* Props for the {@link Video} component.
|
|
6
5
|
*
|
|
7
6
|
* Extends all ControlledVideo props except play, mute, fullscreen, volume, playbackRate, and their associated event handlers
|
|
8
|
-
* @property disclaimer - Props forwarded to the internal {@link Disclaimer} component.
|
|
9
|
-
* While the disclaimer is active, `autoPlay` and `muted` are suppressed on the
|
|
10
|
-
* underlying `<video>` element.
|
|
11
7
|
* @property autoPlayWhenVisible - When `true`, triggers playback the first time the
|
|
12
|
-
* component intersects the viewport
|
|
8
|
+
* component intersects the viewport.
|
|
13
9
|
* @property autoPauseWhenHidden - When `true`, pauses playback whenever the component
|
|
14
10
|
* leaves the viewport.
|
|
15
11
|
* @property autoLoudWhenVisible - When `true`, unmutes the video the first time the
|
|
16
|
-
* component intersects the viewport
|
|
12
|
+
* component intersects the viewport.
|
|
17
13
|
* @property autoMuteWhenHidden - When `true`, mutes the video whenever the component
|
|
18
14
|
* leaves the viewport.
|
|
19
|
-
* @property currentTimeMs - When provided,
|
|
15
|
+
* @property currentTimeMs - When provided, hands ownership of the current time
|
|
16
|
+
* (in milliseconds) to the parent, which is then responsible for updating it —
|
|
17
|
+
* typically to scrub the video from scroll position. A controlled time implies a
|
|
18
|
+
* stopped video, since a playing element would advance a value it does not own:
|
|
19
|
+
* `autoPlay`, `autoPlayWhenVisible` and the play button have no effect for as
|
|
20
|
+
* long as this prop is provided.
|
|
20
21
|
* @property wrapperClassName - Optional additional class name(s) applied to the root wrapper element.
|
|
21
|
-
* @property stateHandlers - Optional callbacks invoked whenever the corresponding
|
|
22
|
-
* state changes. Useful for synchronizing external state with the internal video state.
|
|
23
22
|
* @property className - Optional additional class name(s) applied to the root element.
|
|
24
23
|
* @property children - React children rendered inside the `<video>` element itself
|
|
25
24
|
* (e.g. fallback content).
|
|
26
25
|
*/
|
|
27
26
|
export type Props = Omit<ControlledProps, 'play' | 'fullscreen' | 'volume' | 'mute' | 'playbackRate'> & {
|
|
28
|
-
disclaimer?: DisclaimerProps;
|
|
29
27
|
autoPlayWhenVisible?: boolean;
|
|
30
28
|
autoPauseWhenHidden?: boolean;
|
|
31
29
|
autoLoudWhenVisible?: boolean;
|
|
@@ -34,12 +32,12 @@ export type Props = Omit<ControlledProps, 'play' | 'fullscreen' | 'volume' | 'mu
|
|
|
34
32
|
};
|
|
35
33
|
/**
|
|
36
34
|
* Full-featured video player component. Wraps a native `<video>` element with
|
|
37
|
-
* playback controls, volume, playback rate, a timeline, optional subtitles,
|
|
38
|
-
*
|
|
35
|
+
* playback controls, volume, playback rate, a timeline, optional subtitles, and
|
|
36
|
+
* viewport-driven auto-play/mute behaviours.
|
|
39
37
|
*
|
|
40
38
|
* @param props - Component properties.
|
|
41
39
|
* @see {@link Props}
|
|
42
|
-
* @returns A `<figure>` element containing the video, its controls
|
|
43
|
-
* subtitles
|
|
40
|
+
* @returns A `<figure>` element containing the video, its controls and optional
|
|
41
|
+
* subtitles.
|
|
44
42
|
*/
|
|
45
43
|
export declare const Video: FunctionComponent<Props>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import { Disclaimer } from '../Disclaimer/index.js';
|
|
5
4
|
import { IntersectionObserverComponent } from '../IntersectionObserver/index.js';
|
|
6
5
|
import { mergeClassNames } from '../utils/index.js';
|
|
7
6
|
import { videoWrapper as publicClassName } from '../public-classnames.js';
|
|
@@ -10,33 +9,27 @@ import cssModule from './styles.module.css';
|
|
|
10
9
|
import { ControlledVideo } from './index.controlled.js';
|
|
11
10
|
/**
|
|
12
11
|
* Full-featured video player component. Wraps a native `<video>` element with
|
|
13
|
-
* playback controls, volume, playback rate, a timeline, optional subtitles,
|
|
14
|
-
*
|
|
12
|
+
* playback controls, volume, playback rate, a timeline, optional subtitles, and
|
|
13
|
+
* viewport-driven auto-play/mute behaviours.
|
|
15
14
|
*
|
|
16
15
|
* @param props - Component properties.
|
|
17
16
|
* @see {@link Props}
|
|
18
|
-
* @returns A `<figure>` element containing the video, its controls
|
|
19
|
-
* subtitles
|
|
17
|
+
* @returns A `<figure>` element containing the video, its controls and optional
|
|
18
|
+
* subtitles.
|
|
20
19
|
*/
|
|
21
|
-
export const Video = ({ loop,
|
|
20
|
+
export const Video = ({ loop, autoPlayWhenVisible, autoPauseWhenHidden, autoMuteWhenHidden, autoLoudWhenVisible, wrapperClassName, onPlayButtonClicked, onPauseButtonClicked, onLoudButtonClicked, onMuteButtonClicked, onVolumeRangeChanged, onRateRangeChanged, onFullscreenButtonClicked, ...controlledProps }) => {
|
|
22
21
|
// State & refs
|
|
23
22
|
const [play, setPlay] = useState(false);
|
|
24
23
|
const [volume, setVolume] = useState(1);
|
|
25
24
|
const [mute, setMute] = useState(false);
|
|
26
25
|
const [playbackRate, setPlaybackRate] = useState(1);
|
|
27
26
|
const [fullscreen, setFullscreen] = useState(false);
|
|
28
|
-
const [isDisclaimerOn, setIsDisclaimerOn] = useState(disclaimer?.isOn === true
|
|
29
|
-
|| disclaimer?.defaultIsOn === true
|
|
30
|
-
|| (disclaimer !== undefined && disclaimer.defaultIsOn === undefined));
|
|
31
27
|
const hasBeenAutoPlayed = useRef(false);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return true;
|
|
38
|
-
return isDisclaimerOn;
|
|
39
|
-
}, [disclaimer, isDisclaimerOn]);
|
|
28
|
+
// Several paths below ask for playback — the play button, autoPlayWhenVisible,
|
|
29
|
+
// autoPlay itself. None of them may win over a parent-owned time, so the
|
|
30
|
+
// invariant is applied where the state is forwarded rather than guarded at each
|
|
31
|
+
// of those call sites.
|
|
32
|
+
const isTimeControlled = controlledProps.currentTimeMs !== undefined;
|
|
40
33
|
const needsObserve = useMemo(() => autoLoudWhenVisible === true
|
|
41
34
|
|| autoMuteWhenHidden === true
|
|
42
35
|
|| autoPlayWhenVisible === true
|
|
@@ -49,13 +42,9 @@ export const Video = ({ loop, disclaimer, autoPlayWhenVisible, autoPauseWhenHidd
|
|
|
49
42
|
// Intrisic event handlers
|
|
50
43
|
const handleOnPlayEvent = useCallback((e) => {
|
|
51
44
|
controlledProps.onPlay?.(e);
|
|
52
|
-
if (shouldDisclaimerBeOn) {
|
|
53
|
-
setPlay(false);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
45
|
setPlay(true);
|
|
57
46
|
hasBeenAutoPlayed.current = true;
|
|
58
|
-
}, [controlledProps.onPlay
|
|
47
|
+
}, [controlledProps.onPlay]);
|
|
59
48
|
const handleOnPauseEvent = useCallback((e) => {
|
|
60
49
|
setPlay(false);
|
|
61
50
|
controlledProps.onPause?.(e);
|
|
@@ -69,45 +58,44 @@ export const Video = ({ loop, disclaimer, autoPlayWhenVisible, autoPauseWhenHidd
|
|
|
69
58
|
setPlaybackRate(e.currentTarget.playbackRate);
|
|
70
59
|
controlledProps.onRateChange?.(e);
|
|
71
60
|
}, [controlledProps.onRateChange]);
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
61
|
+
const handleFullscreenChange = useCallback((isFullscreen) => {
|
|
62
|
+
if (!isFullscreen)
|
|
74
63
|
setFullscreen(false);
|
|
75
|
-
|
|
76
|
-
}, [shouldDisclaimerBeOn]);
|
|
64
|
+
}, []);
|
|
77
65
|
const handleOnLoadedMetadataEvent = useCallback((e) => {
|
|
78
66
|
muteAttributeWorkaround(e.currentTarget, controlledProps.muted ?? false);
|
|
79
67
|
controlledProps.onLoadedMetadata?.(e);
|
|
80
68
|
}, [controlledProps.onLoadedMetadata, controlledProps.muted]);
|
|
81
69
|
// User actions
|
|
82
70
|
const handlePlayButtonClick = useCallback((e, isPlaying, video) => {
|
|
83
|
-
|
|
84
|
-
setPlay(
|
|
85
|
-
}, [
|
|
71
|
+
onPlayButtonClicked?.(e, isPlaying, video);
|
|
72
|
+
setPlay(true);
|
|
73
|
+
}, [onPlayButtonClicked]);
|
|
86
74
|
const handlePauseButtonClick = useCallback((e, isPlaying, video) => {
|
|
87
|
-
|
|
75
|
+
onPauseButtonClicked?.(e, isPlaying, video);
|
|
88
76
|
setPlay(false);
|
|
89
|
-
}, [
|
|
77
|
+
}, [onPauseButtonClicked]);
|
|
90
78
|
const handleLoudButtonClick = useCallback((e, isLoud, video) => {
|
|
91
|
-
|
|
79
|
+
onLoudButtonClicked?.(e, isLoud, video);
|
|
92
80
|
setMute(false);
|
|
93
|
-
}, [
|
|
81
|
+
}, [onLoudButtonClicked]);
|
|
94
82
|
const handleMuteButtonClick = useCallback((e, isLoud, video) => {
|
|
95
|
-
|
|
83
|
+
onMuteButtonClicked?.(e, isLoud, video);
|
|
96
84
|
setMute(true);
|
|
97
|
-
}, [
|
|
85
|
+
}, [onMuteButtonClicked]);
|
|
98
86
|
const handleRateRangeChange = useCallback((e, targetRate, currentRate, video) => {
|
|
99
|
-
|
|
87
|
+
onRateRangeChanged?.(e, targetRate, currentRate, video);
|
|
100
88
|
setPlaybackRate(targetRate);
|
|
101
|
-
}, [
|
|
89
|
+
}, [onRateRangeChanged]);
|
|
102
90
|
const handleVolumeRangeChange = useCallback((e, targetVolume, currentVolume, video) => {
|
|
103
|
-
|
|
91
|
+
onVolumeRangeChanged?.(e, targetVolume, currentVolume, video);
|
|
104
92
|
setVolume(targetVolume);
|
|
105
|
-
}, [
|
|
93
|
+
}, [onVolumeRangeChanged]);
|
|
106
94
|
const handleFullscreenButtonClick = useCallback((e, isFullscreen, video) => {
|
|
107
|
-
|
|
108
|
-
setFullscreen(
|
|
109
|
-
}, [
|
|
110
|
-
// Intersection Observer
|
|
95
|
+
onFullscreenButtonClicked?.(e, isFullscreen, video);
|
|
96
|
+
setFullscreen(!isFullscreen);
|
|
97
|
+
}, [onFullscreenButtonClicked]);
|
|
98
|
+
// Intersection Observer
|
|
111
99
|
const onIntersected = useCallback(({ ioEntry }) => {
|
|
112
100
|
if (ioEntry === undefined)
|
|
113
101
|
return;
|
|
@@ -117,12 +105,10 @@ export const Video = ({ loop, disclaimer, autoPlayWhenVisible, autoPauseWhenHidd
|
|
|
117
105
|
if (autoLoudWhenVisible === true && isIntersecting)
|
|
118
106
|
setMute(false);
|
|
119
107
|
if (autoPlayWhenVisible === true
|
|
120
|
-
&& !shouldDisclaimerBeOn
|
|
121
108
|
&& !hasBeenAutoPlayed.current
|
|
122
109
|
&& isIntersecting)
|
|
123
110
|
setPlay(true);
|
|
124
111
|
if (autoMuteWhenHidden === true
|
|
125
|
-
&& !shouldDisclaimerBeOn
|
|
126
112
|
&& !hasBeenAutoPlayed.current
|
|
127
113
|
&& !isIntersecting)
|
|
128
114
|
setMute(true);
|
|
@@ -130,50 +116,19 @@ export const Video = ({ loop, disclaimer, autoPlayWhenVisible, autoPauseWhenHidd
|
|
|
130
116
|
autoPlayWhenVisible,
|
|
131
117
|
autoPauseWhenHidden,
|
|
132
118
|
autoMuteWhenHidden,
|
|
133
|
-
autoLoudWhenVisible
|
|
134
|
-
shouldDisclaimerBeOn
|
|
119
|
+
autoLoudWhenVisible
|
|
135
120
|
]);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (controlledProps.autoPlay === true && !hasBeenAutoPlayed.current) {
|
|
139
|
-
setPlay(true);
|
|
140
|
-
}
|
|
141
|
-
disclaimer?.actionHandlers?.dismissClick?.(prevIsOn);
|
|
142
|
-
}, [controlledProps.autoPlay, disclaimer?.actionHandlers?.dismissClick]);
|
|
121
|
+
// `autoPlay` is forwarded to the element, but the play state is owned here, so
|
|
122
|
+
// it has to be seeded once on mount for the controls to agree with the element.
|
|
143
123
|
useEffect(() => {
|
|
144
|
-
if (
|
|
145
|
-
setIsDisclaimerOn(shouldDisclaimerBeOn);
|
|
146
|
-
}, [isDisclaimerOn, shouldDisclaimerBeOn]);
|
|
147
|
-
useEffect(() => {
|
|
148
|
-
if (shouldDisclaimerBeOn) {
|
|
149
|
-
setMute(true);
|
|
150
|
-
setPlay(false);
|
|
151
|
-
setFullscreen(false);
|
|
152
|
-
}
|
|
153
|
-
else if (controlledProps.autoPlay === true && !hasBeenAutoPlayed.current) {
|
|
124
|
+
if (controlledProps.autoPlay === true && !hasBeenAutoPlayed.current)
|
|
154
125
|
setPlay(true);
|
|
155
|
-
|
|
156
|
-
}, [shouldDisclaimerBeOn]);
|
|
126
|
+
}, []);
|
|
157
127
|
// Render
|
|
158
128
|
const c = clss(publicClassName, { cssModule });
|
|
159
|
-
const rootClss = mergeClassNames(c(
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
loudButtonClick: handleLoudButtonClick,
|
|
165
|
-
muteButtonClick: handleMuteButtonClick,
|
|
166
|
-
volumeRangeChange: handleVolumeRangeChange,
|
|
167
|
-
rateRangeChange: handleRateRangeChange,
|
|
168
|
-
fullscreenButtonClick: handleFullscreenButtonClick
|
|
169
|
-
} });
|
|
170
|
-
const disclaimedContent = needsDisclaimer
|
|
171
|
-
? _jsx(Disclaimer, { ...disclaimer, actionHandlers: {
|
|
172
|
-
...disclaimer?.actionHandlers,
|
|
173
|
-
dismissClick: handleDiclaimerDismiss
|
|
174
|
-
}, children: sensitiveContent })
|
|
175
|
-
: sensitiveContent;
|
|
176
|
-
return (_jsx("div", { className: rootClss, children: needsObserve
|
|
177
|
-
? _jsx(IntersectionObserverComponent, { onIntersected: onIntersected, children: disclaimedContent })
|
|
178
|
-
: disclaimedContent }));
|
|
129
|
+
const rootClss = mergeClassNames(c(), wrapperClassName);
|
|
130
|
+
const videoContent = _jsx(ControlledVideo, { ...controlledProps, play: play && !isTimeControlled, volume: volume, mute: mute, playbackRate: playbackRate, fullscreen: fullscreen, onPlay: handleOnPlayEvent, onPause: handleOnPauseEvent, onVolumeChange: handleOnVolumeChangeEvent, onRateChange: handleOnRateChangeEvent, onLoadedMetadata: handleOnLoadedMetadataEvent, onFullscreenChange: handleFullscreenChange, onPlayButtonClicked: handlePlayButtonClick, onPauseButtonClicked: handlePauseButtonClick, onLoudButtonClicked: handleLoudButtonClick, onMuteButtonClicked: handleMuteButtonClick, onVolumeRangeChanged: handleVolumeRangeChange, onRateRangeChanged: handleRateRangeChange, onFullscreenButtonClicked: handleFullscreenButtonClick });
|
|
131
|
+
return _jsx("div", { className: rootClss, children: needsObserve
|
|
132
|
+
? _jsx(IntersectionObserverComponent, { onIntersected: onIntersected, children: videoContent })
|
|
133
|
+
: videoContent });
|
|
179
134
|
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import type { Dispatch, SetStateAction } from 'react';
|
|
2
1
|
export declare const muteAttributeWorkaround: (video: HTMLVideoElement | null, shouldMute: boolean) => void;
|
|
3
2
|
export declare const forceMute: (video: HTMLVideoElement | null) => void;
|
|
4
3
|
export declare const forceLoud: (video: HTMLVideoElement | null) => void;
|
|
5
4
|
export declare const forceVolume: (video: HTMLVideoElement | null, volume: number) => void;
|
|
6
|
-
export declare const forceCurrentTime: (video: HTMLVideoElement | null, time: number, setCurrentTime: Dispatch<SetStateAction<number>>) => void;
|
|
7
5
|
export declare const forcePlay: (video: HTMLVideoElement | null) => Promise<boolean>;
|
|
8
6
|
export declare const forcePause: (video: HTMLVideoElement | null) => boolean;
|
|
9
7
|
export declare const forcePlaybackRate: (video: HTMLVideoElement | null, rate: number) => void;
|
|
@@ -11,5 +9,39 @@ export declare const forceFullscreen: (video: HTMLVideoElement | null) => Promis
|
|
|
11
9
|
export declare const forceExitFullscreen: (video: HTMLVideoElement | null) => Promise<boolean>;
|
|
12
10
|
export declare function secondsToMs(seconds: number): number;
|
|
13
11
|
export declare function msToSeconds(ms: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* Renders a duration into a caller-defined pattern.
|
|
14
|
+
*
|
|
15
|
+
* The pattern is a free-form string in which the following tokens are replaced,
|
|
16
|
+
* longest first, so that `mm` is consumed before `m`:
|
|
17
|
+
*
|
|
18
|
+
* - `hh`, `mm`, `ss` — hours, minutes and seconds, zero-padded to two digits.
|
|
19
|
+
* - `ms` — the remaining milliseconds, zero-padded to three digits.
|
|
20
|
+
* - `frame` — the remaining milliseconds expressed in frames, zero-padded to two
|
|
21
|
+
* digits.
|
|
22
|
+
* - `h`, `m`, `s`, `f` — the same four values, unpadded.
|
|
23
|
+
*
|
|
24
|
+
* @param ms - The duration, in milliseconds.
|
|
25
|
+
* @param format - The pattern to fill, e.g. `'mm:ss:ms'`.
|
|
26
|
+
* @param fps - Frame rate used to derive the `frame` and `f` tokens. Defaults to `25`.
|
|
27
|
+
* @returns The formatted duration.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* Every field is a remainder of the one above it, never a total: at one hour and
|
|
31
|
+
* a half, `mm` is `30`, not `90`. A pattern that omits `hh` therefore loses the
|
|
32
|
+
* hours rather than folding them into the minutes.
|
|
33
|
+
*
|
|
34
|
+
* Since `h`, `m`, `s` and `f` are tokens on their own, **every** occurrence of
|
|
35
|
+
* those letters is substituted, wherever it sits: `'mm min ss'` renders as
|
|
36
|
+
* `'01 1in 01'`. Separate the fields with punctuation. This is what
|
|
37
|
+
* `agnostic/time/dates/format-date` avoids by delimiting its tokens with
|
|
38
|
+
* `{{…}}` — worth aligning on the day this one is made public.
|
|
39
|
+
*/
|
|
14
40
|
export declare function formatTime(ms: number, format: string, fps?: number): string;
|
|
15
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Where along the timeline a click landed.
|
|
43
|
+
*
|
|
44
|
+
* @param event - The click on the timeline element.
|
|
45
|
+
* @returns A ratio between `0` and `1`, clamped to the element's own bounds.
|
|
46
|
+
*/
|
|
47
|
+
export declare const getTimelineClickProgress: (event: React.MouseEvent<HTMLDivElement>) => number;
|
|
@@ -28,13 +28,6 @@ export const forceVolume = (video, volume) => {
|
|
|
28
28
|
// eslint-disable-next-line no-param-reassign
|
|
29
29
|
video.volume = volume;
|
|
30
30
|
};
|
|
31
|
-
export const forceCurrentTime = (video, time, setCurrentTime) => {
|
|
32
|
-
if (video === null)
|
|
33
|
-
return;
|
|
34
|
-
// eslint-disable-next-line no-param-reassign
|
|
35
|
-
video.currentTime = time;
|
|
36
|
-
setCurrentTime(time);
|
|
37
|
-
};
|
|
38
31
|
export const forcePlay = async (video) => {
|
|
39
32
|
if (video === null)
|
|
40
33
|
return false;
|
|
@@ -105,6 +98,34 @@ export function secondsToMs(seconds) {
|
|
|
105
98
|
export function msToSeconds(ms) {
|
|
106
99
|
return ms / 1000;
|
|
107
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Renders a duration into a caller-defined pattern.
|
|
103
|
+
*
|
|
104
|
+
* The pattern is a free-form string in which the following tokens are replaced,
|
|
105
|
+
* longest first, so that `mm` is consumed before `m`:
|
|
106
|
+
*
|
|
107
|
+
* - `hh`, `mm`, `ss` — hours, minutes and seconds, zero-padded to two digits.
|
|
108
|
+
* - `ms` — the remaining milliseconds, zero-padded to three digits.
|
|
109
|
+
* - `frame` — the remaining milliseconds expressed in frames, zero-padded to two
|
|
110
|
+
* digits.
|
|
111
|
+
* - `h`, `m`, `s`, `f` — the same four values, unpadded.
|
|
112
|
+
*
|
|
113
|
+
* @param ms - The duration, in milliseconds.
|
|
114
|
+
* @param format - The pattern to fill, e.g. `'mm:ss:ms'`.
|
|
115
|
+
* @param fps - Frame rate used to derive the `frame` and `f` tokens. Defaults to `25`.
|
|
116
|
+
* @returns The formatted duration.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* Every field is a remainder of the one above it, never a total: at one hour and
|
|
120
|
+
* a half, `mm` is `30`, not `90`. A pattern that omits `hh` therefore loses the
|
|
121
|
+
* hours rather than folding them into the minutes.
|
|
122
|
+
*
|
|
123
|
+
* Since `h`, `m`, `s` and `f` are tokens on their own, **every** occurrence of
|
|
124
|
+
* those letters is substituted, wherever it sits: `'mm min ss'` renders as
|
|
125
|
+
* `'01 1in 01'`. Separate the fields with punctuation. This is what
|
|
126
|
+
* `agnostic/time/dates/format-date` avoids by delimiting its tokens with
|
|
127
|
+
* `{{…}}` — worth aligning on the day this one is made public.
|
|
128
|
+
*/
|
|
108
129
|
export function formatTime(ms, format, fps = 25) {
|
|
109
130
|
const totalSeconds = Math.floor(ms / 1000);
|
|
110
131
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -123,17 +144,19 @@ export function formatTime(ms, format, fps = 25) {
|
|
|
123
144
|
s: seconds,
|
|
124
145
|
f: frames
|
|
125
146
|
};
|
|
126
|
-
|
|
147
|
+
return Object
|
|
127
148
|
.keys(tokens)
|
|
128
149
|
.sort((a, b) => b.length - a.length)
|
|
129
150
|
.reduce((acc, t) => acc.replace(new RegExp(t, 'gv'), String(tokens[t])), format);
|
|
130
|
-
return result;
|
|
131
151
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Where along the timeline a click landed.
|
|
154
|
+
*
|
|
155
|
+
* @param event - The click on the timeline element.
|
|
156
|
+
* @returns A ratio between `0` and `1`, clamped to the element's own bounds.
|
|
157
|
+
*/
|
|
158
|
+
export const getTimelineClickProgress = (event) => {
|
|
135
159
|
const timelineRect = event.currentTarget.getBoundingClientRect();
|
|
136
160
|
const position = event.clientX - timelineRect.left;
|
|
137
|
-
|
|
138
|
-
return progress;
|
|
161
|
+
return Math.min(1, Math.max(0, position / timelineRect.width));
|
|
139
162
|
};
|
package/components/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as beforeAfter from './BeforeAfter/index.js'
|
|
2
2
|
export * as button from './Button/index.js'
|
|
3
|
-
export * as disclaimer from './Disclaimer/index.js'
|
|
4
3
|
export * as clippable from './Clippable/index.js'
|
|
4
|
+
export * as disclaimer from './Disclaimer/index.js'
|
|
5
5
|
export * as drawer from './Drawer/index.js'
|
|
6
6
|
export * as eventListener from './EventListener/index.js'
|
|
7
7
|
export * as gallery from './Gallery/index.js'
|
package/components/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as beforeAfter from './BeforeAfter/index.js'
|
|
2
2
|
export * as button from './Button/index.js'
|
|
3
|
-
export * as disclaimer from './Disclaimer/index.js'
|
|
4
3
|
export * as clippable from './Clippable/index.js'
|
|
4
|
+
export * as disclaimer from './Disclaimer/index.js'
|
|
5
5
|
export * as drawer from './Drawer/index.js'
|
|
6
6
|
export * as eventListener from './EventListener/index.js'
|
|
7
7
|
export * as gallery from './Gallery/index.js'
|
|
@@ -1 +1,23 @@
|
|
|
1
1
|
export declare function mergeClassNames(...names: Array<string | null | undefined | Array<string | null | undefined>>): string;
|
|
2
|
+
/**
|
|
3
|
+
* Calls `onChange` whenever `value` changes, and only then — never on mount.
|
|
4
|
+
*
|
|
5
|
+
* This is how a component reports one of its state items to its consumer:
|
|
6
|
+
* a bare `useEffect` on the value would also fire on the first render, telling
|
|
7
|
+
* the consumer something changed when nothing did.
|
|
8
|
+
*
|
|
9
|
+
* @template T - Type of the watched value.
|
|
10
|
+
* @param value - The value to watch.
|
|
11
|
+
* @param onChange - Called with the new value, once the change has happened.
|
|
12
|
+
* @param isEqual - Decides whether the value actually changed. Defaults to
|
|
13
|
+
* `Object.is`, which covers booleans, numbers and strings. Pass a custom
|
|
14
|
+
* comparison for values rebuilt on every render, such as an array or an object
|
|
15
|
+
* derived from state, whose identity always differs.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* `onChange` is deliberately left out of the effect's dependencies. A consumer
|
|
19
|
+
* passing an inline arrow creates a new function on every render, which would
|
|
20
|
+
* re-run the effect each time and defeat the guard. The handler is read when the
|
|
21
|
+
* effect fires, so it is never a stale one.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useChangeDispatch<T>(value: T, onChange?: (value: T) => void, isEqual?: (a: T, b: T) => boolean): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
1
2
|
export function mergeClassNames(...names) {
|
|
2
3
|
return names.map(name => {
|
|
3
4
|
if (typeof name !== 'string' && !Array.isArray(name))
|
|
@@ -10,3 +11,33 @@ export function mergeClassNames(...names) {
|
|
|
10
11
|
}).filter((name) => typeof name === 'string')
|
|
11
12
|
.join(' ');
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Calls `onChange` whenever `value` changes, and only then — never on mount.
|
|
16
|
+
*
|
|
17
|
+
* This is how a component reports one of its state items to its consumer:
|
|
18
|
+
* a bare `useEffect` on the value would also fire on the first render, telling
|
|
19
|
+
* the consumer something changed when nothing did.
|
|
20
|
+
*
|
|
21
|
+
* @template T - Type of the watched value.
|
|
22
|
+
* @param value - The value to watch.
|
|
23
|
+
* @param onChange - Called with the new value, once the change has happened.
|
|
24
|
+
* @param isEqual - Decides whether the value actually changed. Defaults to
|
|
25
|
+
* `Object.is`, which covers booleans, numbers and strings. Pass a custom
|
|
26
|
+
* comparison for values rebuilt on every render, such as an array or an object
|
|
27
|
+
* derived from state, whose identity always differs.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* `onChange` is deliberately left out of the effect's dependencies. A consumer
|
|
31
|
+
* passing an inline arrow creates a new function on every render, which would
|
|
32
|
+
* re-run the effect each time and defeat the guard. The handler is read when the
|
|
33
|
+
* effect fires, so it is never a stale one.
|
|
34
|
+
*/
|
|
35
|
+
export function useChangeDispatch(value, onChange, isEqual = Object.is) {
|
|
36
|
+
const previousRef = useRef(value);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (isEqual(previousRef.current, value))
|
|
39
|
+
return;
|
|
40
|
+
previousRef.current = value;
|
|
41
|
+
onChange?.(value);
|
|
42
|
+
}, [value]);
|
|
43
|
+
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as copy from './copy/index.js'
|
|
2
|
-
export * as exists from './exists/index.js'
|
|
3
2
|
export * as download from './download/index.js'
|
|
3
|
+
export * as exists from './exists/index.js'
|
|
4
4
|
export * as move from './move/index.js'
|
|
5
5
|
export * as remove from './remove/index.js'
|
|
6
6
|
export * as stat from './stat/index.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as copy from './copy/index.js'
|
|
2
|
-
export * as exists from './exists/index.js'
|
|
3
2
|
export * as download from './download/index.js'
|
|
3
|
+
export * as exists from './exists/index.js'
|
|
4
4
|
export * as move from './move/index.js'
|
|
5
5
|
export * as remove from './remove/index.js'
|
|
6
6
|
export * as stat from './stat/index.js'
|
package/node/images/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as create from './create/index.js'
|
|
2
|
-
export * as metadata from './metadata/index.js'
|
|
3
2
|
export * as format from './format/index.js'
|
|
3
|
+
export * as metadata from './metadata/index.js'
|
|
4
4
|
export * as transform from './transform/index.js'
|
|
5
5
|
export * as utils from './utils/index.js'
|
package/node/images/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as create from './create/index.js'
|
|
2
|
-
export * as metadata from './metadata/index.js'
|
|
3
2
|
export * as format from './format/index.js'
|
|
3
|
+
export * as metadata from './metadata/index.js'
|
|
4
4
|
export * as transform from './transform/index.js'
|
|
5
5
|
export * as utils from './utils/index.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as blur from './blur/index.js'
|
|
2
|
-
export * as extend from './extend/index.js'
|
|
3
2
|
export * as brighten from './brighten/index.js'
|
|
3
|
+
export * as extend from './extend/index.js'
|
|
4
4
|
export * as extract from './extract/index.js'
|
|
5
5
|
export * as flatten from './flatten/index.js'
|
|
6
6
|
export * as flip from './flip/index.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as blur from './blur/index.js'
|
|
2
|
-
export * as extend from './extend/index.js'
|
|
3
2
|
export * as brighten from './brighten/index.js'
|
|
3
|
+
export * as extend from './extend/index.js'
|
|
4
4
|
export * as extract from './extract/index.js'
|
|
5
5
|
export * as flatten from './flatten/index.js'
|
|
6
6
|
export * as flip from './flip/index.js'
|
package/node/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export * as express from './@express/index.js'
|
|
|
4
4
|
export * as googleCloud from './@google-cloud/index.js'
|
|
5
5
|
export * as cloudStorage from './cloud-storage/index.js'
|
|
6
6
|
export * as encryption from './encryption/index.js'
|
|
7
|
-
export * as ftps from './ftps/index.js'
|
|
8
7
|
export * as files from './files/index.js'
|
|
8
|
+
export * as ftps from './ftps/index.js'
|
|
9
9
|
export * as images from './images/index.js'
|
|
10
10
|
export * as process from './process/index.js'
|
|
11
11
|
export * as sftp from './sftp/index.js'
|
package/node/index.js
CHANGED
|
@@ -4,8 +4,8 @@ export * as express from './@express/index.js'
|
|
|
4
4
|
export * as googleCloud from './@google-cloud/index.js'
|
|
5
5
|
export * as cloudStorage from './cloud-storage/index.js'
|
|
6
6
|
export * as encryption from './encryption/index.js'
|
|
7
|
-
export * as ftps from './ftps/index.js'
|
|
8
7
|
export * as files from './files/index.js'
|
|
8
|
+
export * as ftps from './ftps/index.js'
|
|
9
9
|
export * as images from './images/index.js'
|
|
10
10
|
export * as process from './process/index.js'
|
|
11
11
|
export * as sftp from './sftp/index.js'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design-edito/tools",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Maxime Fabas",
|
|
6
6
|
"license": "ISC",
|
|
@@ -1290,6 +1290,10 @@
|
|
|
1290
1290
|
"./agnostic/time/dates/format-date/index.js": {
|
|
1291
1291
|
"import": "./agnostic/time/dates/format-date/index.js"
|
|
1292
1292
|
},
|
|
1293
|
+
"./agnostic/time/dates/format-date/types.js": {
|
|
1294
|
+
"import": "./agnostic/time/dates/format-date/types.js",
|
|
1295
|
+
"types": "./agnostic/time/dates/format-date/types.d.ts"
|
|
1296
|
+
},
|
|
1293
1297
|
"./agnostic/time/dates/index.js": {
|
|
1294
1298
|
"import": "./agnostic/time/dates/index.js"
|
|
1295
1299
|
},
|
|
@@ -1308,6 +1312,17 @@
|
|
|
1308
1312
|
"import": "./agnostic/time/duration/index.js",
|
|
1309
1313
|
"types": "./agnostic/time/duration/index.d.ts"
|
|
1310
1314
|
},
|
|
1315
|
+
"./agnostic/time/duration/format-duration": {
|
|
1316
|
+
"import": "./agnostic/time/duration/format-duration/index.js",
|
|
1317
|
+
"types": "./agnostic/time/duration/format-duration/index.d.ts"
|
|
1318
|
+
},
|
|
1319
|
+
"./agnostic/time/duration/format-duration/index.js": {
|
|
1320
|
+
"import": "./agnostic/time/duration/format-duration/index.js"
|
|
1321
|
+
},
|
|
1322
|
+
"./agnostic/time/duration/format-duration/types.js": {
|
|
1323
|
+
"import": "./agnostic/time/duration/format-duration/types.js",
|
|
1324
|
+
"types": "./agnostic/time/duration/format-duration/types.d.ts"
|
|
1325
|
+
},
|
|
1311
1326
|
"./agnostic/time/duration/index.js": {
|
|
1312
1327
|
"import": "./agnostic/time/duration/index.js"
|
|
1313
1328
|
},
|
|
@@ -1451,6 +1466,10 @@
|
|
|
1451
1466
|
"./components/JsonEditor/index.js": {
|
|
1452
1467
|
"import": "./components/JsonEditor/index.js"
|
|
1453
1468
|
},
|
|
1469
|
+
"./components/JsonEditor/types.js": {
|
|
1470
|
+
"import": "./components/JsonEditor/types.js",
|
|
1471
|
+
"types": "./components/JsonEditor/types.d.ts"
|
|
1472
|
+
},
|
|
1454
1473
|
"./components/ListLoader": {
|
|
1455
1474
|
"import": "./components/ListLoader/index.js",
|
|
1456
1475
|
"types": "./components/ListLoader/index.d.ts"
|
|
@@ -1521,10 +1540,6 @@
|
|
|
1521
1540
|
"./components/Subtitles/index.js": {
|
|
1522
1541
|
"import": "./components/Subtitles/index.js"
|
|
1523
1542
|
},
|
|
1524
|
-
"./components/Subtitles/types.js": {
|
|
1525
|
-
"import": "./components/Subtitles/types.js",
|
|
1526
|
-
"types": "./components/Subtitles/types.d.ts"
|
|
1527
|
-
},
|
|
1528
1543
|
"./components/Textarea": {
|
|
1529
1544
|
"import": "./components/Textarea/index.js",
|
|
1530
1545
|
"types": "./components/Textarea/index.d.ts"
|