@design-edito/tools 0.5.19 → 0.5.21
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/colors/convert/index.js +0 -1
- package/agnostic/css/index.d.ts +1 -1
- package/agnostic/css/index.js +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +6 -6
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +6 -6
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +4 -4
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +4 -4
- package/agnostic/html/hyper-json/utils/index.js +1 -1
- package/agnostic/html/index.d.ts +2 -2
- package/agnostic/html/index.js +2 -2
- package/agnostic/index.d.ts +1 -1
- package/agnostic/index.js +1 -1
- package/agnostic/misc/index.d.ts +3 -3
- package/agnostic/misc/index.js +3 -3
- package/agnostic/misc/logs/index.d.ts +1 -1
- package/agnostic/misc/logs/index.js +1 -1
- package/agnostic/objects/index.d.ts +1 -1
- package/agnostic/objects/index.js +1 -1
- package/agnostic/random/index.d.ts +1 -1
- package/agnostic/random/index.js +1 -1
- package/agnostic/strings/index.d.ts +1 -1
- package/agnostic/strings/index.js +1 -1
- package/agnostic/time/index.d.ts +1 -1
- package/agnostic/time/index.js +1 -1
- package/components/Sequencer/index.d.ts +62 -81
- package/components/Sequencer/index.js +150 -98
- package/components/Video/index.d.ts +1 -1
- package/components/utils/viewport-behaviours/index.d.ts +25 -1
- package/components/utils/viewport-behaviours/index.js +35 -0
- package/components/utils/viewport-behaviours/utils.d.ts +0 -21
- package/components/utils/viewport-behaviours/utils.js +0 -31
- package/node/@aws-s3/storage/file/index.d.ts +1 -1
- package/node/@aws-s3/storage/file/index.js +1 -1
- package/node/@aws-s3/storage/index.d.ts +1 -1
- package/node/@aws-s3/storage/index.js +1 -1
- package/node/cloud-storage/operations/index.d.ts +1 -1
- package/node/cloud-storage/operations/index.js +1 -1
- package/package.json +1 -1
- package/components/Sequencer/index.controlled.d.ts +0 -68
- package/components/Sequencer/index.controlled.js +0 -70
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-type-assertion -- TransformedColor<C> can't be narrowed from a generic type param at compile time; every assertion here is guarded by an isX(...) runtime check immediately prior */
|
|
2
|
-
/* eslint-disable max-lines */
|
|
3
2
|
import { absoluteModulo } from '../../numbers/absolute-modulo/index.js';
|
|
4
3
|
import { tidy } from '../tidy/index.js';
|
|
5
4
|
import { cssColors } from '../cssColorsMap.js';
|
package/agnostic/css/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as bem from './bem/index.js'
|
|
2
2
|
export * as clss from './clss/index.js'
|
|
3
3
|
export * as generateNiceColor from './generate-nice-color/index.js'
|
|
4
|
-
export * as isValidCssClassName from './is-valid-css-class-name/index.js'
|
|
5
4
|
export * as scale from './scale/index.js'
|
|
5
|
+
export * as isValidCssClassName from './is-valid-css-class-name/index.js'
|
|
6
6
|
export * as stylesSet from './styles-set/index.js'
|
package/agnostic/css/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as bem from './bem/index.js'
|
|
2
2
|
export * as clss from './clss/index.js'
|
|
3
3
|
export * as generateNiceColor from './generate-nice-color/index.js'
|
|
4
|
-
export * as isValidCssClassName from './is-valid-css-class-name/index.js'
|
|
5
4
|
export * as scale from './scale/index.js'
|
|
5
|
+
export * as isValidCssClassName from './is-valid-css-class-name/index.js'
|
|
6
6
|
export * as stylesSet from './styles-set/index.js'
|
|
@@ -4,24 +4,24 @@ export * as and from './and/index.js'
|
|
|
4
4
|
export * as append from './append/index.js'
|
|
5
5
|
export * as at from './at/index.js'
|
|
6
6
|
export * as call from './call/index.js'
|
|
7
|
+
export * as clone from './clone/index.js'
|
|
7
8
|
export * as deleteproperties from './deleteproperties/index.js'
|
|
8
9
|
export * as equals from './equals/index.js'
|
|
9
|
-
export * as clone from './clone/index.js'
|
|
10
10
|
export * as getattribute from './getattribute/index.js'
|
|
11
11
|
export * as getproperties from './getproperties/index.js'
|
|
12
12
|
export * as getproperty from './getproperty/index.js'
|
|
13
13
|
export * as hjparse from './hjparse/index.js'
|
|
14
14
|
export * as hjstringify from './hjstringify/index.js'
|
|
15
15
|
export * as if from './if/index.js'
|
|
16
|
-
export * as length from './length/index.js'
|
|
17
16
|
export * as initialize from './initialize/index.js'
|
|
18
|
-
export * as
|
|
17
|
+
export * as length from './length/index.js'
|
|
19
18
|
export * as map from './map/index.js'
|
|
20
19
|
export * as negate from './negate/index.js'
|
|
21
20
|
export * as notrailing from './notrailing/index.js'
|
|
22
21
|
export * as or from './or/index.js'
|
|
23
22
|
export * as pickrandom from './pickrandom/index.js'
|
|
24
23
|
export * as populate from './populate/index.js'
|
|
24
|
+
export * as join from './join/index.js'
|
|
25
25
|
export * as print from './print/index.js'
|
|
26
26
|
export * as push from './push/index.js'
|
|
27
27
|
export * as pusheach from './pusheach/index.js'
|
|
@@ -37,16 +37,16 @@ export * as setproperty from './setproperty/index.js'
|
|
|
37
37
|
export * as sorton from './sorton/index.js'
|
|
38
38
|
export * as split from './split/index.js'
|
|
39
39
|
export * as spread from './spread/index.js'
|
|
40
|
-
export * as toboolean from './toboolean/index.js'
|
|
41
40
|
export * as toarray from './toarray/index.js'
|
|
41
|
+
export * as toboolean from './toboolean/index.js'
|
|
42
42
|
export * as toelement from './toelement/index.js'
|
|
43
43
|
export * as toggleclass from './toggleclass/index.js'
|
|
44
|
+
export * as tonodelist from './tonodelist/index.js'
|
|
44
45
|
export * as tonull from './tonull/index.js'
|
|
45
46
|
export * as tonumber from './tonumber/index.js'
|
|
46
|
-
export * as tonodelist from './tonodelist/index.js'
|
|
47
47
|
export * as torecord from './torecord/index.js'
|
|
48
48
|
export * as toref from './toref/index.js'
|
|
49
49
|
export * as tostring from './tostring/index.js'
|
|
50
|
+
export * as totext from './totext/index.js'
|
|
50
51
|
export * as transformselected from './transformselected/index.js'
|
|
51
52
|
export * as trim from './trim/index.js'
|
|
52
|
-
export * as totext from './totext/index.js'
|
|
@@ -4,24 +4,24 @@ export * as and from './and/index.js'
|
|
|
4
4
|
export * as append from './append/index.js'
|
|
5
5
|
export * as at from './at/index.js'
|
|
6
6
|
export * as call from './call/index.js'
|
|
7
|
+
export * as clone from './clone/index.js'
|
|
7
8
|
export * as deleteproperties from './deleteproperties/index.js'
|
|
8
9
|
export * as equals from './equals/index.js'
|
|
9
|
-
export * as clone from './clone/index.js'
|
|
10
10
|
export * as getattribute from './getattribute/index.js'
|
|
11
11
|
export * as getproperties from './getproperties/index.js'
|
|
12
12
|
export * as getproperty from './getproperty/index.js'
|
|
13
13
|
export * as hjparse from './hjparse/index.js'
|
|
14
14
|
export * as hjstringify from './hjstringify/index.js'
|
|
15
15
|
export * as if from './if/index.js'
|
|
16
|
-
export * as length from './length/index.js'
|
|
17
16
|
export * as initialize from './initialize/index.js'
|
|
18
|
-
export * as
|
|
17
|
+
export * as length from './length/index.js'
|
|
19
18
|
export * as map from './map/index.js'
|
|
20
19
|
export * as negate from './negate/index.js'
|
|
21
20
|
export * as notrailing from './notrailing/index.js'
|
|
22
21
|
export * as or from './or/index.js'
|
|
23
22
|
export * as pickrandom from './pickrandom/index.js'
|
|
24
23
|
export * as populate from './populate/index.js'
|
|
24
|
+
export * as join from './join/index.js'
|
|
25
25
|
export * as print from './print/index.js'
|
|
26
26
|
export * as push from './push/index.js'
|
|
27
27
|
export * as pusheach from './pusheach/index.js'
|
|
@@ -37,16 +37,16 @@ export * as setproperty from './setproperty/index.js'
|
|
|
37
37
|
export * as sorton from './sorton/index.js'
|
|
38
38
|
export * as split from './split/index.js'
|
|
39
39
|
export * as spread from './spread/index.js'
|
|
40
|
-
export * as toboolean from './toboolean/index.js'
|
|
41
40
|
export * as toarray from './toarray/index.js'
|
|
41
|
+
export * as toboolean from './toboolean/index.js'
|
|
42
42
|
export * as toelement from './toelement/index.js'
|
|
43
43
|
export * as toggleclass from './toggleclass/index.js'
|
|
44
|
+
export * as tonodelist from './tonodelist/index.js'
|
|
44
45
|
export * as tonull from './tonull/index.js'
|
|
45
46
|
export * as tonumber from './tonumber/index.js'
|
|
46
|
-
export * as tonodelist from './tonodelist/index.js'
|
|
47
47
|
export * as torecord from './torecord/index.js'
|
|
48
48
|
export * as toref from './toref/index.js'
|
|
49
49
|
export * as tostring from './tostring/index.js'
|
|
50
|
+
export * as totext from './totext/index.js'
|
|
50
51
|
export * as transformselected from './transformselected/index.js'
|
|
51
52
|
export * as trim from './trim/index.js'
|
|
52
|
-
export * as totext from './totext/index.js'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * as array from './array/index.js'
|
|
2
1
|
export * as any from './any/index.js'
|
|
2
|
+
export * as array from './array/index.js'
|
|
3
|
+
export * as boolean from './boolean/index.js'
|
|
3
4
|
export * as element from './element/index.js'
|
|
4
5
|
export * as get from './get/index.js'
|
|
5
|
-
export * as nodelist from './nodelist/index.js'
|
|
6
6
|
export * as guess from './guess/index.js'
|
|
7
|
+
export * as nodelist from './nodelist/index.js'
|
|
7
8
|
export * as null from './null/index.js'
|
|
8
|
-
export * as boolean from './boolean/index.js'
|
|
9
9
|
export * as number from './number/index.js'
|
|
10
10
|
export * as record from './record/index.js'
|
|
11
|
-
export * as string from './string/index.js'
|
|
12
11
|
export * as ref from './ref/index.js'
|
|
12
|
+
export * as string from './string/index.js'
|
|
13
13
|
export * as text from './text/index.js'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * as array from './array/index.js'
|
|
2
1
|
export * as any from './any/index.js'
|
|
2
|
+
export * as array from './array/index.js'
|
|
3
|
+
export * as boolean from './boolean/index.js'
|
|
3
4
|
export * as element from './element/index.js'
|
|
4
5
|
export * as get from './get/index.js'
|
|
5
|
-
export * as nodelist from './nodelist/index.js'
|
|
6
6
|
export * as guess from './guess/index.js'
|
|
7
|
+
export * as nodelist from './nodelist/index.js'
|
|
7
8
|
export * as null from './null/index.js'
|
|
8
|
-
export * as boolean from './boolean/index.js'
|
|
9
9
|
export * as number from './number/index.js'
|
|
10
10
|
export * as record from './record/index.js'
|
|
11
|
-
export * as string from './string/index.js'
|
|
12
11
|
export * as ref from './ref/index.js'
|
|
12
|
+
export * as string from './string/index.js'
|
|
13
13
|
export * as text from './text/index.js'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* eslint-disable
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-type-assertion -- generic type params (T/K/Value) and DOM NodeList casts here can't be narrowed from a generic/runtime check at compile time; guarded by runtime typeCheck(s)/instanceof checks immediately prior */
|
|
2
2
|
import * as Window from '../../../misc/crossenv/window/index.js';
|
|
3
3
|
import { isRecord } from '../../../objects/is-record/index.js';
|
|
4
4
|
import { recordMap } from '../../../objects/record-map/index.js';
|
package/agnostic/html/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * as deepSelect from './deep-select/index.js'
|
|
2
2
|
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
3
3
|
export * as getPositionInsideParent from './get-position-inside-parent/index.js'
|
|
4
|
-
export * as insertNode from './insert-node/index.js'
|
|
5
4
|
export * as hyperJson from './hyper-json/index.js'
|
|
5
|
+
export * as insertNode from './insert-node/index.js'
|
|
6
|
+
export * as placeholders from './placeholders/index.js'
|
|
6
7
|
export * as replaceInElement from './replace-in-element/index.js'
|
|
7
8
|
export * as selectorToElement from './selector-to-element/index.js'
|
|
8
|
-
export * as placeholders from './placeholders/index.js'
|
|
9
9
|
export * as stringToNodes from './string-to-nodes/index.js'
|
|
10
10
|
export * as watchSelection from './watch-selection/index.js'
|
package/agnostic/html/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * as deepSelect from './deep-select/index.js'
|
|
2
2
|
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
3
3
|
export * as getPositionInsideParent from './get-position-inside-parent/index.js'
|
|
4
|
-
export * as insertNode from './insert-node/index.js'
|
|
5
4
|
export * as hyperJson from './hyper-json/index.js'
|
|
5
|
+
export * as insertNode from './insert-node/index.js'
|
|
6
|
+
export * as placeholders from './placeholders/index.js'
|
|
6
7
|
export * as replaceInElement from './replace-in-element/index.js'
|
|
7
8
|
export * as selectorToElement from './selector-to-element/index.js'
|
|
8
|
-
export * as placeholders from './placeholders/index.js'
|
|
9
9
|
export * as stringToNodes from './string-to-nodes/index.js'
|
|
10
10
|
export * as watchSelection from './watch-selection/index.js'
|
package/agnostic/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as arrays from './arrays/index.js'
|
|
2
|
-
export * as booleans from './booleans/index.js'
|
|
3
2
|
export * as colors from './colors/index.js'
|
|
3
|
+
export * as booleans from './booleans/index.js'
|
|
4
4
|
export * as css from './css/index.js'
|
|
5
5
|
export * as errors from './errors/index.js'
|
|
6
6
|
export * as html from './html/index.js'
|
package/agnostic/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as arrays from './arrays/index.js'
|
|
2
|
-
export * as booleans from './booleans/index.js'
|
|
3
2
|
export * as colors from './colors/index.js'
|
|
3
|
+
export * as booleans from './booleans/index.js'
|
|
4
4
|
export * as css from './css/index.js'
|
|
5
5
|
export * as errors from './errors/index.js'
|
|
6
6
|
export * as html from './html/index.js'
|
package/agnostic/misc/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * as assert from './assert/index.js'
|
|
2
2
|
export * as cast from './cast/index.js'
|
|
3
|
+
export * as connection from './connection/index.js'
|
|
3
4
|
export * as crawler from './crawler/index.js'
|
|
4
5
|
export * as crossenv from './crossenv/index.js'
|
|
5
|
-
export * as connection from './connection/index.js'
|
|
6
|
-
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
7
6
|
export * as dataSize from './data-size/index.js'
|
|
7
|
+
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
8
8
|
export * as isNullish from './is-nullish/index.js'
|
|
9
|
-
export * as logs from './logs/index.js'
|
|
10
9
|
export * as loremIpsum from './lorem-ipsum/index.js'
|
|
10
|
+
export * as logs from './logs/index.js'
|
|
11
11
|
export * as normalizeExtension from './normalize-extension/index.js'
|
|
12
12
|
export * as outcome from './outcome/index.js'
|
package/agnostic/misc/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * as assert from './assert/index.js'
|
|
2
2
|
export * as cast from './cast/index.js'
|
|
3
|
+
export * as connection from './connection/index.js'
|
|
3
4
|
export * as crawler from './crawler/index.js'
|
|
4
5
|
export * as crossenv from './crossenv/index.js'
|
|
5
|
-
export * as connection from './connection/index.js'
|
|
6
|
-
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
7
6
|
export * as dataSize from './data-size/index.js'
|
|
7
|
+
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
8
8
|
export * as isNullish from './is-nullish/index.js'
|
|
9
|
-
export * as logs from './logs/index.js'
|
|
10
9
|
export * as loremIpsum from './lorem-ipsum/index.js'
|
|
10
|
+
export * as logs from './logs/index.js'
|
|
11
11
|
export * as normalizeExtension from './normalize-extension/index.js'
|
|
12
12
|
export * as outcome from './outcome/index.js'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * as deepGetProperty from './deep-get-property/index.js'
|
|
2
2
|
export * as enums from './enums/index.js'
|
|
3
3
|
export * as flattenGetters from './flatten-getters/index.js'
|
|
4
|
+
export * as isObject from './is-object/index.js'
|
|
4
5
|
export * as isRecord from './is-record/index.js'
|
|
5
6
|
export * as recordFormat from './record-format/index.js'
|
|
6
|
-
export * as isObject from './is-object/index.js'
|
|
7
7
|
export * as recordMap from './record-map/index.js'
|
|
8
8
|
export * as sortKeys from './sort-keys/index.js'
|
|
9
9
|
export * as validation from './validation/index.js'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * as deepGetProperty from './deep-get-property/index.js'
|
|
2
2
|
export * as enums from './enums/index.js'
|
|
3
3
|
export * as flattenGetters from './flatten-getters/index.js'
|
|
4
|
+
export * as isObject from './is-object/index.js'
|
|
4
5
|
export * as isRecord from './is-record/index.js'
|
|
5
6
|
export * as recordFormat from './record-format/index.js'
|
|
6
|
-
export * as isObject from './is-object/index.js'
|
|
7
7
|
export * as recordMap from './record-map/index.js'
|
|
8
8
|
export * as sortKeys from './sort-keys/index.js'
|
|
9
9
|
export * as validation from './validation/index.js'
|
package/agnostic/random/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as charCodes from './char-codes/index.js'
|
|
2
|
+
export * as matches from './matches/index.js'
|
|
2
3
|
export * as normalizeIndent from './normalize-indent/index.js'
|
|
3
4
|
export * as parseTable from './parse-table/index.js'
|
|
4
|
-
export * as matches from './matches/index.js'
|
|
5
5
|
export * as replaceAll from './replace-all/index.js'
|
|
6
6
|
export * as splitTrim from './split-trim/index.js'
|
|
7
7
|
export * as toAlphanum from './to-alphanum/index.js'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as charCodes from './char-codes/index.js'
|
|
2
|
+
export * as matches from './matches/index.js'
|
|
2
3
|
export * as normalizeIndent from './normalize-indent/index.js'
|
|
3
4
|
export * as parseTable from './parse-table/index.js'
|
|
4
|
-
export * as matches from './matches/index.js'
|
|
5
5
|
export * as replaceAll from './replace-all/index.js'
|
|
6
6
|
export * as splitTrim from './split-trim/index.js'
|
|
7
7
|
export * as toAlphanum from './to-alphanum/index.js'
|
package/agnostic/time/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export * as dates from './dates/index.js'
|
|
1
2
|
export * as duration from './duration/index.js'
|
|
2
3
|
export * as timeout from './timeout/index.js'
|
|
3
|
-
export * as dates from './dates/index.js'
|
|
4
4
|
export * as transitions from './transitions/index.js'
|
|
5
5
|
export * as wait from './wait/index.js'
|
package/agnostic/time/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export * as dates from './dates/index.js'
|
|
1
2
|
export * as duration from './duration/index.js'
|
|
2
3
|
export * as timeout from './timeout/index.js'
|
|
3
|
-
export * as dates from './dates/index.js'
|
|
4
4
|
export * as transitions from './transitions/index.js'
|
|
5
5
|
export * as wait from './wait/index.js'
|
|
@@ -1,97 +1,78 @@
|
|
|
1
|
-
import { type FunctionComponent } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import type { ViewportObserverOptions } from '../utils/types.js';
|
|
4
|
-
import { type Props as ControlledProps } from './index.controlled.js';
|
|
1
|
+
import { type FunctionComponent, type PropsWithChildren } from 'react';
|
|
2
|
+
import type { WithClassName } from '../utils/types.js';
|
|
5
3
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @property
|
|
18
|
-
* play
|
|
19
|
-
*
|
|
20
|
-
* it
|
|
21
|
-
* @property
|
|
22
|
-
*
|
|
23
|
-
* @property
|
|
24
|
-
*
|
|
25
|
-
* @property
|
|
26
|
-
*
|
|
27
|
-
* @property
|
|
28
|
-
*
|
|
29
|
-
* @property
|
|
30
|
-
*
|
|
31
|
-
* @property
|
|
32
|
-
*
|
|
33
|
-
* @property
|
|
34
|
-
* counts as visible, forwarded to the internal {@link IntersectionObserver}.
|
|
35
|
-
* @property root - The observer's root. Defaults to the viewport.
|
|
36
|
-
* @property rootMargin - Grows or shrinks that root before measuring.
|
|
37
|
-
* @property onVisibilityChanged - Called on every crossing with the new value.
|
|
38
|
-
* `onIntersected` is the raw form of the same event, carrying the entry and the
|
|
39
|
-
* observer; this one carries the answer.
|
|
40
|
-
* @property onIntersected - Forwarded verbatim to the internal
|
|
41
|
-
* {@link IntersectionObserverComponent}, and called on every intersection
|
|
42
|
-
* change whichever mode the sequencer runs in.
|
|
43
|
-
* @property onIsPlayingChanged - Called after the effective play state changed,
|
|
44
|
-
* with the new value.
|
|
45
|
-
* @property onStepChanged - Called after the forwarded step changed, with the
|
|
46
|
-
* new value.
|
|
47
|
-
* @property onLooped - Called when the step wraps around (either direction),
|
|
48
|
-
* only while `loop` is `true`.
|
|
49
|
-
* @property onReachedFirstStep - Called when the forwarded step becomes `0`.
|
|
50
|
-
* @property onReachedLastStep - Called when the forwarded step becomes the last
|
|
51
|
-
* one.
|
|
4
|
+
* @property totalSteps - How many steps the sequence has. Falls back to the number of
|
|
5
|
+
* **element** children: text and whitespace never count, which matters more than it
|
|
6
|
+
* looks — an article writes its children across several lines, and a text node counting
|
|
7
|
+
* as a step would put every index out by one.
|
|
8
|
+
* @property stepMap - Rewrites what a position means, **by position and nothing else**:
|
|
9
|
+
* at position `i` the active step is `stepMap[i]` when there is one, and `i` otherwise.
|
|
10
|
+
* `[2, 6, 7]` over seven steps plays `2, 6, 7, 3, 4, 5, 6` — a step may be skipped, may
|
|
11
|
+
* come back, and may not correspond to any child at all, in which case nothing lights up
|
|
12
|
+
* and that is a legal thing to write.
|
|
13
|
+
* @property step - The position, taken over by the consumer. Provided, the tempo stops
|
|
14
|
+
* advancing anything: the counter is theirs.
|
|
15
|
+
* @property defaultStep - The position to start from. Ignored when `step` is provided.
|
|
16
|
+
* @property play - Whether the sequence advances. **There are no controls in this
|
|
17
|
+
* component** — nothing to click, so nothing to surrender to — and this is the only way
|
|
18
|
+
* it moves on its own.
|
|
19
|
+
* @property tempo - Speed in beats per minute: one step every `60000 / tempo` ms, so `60`
|
|
20
|
+
* is a step per second. Clamped to a minimum of `1`.
|
|
21
|
+
* @property loop - Whether the sequence wraps round. **`false` by default**, so a
|
|
22
|
+
* sequence ends the way a video does rather than running forever.
|
|
23
|
+
* @property onStepChanged - Called when the position changes, with the position and the
|
|
24
|
+
* active step it resolves to. Never on mount.
|
|
25
|
+
* @property onIsPlayingChanged - Called once the effective play state changed — which
|
|
26
|
+
* includes it dropping to `false` on its own at the end.
|
|
27
|
+
* @property onIsEndedChanged - Called when the sequence reaches its last step, or leaves
|
|
28
|
+
* it. A looping sequence never ends, so never emits.
|
|
29
|
+
* @property onLooped - Called on each wrap, only while `loop` is `true`.
|
|
30
|
+
* @property onReachedFirstStep - Called when the position becomes `0`.
|
|
31
|
+
* @property onReachedLastStep - Called when the position becomes the last one.
|
|
52
32
|
*/
|
|
53
|
-
export type Props =
|
|
33
|
+
export type Props = PropsWithChildren<WithClassName<{
|
|
34
|
+
totalSteps?: number;
|
|
35
|
+
stepMap?: number[];
|
|
36
|
+
step?: number;
|
|
54
37
|
defaultStep?: number;
|
|
55
|
-
tempo?: number;
|
|
56
38
|
play?: boolean;
|
|
39
|
+
tempo?: number;
|
|
57
40
|
loop?: boolean;
|
|
58
|
-
|
|
59
|
-
clampLast?: boolean;
|
|
60
|
-
resetOnVisible?: boolean;
|
|
61
|
-
resetOnHidden?: boolean;
|
|
62
|
-
playOnVisible?: boolean;
|
|
63
|
-
pauseOnHidden?: boolean;
|
|
64
|
-
onIntersected?: IOCompProps['onIntersected'];
|
|
65
|
-
onVisibilityChanged?: (isVisible: boolean) => void;
|
|
41
|
+
onStepChanged?: (step: number, activeStep: number) => void;
|
|
66
42
|
onIsPlayingChanged?: (isPlaying: boolean) => void;
|
|
67
|
-
|
|
43
|
+
onIsEndedChanged?: (isEnded: boolean) => void;
|
|
68
44
|
onLooped?: () => void;
|
|
69
45
|
onReachedFirstStep?: () => void;
|
|
70
46
|
onReachedLastStep?: () => void;
|
|
71
|
-
}
|
|
47
|
+
}>>;
|
|
72
48
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
49
|
+
* A sequencer over its children, which it classifies and never moves.
|
|
50
|
+
*
|
|
51
|
+
* It renders no box of its own around anything: **the modifiers go straight onto the
|
|
52
|
+
* children**, by `cloneElement`. A wrapper would take the place a consumer lays out —
|
|
53
|
+
* it would be the grid or flex item, leaving the element they actually wrote one level
|
|
54
|
+
* down — and a sequencer exists precisely so that a stylesheet can animate that element.
|
|
55
|
+
* The cost is the contract: **a child has to honour `className`**, which every DOM
|
|
56
|
+
* element does, and every component here does by convention. One that ignores it gets no
|
|
57
|
+
* modifiers, silently.
|
|
77
58
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* to the controlled layer. Passing `play` disables internal play state management
|
|
81
|
-
* while still allowing viewport handlers to fire `onIntersected`.
|
|
59
|
+
* Children that are not elements — text, whitespace — are rendered untouched and take no
|
|
60
|
+
* part: they carry no class, so they simply stay visible throughout.
|
|
82
61
|
*
|
|
83
|
-
* ###
|
|
84
|
-
* -
|
|
85
|
-
* -
|
|
86
|
-
* - `tempo` — the current tempo, which the controlled layer exposes as `data-tempo`.
|
|
62
|
+
* ### On the root
|
|
63
|
+
* `--playing`, `--at-start`, `--at-end`, `--ended`, plus `data-step`, `data-active-step`,
|
|
64
|
+
* `data-total-steps` and `data-tempo`.
|
|
87
65
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
66
|
+
* ### On each element child
|
|
67
|
+
* The `__child` element class, then three pairs, one of each always present:
|
|
68
|
+
* - `--on` / `--off` — whether it belongs to the active step.
|
|
69
|
+
* - `--is-first` / `--not-first` — whether its first turn in this lap is still to come.
|
|
70
|
+
* - `--is-last` / `--not-last` — whether it has another turn left in this lap.
|
|
90
71
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
72
|
+
* **The three pairs are derived, not remembered.** The order of the whole lap is known
|
|
73
|
+
* from `stepMap` alone, so « has it been shown yet » is a question about positions before
|
|
74
|
+
* this one, not about what happened since mount. A child active at positions 1 and 6 is
|
|
75
|
+
* therefore `--is-first` at 1 and `--not-first` at 6, and the answer is the same on every
|
|
76
|
+
* lap without anything being reset.
|
|
96
77
|
*/
|
|
97
78
|
export declare const Sequencer: FunctionComponent<Props>;
|
|
@@ -1,116 +1,168 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Children, cloneElement, isValidElement, useEffect, useState } from 'react';
|
|
3
3
|
import { absoluteModulo } from '../../agnostic/numbers/absolute-modulo/index.js';
|
|
4
4
|
import { clamp } from '../../agnostic/numbers/clamp/index.js';
|
|
5
|
-
import {
|
|
6
|
-
import { useChangeDispatch } from '../utils/index.js';
|
|
7
|
-
import {
|
|
5
|
+
import { clss } from '../../agnostic/css/clss/index.js';
|
|
6
|
+
import { mergeClassNames, useChangeDispatch } from '../utils/index.js';
|
|
7
|
+
import { sequencer as publicClassName } from '../public-classnames.js';
|
|
8
|
+
import cssModule from './styles.module.css';
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
* {@link ControlledSequencer} instance with an internal tempo-based interval,
|
|
11
|
-
* optional loop/clamp boundary behaviour, and viewport-driven play/reset triggers
|
|
12
|
-
* via an {@link IntersectionObserverComponent}.
|
|
10
|
+
* The attribute a child uses to say which steps it belongs to.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
12
|
+
* **Written on the child rather than gathered in a prop**, and that is the whole
|
|
13
|
+
* difference with the `activateOnStep` this component used to take. A parallel array and
|
|
14
|
+
* a children list derive from one another: inserting a child in the middle means
|
|
15
|
+
* reindexing the array, and nothing signals the one time it is forgotten. Carried by the
|
|
16
|
+
* child, the attachment travels with it.
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
* It stays in the DOM once read — it costs nothing, it is worth having while debugging,
|
|
19
|
+
* and a stylesheet can select on it.
|
|
20
|
+
*/
|
|
21
|
+
const STEPS_ATTRIBUTE = 'data-steps';
|
|
22
|
+
/**
|
|
23
|
+
* `data-steps="2, 6"` into the steps it names.
|
|
24
|
+
*
|
|
25
|
+
* Anything unreadable gives back `null`, which the caller reads as « the attribute was
|
|
26
|
+
* not written » and falls back to the child's position. That is lm-link's rule applied
|
|
27
|
+
* here — a typo costs the default behaviour, never a broken one.
|
|
28
|
+
*/
|
|
29
|
+
function parseSteps(raw) {
|
|
30
|
+
if (typeof raw !== 'string')
|
|
31
|
+
return null;
|
|
32
|
+
const parts = raw.split(',').map(part => part.trim()).filter(part => part !== '');
|
|
33
|
+
if (parts.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
const steps = parts.map(Number);
|
|
36
|
+
if (steps.some(step => !Number.isInteger(step)))
|
|
37
|
+
return null;
|
|
38
|
+
return steps;
|
|
39
|
+
}
|
|
40
|
+
/** The steps a child answers to: what it declares, or where it sits. */
|
|
41
|
+
function stepsOf(child, elementIndex) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- a React element's props are a record, whatever else they are
|
|
43
|
+
const declared = parseSteps(child.props[STEPS_ATTRIBUTE]);
|
|
44
|
+
return declared ?? [elementIndex];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A sequencer over its children, which it classifies and never moves.
|
|
48
|
+
*
|
|
49
|
+
* It renders no box of its own around anything: **the modifiers go straight onto the
|
|
50
|
+
* children**, by `cloneElement`. A wrapper would take the place a consumer lays out —
|
|
51
|
+
* it would be the grid or flex item, leaving the element they actually wrote one level
|
|
52
|
+
* down — and a sequencer exists precisely so that a stylesheet can animate that element.
|
|
53
|
+
* The cost is the contract: **a child has to honour `className`**, which every DOM
|
|
54
|
+
* element does, and every component here does by convention. One that ignores it gets no
|
|
55
|
+
* modifiers, silently.
|
|
56
|
+
*
|
|
57
|
+
* Children that are not elements — text, whitespace — are rendered untouched and take no
|
|
58
|
+
* part: they carry no class, so they simply stay visible throughout.
|
|
23
59
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
60
|
+
* ### On the root
|
|
61
|
+
* `--playing`, `--at-start`, `--at-end`, `--ended`, plus `data-step`, `data-active-step`,
|
|
62
|
+
* `data-total-steps` and `data-tempo`.
|
|
26
63
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
64
|
+
* ### On each element child
|
|
65
|
+
* The `__child` element class, then three pairs, one of each always present:
|
|
66
|
+
* - `--on` / `--off` — whether it belongs to the active step.
|
|
67
|
+
* - `--is-first` / `--not-first` — whether its first turn in this lap is still to come.
|
|
68
|
+
* - `--is-last` / `--not-last` — whether it has another turn left in this lap.
|
|
69
|
+
*
|
|
70
|
+
* **The three pairs are derived, not remembered.** The order of the whole lap is known
|
|
71
|
+
* from `stepMap` alone, so « has it been shown yet » is a question about positions before
|
|
72
|
+
* this one, not about what happened since mount. A child active at positions 1 and 6 is
|
|
73
|
+
* therefore `--is-first` at 1 and `--not-first` at 6, and the answer is the same on every
|
|
74
|
+
* lap without anything being reset.
|
|
32
75
|
*/
|
|
33
|
-
export const Sequencer = ({
|
|
34
|
-
// State
|
|
35
|
-
const { step, activateOnStep, children } = controlledProps;
|
|
36
|
-
const [internalPlay, setInternalPlay] = useState(play ?? false);
|
|
76
|
+
export const Sequencer = ({ totalSteps, stepMap, step, defaultStep, play, tempo = 60, loop, onStepChanged, onIsPlayingChanged, onIsEndedChanged, onLooped, onReachedFirstStep, onReachedLastStep, className, children }) => {
|
|
37
77
|
const [internalStep, setInternalStep] = useState(step ?? defaultStep ?? 0);
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
78
|
+
const [hasLapped, setHasLapped] = useState(0);
|
|
79
|
+
// Children, split once: what takes part and what merely renders.
|
|
80
|
+
const childrenArr = Children.toArray(children);
|
|
81
|
+
const elements = childrenArr.filter(isValidElement);
|
|
82
|
+
const stepsCount = Math.max(totalSteps ?? elements.length, 0);
|
|
83
|
+
// The two numbers
|
|
84
|
+
const rawStep = step ?? internalStep;
|
|
85
|
+
const position = stepsCount > 0
|
|
86
|
+
? (loop === true
|
|
87
|
+
? absoluteModulo(rawStep, stepsCount)
|
|
88
|
+
: clamp(rawStep, 0, stepsCount - 1))
|
|
89
|
+
: 0;
|
|
90
|
+
const activeStep = stepMap?.[position] ?? position;
|
|
91
|
+
// A sequence that does not loop stops on its last step, and says so rather than
|
|
92
|
+
// claiming to still be playing. Derived rather than held: nothing has to be unset when
|
|
93
|
+
// `loop` or `step` changes under it.
|
|
94
|
+
const isEnded = loop !== true && stepsCount > 0 && position >= stepsCount - 1;
|
|
95
|
+
const isPlaying = (play ?? false) && !isEnded;
|
|
41
96
|
useEffect(() => {
|
|
42
|
-
|
|
43
|
-
if (!actualPlay || step !== undefined)
|
|
97
|
+
if (!isPlaying || step !== undefined || stepsCount <= 0)
|
|
44
98
|
return;
|
|
45
|
-
const interval = window.setInterval(() =>
|
|
46
|
-
setInternalStep(s => s + 1);
|
|
47
|
-
}, 1000 / (clampedTempo / 60));
|
|
99
|
+
const interval = window.setInterval(() => setInternalStep(current => current + 1), 60000 / Math.max(tempo, 1));
|
|
48
100
|
return () => window.clearInterval(interval);
|
|
49
|
-
}, [
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
: Children.toArray(children).length;
|
|
54
|
-
let forwardedStep;
|
|
55
|
-
if (loop === true) {
|
|
56
|
-
forwardedStep = absoluteModulo(actualStep, stepsCount);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
const leftClamp = clampFirst === true ? 0 : -Infinity;
|
|
60
|
-
const rightClamp = clampLast === true ? stepsCount - 1 : Infinity;
|
|
61
|
-
forwardedStep = clamp(actualStep, leftClamp, rightClamp);
|
|
62
|
-
}
|
|
63
|
-
// State dispatch
|
|
64
|
-
useChangeDispatch(actualPlay, onIsPlayingChanged);
|
|
65
|
-
useChangeDispatch(forwardedStep, onStepChanged);
|
|
66
|
-
// Fx. dep. `forwardedStep` - loop / boundary events
|
|
67
|
-
const previousStepsRef = useRef(null);
|
|
101
|
+
}, [isPlaying, step, stepsCount, tempo]);
|
|
102
|
+
// A lap counter rather than a comparison of steps: `onLooped` has to fire on the wrap
|
|
103
|
+
// itself, and the position on either side of it says nothing about having crossed.
|
|
104
|
+
const lap = stepsCount > 0 ? Math.floor(rawStep / stepsCount) : 0;
|
|
68
105
|
useEffect(() => {
|
|
69
|
-
if (
|
|
106
|
+
if (loop !== true)
|
|
70
107
|
return;
|
|
71
|
-
|
|
72
|
-
previousStepsRef.current = { forwarded: forwardedStep, actual: actualStep };
|
|
73
|
-
if (previous === null)
|
|
108
|
+
if (lap === hasLapped)
|
|
74
109
|
return;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const { isIntersecting } = ioEntry ?? {};
|
|
87
|
-
if (isIntersecting !== undefined)
|
|
88
|
-
onVisibilityChanged?.(isIntersecting);
|
|
89
|
-
// Both handlers fire whatever the mode: a controlled sequencer still wants to
|
|
90
|
-
// hear about the viewport, it just doesn't let it drive the step.
|
|
91
|
-
if (play === true || step !== undefined)
|
|
92
|
-
return;
|
|
93
|
-
if (isIntersecting === true) {
|
|
94
|
-
if (resetOnVisible === true)
|
|
95
|
-
setInternalStep(0);
|
|
96
|
-
if (playOnVisible === true)
|
|
97
|
-
setInternalPlay(true);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
if (resetOnHidden === true)
|
|
101
|
-
setInternalStep(0);
|
|
102
|
-
if (pauseOnHidden === true)
|
|
103
|
-
setInternalPlay(false);
|
|
104
|
-
}
|
|
105
|
-
}, [
|
|
106
|
-
resetOnVisible,
|
|
107
|
-
playOnVisible,
|
|
108
|
-
resetOnHidden,
|
|
109
|
-
pauseOnHidden,
|
|
110
|
-
play,
|
|
111
|
-
step,
|
|
112
|
-
onIntersected
|
|
113
|
-
]);
|
|
110
|
+
setHasLapped(lap);
|
|
111
|
+
onLooped?.();
|
|
112
|
+
}, [lap, loop]);
|
|
113
|
+
// State dispatch
|
|
114
|
+
useChangeDispatch(position, () => onStepChanged?.(position, activeStep));
|
|
115
|
+
useChangeDispatch(isPlaying, onIsPlayingChanged);
|
|
116
|
+
useChangeDispatch(isEnded, onIsEndedChanged);
|
|
117
|
+
useChangeDispatch(position === 0, atStart => { if (atStart)
|
|
118
|
+
onReachedFirstStep?.(); });
|
|
119
|
+
useChangeDispatch(stepsCount > 0 && position === stepsCount - 1, atEnd => { if (atEnd)
|
|
120
|
+
onReachedLastStep?.(); });
|
|
114
121
|
// Rendering
|
|
115
|
-
|
|
122
|
+
const c = clss(publicClassName, { cssModule });
|
|
123
|
+
const rootClss = mergeClassNames(c(null, {
|
|
124
|
+
playing: isPlaying,
|
|
125
|
+
'at-start': position === 0,
|
|
126
|
+
'at-end': stepsCount > 0 && position === stepsCount - 1,
|
|
127
|
+
ended: isEnded
|
|
128
|
+
}), className);
|
|
129
|
+
// Walked once per render: for each element, the positions of this lap at which it is
|
|
130
|
+
// active. Cheap, and it is what makes the three pairs answerable without memory.
|
|
131
|
+
const positionsOf = (steps) => {
|
|
132
|
+
const positions = [];
|
|
133
|
+
for (let i = 0; i < stepsCount; i += 1) {
|
|
134
|
+
if (steps.includes(stepMap?.[i] ?? i))
|
|
135
|
+
positions.push(i);
|
|
136
|
+
}
|
|
137
|
+
return positions;
|
|
138
|
+
};
|
|
139
|
+
let elementIndex = -1;
|
|
140
|
+
return _jsx("div", { className: rootClss, "data-step": position, "data-active-step": activeStep, "data-total-steps": stepsCount, "data-tempo": tempo, children: childrenArr.map((child, childPos) => {
|
|
141
|
+
if (!isValidElement(child))
|
|
142
|
+
return child;
|
|
143
|
+
elementIndex += 1;
|
|
144
|
+
const steps = stepsOf(child, elementIndex);
|
|
145
|
+
const positions = positionsOf(steps);
|
|
146
|
+
const isOn = steps.includes(activeStep);
|
|
147
|
+
const hasEarlier = positions.some(p => p < position);
|
|
148
|
+
const hasLater = positions.some(p => p > position);
|
|
149
|
+
const childClss = c('child', {
|
|
150
|
+
on: isOn,
|
|
151
|
+
off: !isOn,
|
|
152
|
+
'is-first': !hasEarlier,
|
|
153
|
+
'not-first': hasEarlier,
|
|
154
|
+
'is-last': !hasLater,
|
|
155
|
+
'not-last': hasLater
|
|
156
|
+
});
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- a React element's props are a record, whatever else they are
|
|
158
|
+
const ownClassName = child.props.className;
|
|
159
|
+
// `className` is the whole of what a child is asked to honour, and the only prop
|
|
160
|
+
// touched here — its own is kept, and comes second so a consumer's class wins a
|
|
161
|
+
// shorthand conflict.
|
|
162
|
+
const nextProps = {
|
|
163
|
+
key: childPos,
|
|
164
|
+
className: mergeClassNames(childClss, typeof ownClassName === 'string' ? ownClassName : undefined)
|
|
165
|
+
};
|
|
166
|
+
return cloneElement(child, nextProps);
|
|
167
|
+
}) });
|
|
116
168
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import type { ViewportBehaviours } from '../utils/viewport-behaviours/types.js';
|
|
3
3
|
import type { VideoAction } from './types.js';
|
|
4
4
|
import { type Props as ControlledProps } from './index.controlled.js';
|
|
5
5
|
/**
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
import type { ActionTable, ViewportBehaviours, VisibilityOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Whether a string is an instruction this vocabulary answers to.
|
|
5
|
+
*
|
|
6
|
+
* **It lives in the entry point and not next to `parseInstruction`**, which is where it
|
|
7
|
+
* belongs by subject, because the publish step only maps `index.js` and `types.js` into
|
|
8
|
+
* the package's exports — a `utils.js` is unreachable from outside, whatever it holds.
|
|
9
|
+
*
|
|
10
|
+
* **Exported for the consumers that receive their props as text.** lm-link reads an
|
|
11
|
+
* article's XML, where nothing is typed, and has to reject `'jump-to:banana'` before it
|
|
12
|
+
* reaches a component. Written on its side, the rule would exist twice and drift in
|
|
13
|
+
* silence — a verb added here would be rejected there for no visible reason.
|
|
14
|
+
*
|
|
15
|
+
* Returns a plain boolean rather than a type predicate, and that is not an oversight: a
|
|
16
|
+
* verb taking an argument is written `'jump-to:500'`, which is not a member of the verb
|
|
17
|
+
* list this checks against. Narrowing to `Instruction<A>` would therefore claim more than
|
|
18
|
+
* the list can support, and the caller that needs the narrow type is better off asserting
|
|
19
|
+
* it once, where it can say why.
|
|
20
|
+
*
|
|
21
|
+
* @param value - What the consumer wrote.
|
|
22
|
+
* @param verbs - The vocabulary, bare — `VIDEO_VERBS` and its like.
|
|
23
|
+
* @param withArgument - Those of them that take one, and what a valid one looks like. A
|
|
24
|
+
* verb given an argument it does not take, or denied one it needs, fails either way:
|
|
25
|
+
* both are a consumer meaning something the component cannot do.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isInstruction(value: unknown, verbs: readonly string[], withArgument?: Readonly<Partial<Record<string, (arg: string) => boolean>>>): boolean;
|
|
3
28
|
/**
|
|
4
29
|
* Whether the element counts as visible — **as a state, not as a crossing**.
|
|
5
30
|
*
|
|
@@ -51,4 +76,3 @@ export type ViewportBehavioursResult = {
|
|
|
51
76
|
* and yielding is the silent one.
|
|
52
77
|
*/
|
|
53
78
|
export declare function useViewportBehaviours<A extends string>(targetRef: RefObject<Element | null>, props: ViewportBehaviours<A>, table: ActionTable<A>, suspended?: boolean): ViewportBehavioursResult;
|
|
54
|
-
export type { ActionSpec, ActionTable, Instruction, Modifier, ParsedInstruction, ViewportBehaviours, VisibilityOptions } from './types.js';
|
|
@@ -2,6 +2,41 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { useIntersectionObserver } from '../../IntersectionObserver/index.js';
|
|
3
3
|
import { useChangeDispatch } from '../index.js';
|
|
4
4
|
import { parseInstruction, toInstructionList } from './utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Whether a string is an instruction this vocabulary answers to.
|
|
7
|
+
*
|
|
8
|
+
* **It lives in the entry point and not next to `parseInstruction`**, which is where it
|
|
9
|
+
* belongs by subject, because the publish step only maps `index.js` and `types.js` into
|
|
10
|
+
* the package's exports — a `utils.js` is unreachable from outside, whatever it holds.
|
|
11
|
+
*
|
|
12
|
+
* **Exported for the consumers that receive their props as text.** lm-link reads an
|
|
13
|
+
* article's XML, where nothing is typed, and has to reject `'jump-to:banana'` before it
|
|
14
|
+
* reaches a component. Written on its side, the rule would exist twice and drift in
|
|
15
|
+
* silence — a verb added here would be rejected there for no visible reason.
|
|
16
|
+
*
|
|
17
|
+
* Returns a plain boolean rather than a type predicate, and that is not an oversight: a
|
|
18
|
+
* verb taking an argument is written `'jump-to:500'`, which is not a member of the verb
|
|
19
|
+
* list this checks against. Narrowing to `Instruction<A>` would therefore claim more than
|
|
20
|
+
* the list can support, and the caller that needs the narrow type is better off asserting
|
|
21
|
+
* it once, where it can say why.
|
|
22
|
+
*
|
|
23
|
+
* @param value - What the consumer wrote.
|
|
24
|
+
* @param verbs - The vocabulary, bare — `VIDEO_VERBS` and its like.
|
|
25
|
+
* @param withArgument - Those of them that take one, and what a valid one looks like. A
|
|
26
|
+
* verb given an argument it does not take, or denied one it needs, fails either way:
|
|
27
|
+
* both are a consumer meaning something the component cannot do.
|
|
28
|
+
*/
|
|
29
|
+
export function isInstruction(value, verbs, withArgument = {}) {
|
|
30
|
+
if (typeof value !== 'string')
|
|
31
|
+
return false;
|
|
32
|
+
const { verb, arg } = parseInstruction(value);
|
|
33
|
+
if (!verbs.includes(verb))
|
|
34
|
+
return false;
|
|
35
|
+
const validate = withArgument[verb];
|
|
36
|
+
if (validate === undefined)
|
|
37
|
+
return arg === undefined;
|
|
38
|
+
return arg !== undefined && validate(arg);
|
|
39
|
+
}
|
|
5
40
|
/**
|
|
6
41
|
* Whether the element counts as visible — **as a state, not as a crossing**.
|
|
7
42
|
*
|
|
@@ -24,24 +24,3 @@ export declare function parseInstruction(instruction: string): ParsedInstruction
|
|
|
24
24
|
* @returns The instructions in the order they were given, which is the order they run.
|
|
25
25
|
*/
|
|
26
26
|
export declare function toInstructionList<A extends string>(given: Instruction<A> | Array<Instruction<A>> | undefined): Array<Instruction<A>>;
|
|
27
|
-
/**
|
|
28
|
-
* Whether a string is an instruction this vocabulary answers to.
|
|
29
|
-
*
|
|
30
|
-
* **Exported for the consumers that receive their props as text.** lm-link reads an
|
|
31
|
-
* article's XML, where nothing is typed, and has to reject `'jump-to:banana'` before it
|
|
32
|
-
* reaches a component. Written on its side, the rule would exist twice and drift in
|
|
33
|
-
* silence — a verb added here would be rejected there for no visible reason.
|
|
34
|
-
*
|
|
35
|
-
* Returns a plain boolean rather than a type predicate, and that is not an oversight: a
|
|
36
|
-
* verb taking an argument is written `'jump-to:500'`, which is not a member of the verb
|
|
37
|
-
* list this checks against. Narrowing to `Instruction<A>` would therefore claim more than
|
|
38
|
-
* the list can support, and the caller that needs the narrow type is better off asserting
|
|
39
|
-
* it once, where it can say why.
|
|
40
|
-
*
|
|
41
|
-
* @param value - What the consumer wrote.
|
|
42
|
-
* @param verbs - The vocabulary, bare — `VIDEO_VERBS` and its like.
|
|
43
|
-
* @param withArgument - Those of them that take one, and what a valid one looks like. A
|
|
44
|
-
* verb given an argument it does not take, or denied one it needs, fails either way:
|
|
45
|
-
* both are a consumer meaning something the component cannot do.
|
|
46
|
-
*/
|
|
47
|
-
export declare function isInstruction(value: unknown, verbs: readonly string[], withArgument?: Readonly<Partial<Record<string, (arg: string) => boolean>>>): boolean;
|
|
@@ -53,34 +53,3 @@ export function toInstructionList(given) {
|
|
|
53
53
|
return given;
|
|
54
54
|
return [given];
|
|
55
55
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Whether a string is an instruction this vocabulary answers to.
|
|
58
|
-
*
|
|
59
|
-
* **Exported for the consumers that receive their props as text.** lm-link reads an
|
|
60
|
-
* article's XML, where nothing is typed, and has to reject `'jump-to:banana'` before it
|
|
61
|
-
* reaches a component. Written on its side, the rule would exist twice and drift in
|
|
62
|
-
* silence — a verb added here would be rejected there for no visible reason.
|
|
63
|
-
*
|
|
64
|
-
* Returns a plain boolean rather than a type predicate, and that is not an oversight: a
|
|
65
|
-
* verb taking an argument is written `'jump-to:500'`, which is not a member of the verb
|
|
66
|
-
* list this checks against. Narrowing to `Instruction<A>` would therefore claim more than
|
|
67
|
-
* the list can support, and the caller that needs the narrow type is better off asserting
|
|
68
|
-
* it once, where it can say why.
|
|
69
|
-
*
|
|
70
|
-
* @param value - What the consumer wrote.
|
|
71
|
-
* @param verbs - The vocabulary, bare — `VIDEO_VERBS` and its like.
|
|
72
|
-
* @param withArgument - Those of them that take one, and what a valid one looks like. A
|
|
73
|
-
* verb given an argument it does not take, or denied one it needs, fails either way:
|
|
74
|
-
* both are a consumer meaning something the component cannot do.
|
|
75
|
-
*/
|
|
76
|
-
export function isInstruction(value, verbs, withArgument = {}) {
|
|
77
|
-
if (typeof value !== 'string')
|
|
78
|
-
return false;
|
|
79
|
-
const { verb, arg } = parseInstruction(value);
|
|
80
|
-
if (!verbs.includes(verb))
|
|
81
|
-
return false;
|
|
82
|
-
const validate = withArgument[verb];
|
|
83
|
-
if (validate === undefined)
|
|
84
|
-
return arg === undefined;
|
|
85
|
-
return arg !== undefined && validate(arg);
|
|
86
|
-
}
|
|
@@ -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'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as copyDir from './copy-dir/index.js'
|
|
2
|
-
export * as downloadFile from './download-file/index.js'
|
|
3
2
|
export * as copyFile from './copy-file/index.js'
|
|
3
|
+
export * as downloadFile from './download-file/index.js'
|
|
4
4
|
export * as existsFile from './exists-file/index.js'
|
|
5
5
|
export * as listDir from './list-dir/index.js'
|
|
6
6
|
export * as moveDir from './move-dir/index.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as copyDir from './copy-dir/index.js'
|
|
2
|
-
export * as downloadFile from './download-file/index.js'
|
|
3
2
|
export * as copyFile from './copy-file/index.js'
|
|
3
|
+
export * as downloadFile from './download-file/index.js'
|
|
4
4
|
export * as existsFile from './exists-file/index.js'
|
|
5
5
|
export * as listDir from './list-dir/index.js'
|
|
6
6
|
export * as moveDir from './move-dir/index.js'
|
package/package.json
CHANGED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { type FunctionComponent, type PropsWithChildren } from 'react';
|
|
2
|
-
import type { WithClassName } from '../utils/types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Props for the {@link ControlledSequencer} component.
|
|
5
|
-
*
|
|
6
|
-
* This is the low-level controlled interface. All state is driven externally —
|
|
7
|
-
* the component holds no internal state of its own. For the uncontrolled
|
|
8
|
-
* version that reacts to external events and derives these props automatically,
|
|
9
|
-
* see the default export of the parent module.
|
|
10
|
-
*
|
|
11
|
-
* @property step - Zero-based index of the currently active step. Determines
|
|
12
|
-
* which child is marked active, which are previous, and which are next.
|
|
13
|
-
* Defaults to `0`.
|
|
14
|
-
* @property activateOnStep - Optional 2D array that overrides the default
|
|
15
|
-
* one-child-per-step activation logic. Each entry at index `i` is the list of
|
|
16
|
-
* child indices that should be active when `step === i`, allowing multiple
|
|
17
|
-
* children to be simultaneously active on a given step. When omitted, exactly
|
|
18
|
-
* one child is active at a time (the child at index `step`).
|
|
19
|
-
* @property isPlaying - Whether the sequence is currently progressing. The
|
|
20
|
-
* controlled layer never advances on its own; this only drives the `--playing`
|
|
21
|
-
* modifier. Defaults to `false`.
|
|
22
|
-
* @property tempo - Playback speed in beats per minute, exposed as `data-tempo`
|
|
23
|
-
* for styling and scripting. Purely informational here — the interval itself
|
|
24
|
-
* lives in the uncontrolled wrapper. When omitted, no attribute is rendered.
|
|
25
|
-
* @property className - Optional additional class name(s) applied to the root element.
|
|
26
|
-
* @property children - The items to sequence. Each child is wrapped in a
|
|
27
|
-
* classifier `<div>` and receives one of the `--active`, `--previous`, or
|
|
28
|
-
* `--next` modifiers depending on its position relative to the current `step`.
|
|
29
|
-
*/
|
|
30
|
-
export type Props = PropsWithChildren<WithClassName<{
|
|
31
|
-
step?: number;
|
|
32
|
-
activateOnStep?: number[][];
|
|
33
|
-
isPlaying?: boolean;
|
|
34
|
-
tempo?: number;
|
|
35
|
-
}>>;
|
|
36
|
-
/**
|
|
37
|
-
* Controlled sequencer component. Renders each child inside a classifier
|
|
38
|
-
* wrapper and assigns step-relative modifiers based on `step` and the optional
|
|
39
|
-
* `activateOnStep` override map.
|
|
40
|
-
*
|
|
41
|
-
* This component is purely presentational and holds no internal state.
|
|
42
|
-
* It is designed to be driven by the uncontrolled wrapper, which handles
|
|
43
|
-
* timing, playback events, and derives the props passed here.
|
|
44
|
-
*
|
|
45
|
-
* ### Root element modifiers
|
|
46
|
-
* The root `<div>` receives the public class name defined by `sequencer` and
|
|
47
|
-
* the following BEM-style modifier classes:
|
|
48
|
-
* - `--playing` — when `isPlaying` is `true`.
|
|
49
|
-
* - `--at-start` — when the current step is the first step.
|
|
50
|
-
* - `--at-end` — when the current step is the last step.
|
|
51
|
-
*
|
|
52
|
-
* ### Data attributes on the root element
|
|
53
|
-
* - `data-step` — the current step index.
|
|
54
|
-
* - `data-tempo` — current playback tempo, when `tempo` is provided.
|
|
55
|
-
*
|
|
56
|
-
* ### Child wrapper elements
|
|
57
|
-
* Each child is wrapped in a `<div>` with the `__child` element class and
|
|
58
|
-
* exactly one of the following mutually exclusive modifiers:
|
|
59
|
-
* - `--active` — this child corresponds to the current step (or is included
|
|
60
|
-
* in `activateOnStep[step]`).
|
|
61
|
-
* - `--previous` — this child was active in a prior step.
|
|
62
|
-
* - `--next` — this child has not yet been reached.
|
|
63
|
-
*
|
|
64
|
-
* @param props - Component properties.
|
|
65
|
-
* @see {@link Props}
|
|
66
|
-
* @returns A root `<div>` containing one classifier wrapper per child.
|
|
67
|
-
*/
|
|
68
|
-
export declare const ControlledSequencer: FunctionComponent<Props>;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Children } from 'react';
|
|
3
|
-
import { clss } from '../../agnostic/css/clss/index.js';
|
|
4
|
-
import { mergeClassNames } from '../utils/index.js';
|
|
5
|
-
import { sequencer as publicClassName } from '../public-classnames.js';
|
|
6
|
-
import cssModule from './styles.module.css';
|
|
7
|
-
/**
|
|
8
|
-
* Controlled sequencer component. Renders each child inside a classifier
|
|
9
|
-
* wrapper and assigns step-relative modifiers based on `step` and the optional
|
|
10
|
-
* `activateOnStep` override map.
|
|
11
|
-
*
|
|
12
|
-
* This component is purely presentational and holds no internal state.
|
|
13
|
-
* It is designed to be driven by the uncontrolled wrapper, which handles
|
|
14
|
-
* timing, playback events, and derives the props passed here.
|
|
15
|
-
*
|
|
16
|
-
* ### Root element modifiers
|
|
17
|
-
* The root `<div>` receives the public class name defined by `sequencer` and
|
|
18
|
-
* the following BEM-style modifier classes:
|
|
19
|
-
* - `--playing` — when `isPlaying` is `true`.
|
|
20
|
-
* - `--at-start` — when the current step is the first step.
|
|
21
|
-
* - `--at-end` — when the current step is the last step.
|
|
22
|
-
*
|
|
23
|
-
* ### Data attributes on the root element
|
|
24
|
-
* - `data-step` — the current step index.
|
|
25
|
-
* - `data-tempo` — current playback tempo, when `tempo` is provided.
|
|
26
|
-
*
|
|
27
|
-
* ### Child wrapper elements
|
|
28
|
-
* Each child is wrapped in a `<div>` with the `__child` element class and
|
|
29
|
-
* exactly one of the following mutually exclusive modifiers:
|
|
30
|
-
* - `--active` — this child corresponds to the current step (or is included
|
|
31
|
-
* in `activateOnStep[step]`).
|
|
32
|
-
* - `--previous` — this child was active in a prior step.
|
|
33
|
-
* - `--next` — this child has not yet been reached.
|
|
34
|
-
*
|
|
35
|
-
* @param props - Component properties.
|
|
36
|
-
* @see {@link Props}
|
|
37
|
-
* @returns A root `<div>` containing one classifier wrapper per child.
|
|
38
|
-
*/
|
|
39
|
-
export const ControlledSequencer = ({ step = 0, activateOnStep, isPlaying = false, tempo, className, children }) => {
|
|
40
|
-
const childrenArr = Children.toArray(children);
|
|
41
|
-
const stepsCount = activateOnStep?.length ?? childrenArr.length;
|
|
42
|
-
// Rendering
|
|
43
|
-
const c = clss(publicClassName, { cssModule });
|
|
44
|
-
const rootClss = mergeClassNames(c(null, {
|
|
45
|
-
playing: isPlaying,
|
|
46
|
-
'at-start': step === 0,
|
|
47
|
-
'at-end': step === stepsCount - 1
|
|
48
|
-
}), className);
|
|
49
|
-
return _jsx("div", { className: rootClss, "data-step": step, "data-tempo": tempo, children: childrenArr
|
|
50
|
-
.map((child, childPos) => {
|
|
51
|
-
const thisStepActivateOnStep = activateOnStep?.[step];
|
|
52
|
-
const isPrevious = activateOnStep === undefined
|
|
53
|
-
? childPos < step
|
|
54
|
-
: [...activateOnStep]
|
|
55
|
-
.slice(0, step)
|
|
56
|
-
.some(list => list.includes(childPos));
|
|
57
|
-
const isCurrent = activateOnStep === undefined
|
|
58
|
-
? childPos === step
|
|
59
|
-
: Array.isArray(thisStepActivateOnStep)
|
|
60
|
-
? thisStepActivateOnStep.includes(childPos)
|
|
61
|
-
: false;
|
|
62
|
-
const isNext = !isPrevious && !isCurrent;
|
|
63
|
-
const childClss = c('child', {
|
|
64
|
-
current: isCurrent,
|
|
65
|
-
prev: isPrevious,
|
|
66
|
-
next: isNext
|
|
67
|
-
});
|
|
68
|
-
return _jsx("div", { className: childClss, children: child }, childPos);
|
|
69
|
-
}) });
|
|
70
|
-
};
|