@design-edito/tools 0.5.0 → 0.5.2
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/hyper-json/smart-tags/coalesced/index.d.ts +13 -13
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +13 -13
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +3 -3
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +3 -3
- package/agnostic/html/index.d.ts +2 -2
- package/agnostic/html/index.js +2 -2
- 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/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/index.d.ts +1 -1
- package/agnostic/time/index.js +1 -1
- package/components/Input/index.controlled.d.ts +1 -1
- package/components/JsonEditor/index.js +16 -14
- package/components/ListLoader/index.controlled.d.ts +78 -0
- package/components/ListLoader/index.controlled.js +99 -0
- package/components/ListLoader/index.d.ts +69 -0
- package/components/ListLoader/index.js +146 -0
- package/components/ListLoader/styles.module.css +0 -0
- package/components/ListLoader/utils.d.ts +8 -0
- package/components/ListLoader/utils.js +10 -0
- package/components/index.d.ts +3 -2
- package/components/index.js +3 -2
- package/components/public-classnames.d.ts +1 -0
- package/components/public-classnames.js +1 -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/directory/index.d.ts +1 -1
- package/node/@google-cloud/storage/directory/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/files/get-size/index.d.ts +56 -0
- package/node/files/get-size/index.js +167 -0
- package/node/files/get-size/index.test.d.ts +1 -0
- package/node/files/get-size/index.test.js +143 -0
- package/node/files/index.d.ts +1 -0
- package/node/files/index.js +1 -0
- package/node/images/index.d.ts +1 -1
- package/node/images/index.js +1 -1
- package/node/images/transform/operations/index.d.ts +2 -2
- package/node/images/transform/operations/index.js +2 -2
- package/node/index.d.ts +1 -1
- package/node/index.js +1 -1
- package/package.json +15 -1
|
@@ -2,20 +2,21 @@ export * as add from './add/index.js'
|
|
|
2
2
|
export * as addclass from './addclass/index.js'
|
|
3
3
|
export * as and from './and/index.js'
|
|
4
4
|
export * as append from './append/index.js'
|
|
5
|
-
export * as call from './call/index.js'
|
|
6
5
|
export * as at from './at/index.js'
|
|
6
|
+
export * as call from './call/index.js'
|
|
7
7
|
export * as clone from './clone/index.js'
|
|
8
|
-
export * as deleteproperties from './deleteproperties/index.js'
|
|
9
8
|
export * as equals from './equals/index.js'
|
|
9
|
+
export * as deleteproperties from './deleteproperties/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
|
-
export * as hjparse from './hjparse/index.js'
|
|
14
13
|
export * as hjstringify from './hjstringify/index.js'
|
|
15
|
-
export * as
|
|
16
|
-
export * as length from './length/index.js'
|
|
14
|
+
export * as hjparse from './hjparse/index.js'
|
|
17
15
|
export * as if from './if/index.js'
|
|
18
16
|
export * as initialize from './initialize/index.js'
|
|
17
|
+
export * as join from './join/index.js'
|
|
18
|
+
export * as length from './length/index.js'
|
|
19
|
+
export * as map from './map/index.js'
|
|
19
20
|
export * as negate from './negate/index.js'
|
|
20
21
|
export * as notrailing from './notrailing/index.js'
|
|
21
22
|
export * as or from './or/index.js'
|
|
@@ -23,30 +24,29 @@ export * as pickrandom from './pickrandom/index.js'
|
|
|
23
24
|
export * as populate from './populate/index.js'
|
|
24
25
|
export * as print from './print/index.js'
|
|
25
26
|
export * as push from './push/index.js'
|
|
26
|
-
export * as map from './map/index.js'
|
|
27
27
|
export * as pusheach from './pusheach/index.js'
|
|
28
28
|
export * as recordtoarray from './recordtoarray/index.js'
|
|
29
|
-
export * as removeattribute from './removeattribute/index.js'
|
|
30
29
|
export * as removeclass from './removeclass/index.js'
|
|
31
|
-
export * as
|
|
32
|
-
export * as select from './select/index.js'
|
|
30
|
+
export * as removeattribute from './removeattribute/index.js'
|
|
33
31
|
export * as renameproperty from './renameproperty/index.js'
|
|
32
|
+
export * as replace from './replace/index.js'
|
|
34
33
|
export * as set from './set/index.js'
|
|
34
|
+
export * as select from './select/index.js'
|
|
35
35
|
export * as setattribute from './setattribute/index.js'
|
|
36
|
-
export * as setproperty from './setproperty/index.js'
|
|
37
36
|
export * as sorton from './sorton/index.js'
|
|
38
37
|
export * as split from './split/index.js'
|
|
39
38
|
export * as spread from './spread/index.js'
|
|
40
39
|
export * as toarray from './toarray/index.js'
|
|
41
|
-
export * as toboolean from './toboolean/index.js'
|
|
42
40
|
export * as toelement from './toelement/index.js'
|
|
41
|
+
export * as setproperty from './setproperty/index.js'
|
|
43
42
|
export * as toggleclass from './toggleclass/index.js'
|
|
44
43
|
export * as tonodelist from './tonodelist/index.js'
|
|
45
44
|
export * as tonull from './tonull/index.js'
|
|
46
|
-
export * as
|
|
47
|
-
export * as torecord from './torecord/index.js'
|
|
45
|
+
export * as toboolean from './toboolean/index.js'
|
|
48
46
|
export * as toref from './toref/index.js'
|
|
47
|
+
export * as torecord from './torecord/index.js'
|
|
49
48
|
export * as tostring from './tostring/index.js'
|
|
50
49
|
export * as totext from './totext/index.js'
|
|
51
50
|
export * as transformselected from './transformselected/index.js'
|
|
52
51
|
export * as trim from './trim/index.js'
|
|
52
|
+
export * as tonumber from './tonumber/index.js'
|
|
@@ -2,20 +2,21 @@ export * as add from './add/index.js'
|
|
|
2
2
|
export * as addclass from './addclass/index.js'
|
|
3
3
|
export * as and from './and/index.js'
|
|
4
4
|
export * as append from './append/index.js'
|
|
5
|
-
export * as call from './call/index.js'
|
|
6
5
|
export * as at from './at/index.js'
|
|
6
|
+
export * as call from './call/index.js'
|
|
7
7
|
export * as clone from './clone/index.js'
|
|
8
|
-
export * as deleteproperties from './deleteproperties/index.js'
|
|
9
8
|
export * as equals from './equals/index.js'
|
|
9
|
+
export * as deleteproperties from './deleteproperties/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
|
-
export * as hjparse from './hjparse/index.js'
|
|
14
13
|
export * as hjstringify from './hjstringify/index.js'
|
|
15
|
-
export * as
|
|
16
|
-
export * as length from './length/index.js'
|
|
14
|
+
export * as hjparse from './hjparse/index.js'
|
|
17
15
|
export * as if from './if/index.js'
|
|
18
16
|
export * as initialize from './initialize/index.js'
|
|
17
|
+
export * as join from './join/index.js'
|
|
18
|
+
export * as length from './length/index.js'
|
|
19
|
+
export * as map from './map/index.js'
|
|
19
20
|
export * as negate from './negate/index.js'
|
|
20
21
|
export * as notrailing from './notrailing/index.js'
|
|
21
22
|
export * as or from './or/index.js'
|
|
@@ -23,30 +24,29 @@ export * as pickrandom from './pickrandom/index.js'
|
|
|
23
24
|
export * as populate from './populate/index.js'
|
|
24
25
|
export * as print from './print/index.js'
|
|
25
26
|
export * as push from './push/index.js'
|
|
26
|
-
export * as map from './map/index.js'
|
|
27
27
|
export * as pusheach from './pusheach/index.js'
|
|
28
28
|
export * as recordtoarray from './recordtoarray/index.js'
|
|
29
|
-
export * as removeattribute from './removeattribute/index.js'
|
|
30
29
|
export * as removeclass from './removeclass/index.js'
|
|
31
|
-
export * as
|
|
32
|
-
export * as select from './select/index.js'
|
|
30
|
+
export * as removeattribute from './removeattribute/index.js'
|
|
33
31
|
export * as renameproperty from './renameproperty/index.js'
|
|
32
|
+
export * as replace from './replace/index.js'
|
|
34
33
|
export * as set from './set/index.js'
|
|
34
|
+
export * as select from './select/index.js'
|
|
35
35
|
export * as setattribute from './setattribute/index.js'
|
|
36
|
-
export * as setproperty from './setproperty/index.js'
|
|
37
36
|
export * as sorton from './sorton/index.js'
|
|
38
37
|
export * as split from './split/index.js'
|
|
39
38
|
export * as spread from './spread/index.js'
|
|
40
39
|
export * as toarray from './toarray/index.js'
|
|
41
|
-
export * as toboolean from './toboolean/index.js'
|
|
42
40
|
export * as toelement from './toelement/index.js'
|
|
41
|
+
export * as setproperty from './setproperty/index.js'
|
|
43
42
|
export * as toggleclass from './toggleclass/index.js'
|
|
44
43
|
export * as tonodelist from './tonodelist/index.js'
|
|
45
44
|
export * as tonull from './tonull/index.js'
|
|
46
|
-
export * as
|
|
47
|
-
export * as torecord from './torecord/index.js'
|
|
45
|
+
export * as toboolean from './toboolean/index.js'
|
|
48
46
|
export * as toref from './toref/index.js'
|
|
47
|
+
export * as torecord from './torecord/index.js'
|
|
49
48
|
export * as tostring from './tostring/index.js'
|
|
50
49
|
export * as totext from './totext/index.js'
|
|
51
50
|
export * as transformselected from './transformselected/index.js'
|
|
52
51
|
export * as trim from './trim/index.js'
|
|
52
|
+
export * as tonumber from './tonumber/index.js'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export * as any from './any/index.js'
|
|
2
|
-
export * as array from './array/index.js'
|
|
3
2
|
export * as boolean from './boolean/index.js'
|
|
4
3
|
export * as element from './element/index.js'
|
|
5
4
|
export * as get from './get/index.js'
|
|
6
5
|
export * as guess from './guess/index.js'
|
|
7
6
|
export * as nodelist from './nodelist/index.js'
|
|
8
|
-
export * as number from './number/index.js'
|
|
9
7
|
export * as null from './null/index.js'
|
|
8
|
+
export * as number from './number/index.js'
|
|
10
9
|
export * as record from './record/index.js'
|
|
11
10
|
export * as ref from './ref/index.js'
|
|
12
|
-
export * as string from './string/index.js'
|
|
13
11
|
export * as text from './text/index.js'
|
|
12
|
+
export * as string from './string/index.js'
|
|
13
|
+
export * as array from './array/index.js'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export * as any from './any/index.js'
|
|
2
|
-
export * as array from './array/index.js'
|
|
3
2
|
export * as boolean from './boolean/index.js'
|
|
4
3
|
export * as element from './element/index.js'
|
|
5
4
|
export * as get from './get/index.js'
|
|
6
5
|
export * as guess from './guess/index.js'
|
|
7
6
|
export * as nodelist from './nodelist/index.js'
|
|
8
|
-
export * as number from './number/index.js'
|
|
9
7
|
export * as null from './null/index.js'
|
|
8
|
+
export * as number from './number/index.js'
|
|
10
9
|
export * as record from './record/index.js'
|
|
11
10
|
export * as ref from './ref/index.js'
|
|
12
|
-
export * as string from './string/index.js'
|
|
13
11
|
export * as text from './text/index.js'
|
|
12
|
+
export * as string from './string/index.js'
|
|
13
|
+
export * as array from './array/index.js'
|
package/agnostic/html/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * as deepSelect from './deep-select/index.js'
|
|
2
|
+
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
2
3
|
export * as getPositionInsideParent from './get-position-inside-parent/index.js'
|
|
3
4
|
export * as hyperJson from './hyper-json/index.js'
|
|
4
5
|
export * as insertNode from './insert-node/index.js'
|
|
5
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 stringToNodes from './string-to-nodes/index.js'
|
|
9
|
-
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
10
9
|
export * as watchSelection from './watch-selection/index.js'
|
|
10
|
+
export * as stringToNodes from './string-to-nodes/index.js'
|
package/agnostic/html/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * as deepSelect from './deep-select/index.js'
|
|
2
|
+
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
2
3
|
export * as getPositionInsideParent from './get-position-inside-parent/index.js'
|
|
3
4
|
export * as hyperJson from './hyper-json/index.js'
|
|
4
5
|
export * as insertNode from './insert-node/index.js'
|
|
5
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 stringToNodes from './string-to-nodes/index.js'
|
|
9
|
-
export * as getNodeAncestors from './get-node-ancestors/index.js'
|
|
10
9
|
export * as watchSelection from './watch-selection/index.js'
|
|
10
|
+
export * as stringToNodes from './string-to-nodes/index.js'
|
package/agnostic/misc/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * as assert from './assert/index.js'
|
|
2
|
-
export * as cast from './cast/index.js'
|
|
3
2
|
export * as connection from './connection/index.js'
|
|
3
|
+
export * as cast from './cast/index.js'
|
|
4
4
|
export * as crawler from './crawler/index.js'
|
|
5
5
|
export * as crossenv from './crossenv/index.js'
|
|
6
|
-
export * as dataSize from './data-size/index.js'
|
|
7
|
-
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
8
6
|
export * as isNullish from './is-nullish/index.js'
|
|
9
7
|
export * as logs from './logs/index.js'
|
|
10
8
|
export * as loremIpsum from './lorem-ipsum/index.js'
|
|
11
9
|
export * as normalizeExtension from './normalize-extension/index.js'
|
|
12
10
|
export * as outcome from './outcome/index.js'
|
|
11
|
+
export * as dataSize from './data-size/index.js'
|
|
12
|
+
export * as isConstructorFunction from './is-constructor-function/index.js'
|
package/agnostic/misc/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * as assert from './assert/index.js'
|
|
2
|
-
export * as cast from './cast/index.js'
|
|
3
2
|
export * as connection from './connection/index.js'
|
|
3
|
+
export * as cast from './cast/index.js'
|
|
4
4
|
export * as crawler from './crawler/index.js'
|
|
5
5
|
export * as crossenv from './crossenv/index.js'
|
|
6
|
-
export * as dataSize from './data-size/index.js'
|
|
7
|
-
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
8
6
|
export * as isNullish from './is-nullish/index.js'
|
|
9
7
|
export * as logs from './logs/index.js'
|
|
10
8
|
export * as loremIpsum from './lorem-ipsum/index.js'
|
|
11
9
|
export * as normalizeExtension from './normalize-extension/index.js'
|
|
12
10
|
export * as outcome from './outcome/index.js'
|
|
11
|
+
export * as dataSize from './data-size/index.js'
|
|
12
|
+
export * as isConstructorFunction from './is-constructor-function/index.js'
|
|
@@ -2,5 +2,5 @@ export * as absoluteModulo from './absolute-modulo/index.js'
|
|
|
2
2
|
export * as approximateRational from './approximate-rational/index.js'
|
|
3
3
|
export * as clamp from './clamp/index.js'
|
|
4
4
|
export * as geometricProgressions from './geometric-progressions/index.js'
|
|
5
|
-
export * as interpolate from './interpolate/index.js'
|
|
6
5
|
export * as round from './round/index.js'
|
|
6
|
+
export * as interpolate from './interpolate/index.js'
|
|
@@ -2,5 +2,5 @@ export * as absoluteModulo from './absolute-modulo/index.js'
|
|
|
2
2
|
export * as approximateRational from './approximate-rational/index.js'
|
|
3
3
|
export * as clamp from './clamp/index.js'
|
|
4
4
|
export * as geometricProgressions from './geometric-progressions/index.js'
|
|
5
|
-
export * as interpolate from './interpolate/index.js'
|
|
6
5
|
export * as round from './round/index.js'
|
|
6
|
+
export * as interpolate from './interpolate/index.js'
|
package/agnostic/optim/index.js
CHANGED
|
@@ -3,6 +3,6 @@ export * as matches from './matches/index.js'
|
|
|
3
3
|
export * as normalizeIndent from './normalize-indent/index.js'
|
|
4
4
|
export * as parseTable from './parse-table/index.js'
|
|
5
5
|
export * as replaceAll from './replace-all/index.js'
|
|
6
|
-
export * as splitTrim from './split-trim/index.js'
|
|
7
6
|
export * as toAlphanum from './to-alphanum/index.js'
|
|
7
|
+
export * as splitTrim from './split-trim/index.js'
|
|
8
8
|
export * as trim from './trim/index.js'
|
|
@@ -3,6 +3,6 @@ export * as matches from './matches/index.js'
|
|
|
3
3
|
export * as normalizeIndent from './normalize-indent/index.js'
|
|
4
4
|
export * as parseTable from './parse-table/index.js'
|
|
5
5
|
export * as replaceAll from './replace-all/index.js'
|
|
6
|
-
export * as splitTrim from './split-trim/index.js'
|
|
7
6
|
export * as toAlphanum from './to-alphanum/index.js'
|
|
7
|
+
export * as splitTrim from './split-trim/index.js'
|
|
8
8
|
export * as trim from './trim/index.js'
|
package/agnostic/time/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as dates from './dates/index.js'
|
|
2
|
-
export * as duration from './duration/index.js'
|
|
3
2
|
export * as timeout from './timeout/index.js'
|
|
3
|
+
export * as duration from './duration/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
1
|
export * as dates from './dates/index.js'
|
|
2
|
-
export * as duration from './duration/index.js'
|
|
3
2
|
export * as timeout from './timeout/index.js'
|
|
3
|
+
export * as duration from './duration/index.js'
|
|
4
4
|
export * as transitions from './transitions/index.js'
|
|
5
5
|
export * as wait from './wait/index.js'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type FunctionComponent, type InputHTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import type { WithClassName } from '../utils/types.js';
|
|
3
3
|
/**
|
|
4
|
-
* Props for the {@link
|
|
4
|
+
* Props for the {@link ControlledInput} component.
|
|
5
5
|
*
|
|
6
6
|
* Extends all native {@link InputHTMLAttributes} and {@link WithClassName}
|
|
7
7
|
* with optional label and error content.
|
|
@@ -60,11 +60,19 @@ export const JsonEditor = ({ defaultValue = null, onChange, onValidationError, s
|
|
|
60
60
|
const rootClss = mergeClassNames(c(null, {}), className);
|
|
61
61
|
return _jsxs("div", { className: rootClss, children: [_jsx(ValueEditor, { defaultValue: defaultValue, onChange: val => setValueAndDispatch(val), path: [] }), _jsx("pre", { children: JSON.stringify(value, null, 2) })] });
|
|
62
62
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
function getValueType(value) {
|
|
64
|
+
if (value === null)
|
|
65
|
+
return 'null';
|
|
66
|
+
if (Array.isArray(value))
|
|
67
|
+
return 'array';
|
|
68
|
+
if (isNonNullObject(value))
|
|
69
|
+
return 'record';
|
|
70
|
+
if (typeof value === 'string')
|
|
71
|
+
return 'string';
|
|
72
|
+
if (typeof value === 'number')
|
|
73
|
+
return 'number';
|
|
74
|
+
return 'boolean';
|
|
75
|
+
}
|
|
68
76
|
export const ValueEditor = ({ defaultValue = {}, onChange, path = [] }) => {
|
|
69
77
|
// State
|
|
70
78
|
const [value, setValue] = useState(defaultValue);
|
|
@@ -94,16 +102,10 @@ export const ValueEditor = ({ defaultValue = {}, onChange, path = [] }) => {
|
|
|
94
102
|
const handleRecordValueChange = e => setValueAndDispatch(e);
|
|
95
103
|
const handleArrayValueChange = e => setValueAndDispatch(e);
|
|
96
104
|
// Rendering
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
number: typeof value === 'number',
|
|
100
|
-
boolean: typeof value === 'boolean',
|
|
101
|
-
null: value === null,
|
|
102
|
-
array: Array.isArray(value),
|
|
103
|
-
record: !Array.isArray(value) && isNonNullObject(value)
|
|
104
|
-
});
|
|
105
|
+
const valueType = getValueType(value);
|
|
106
|
+
const valueEditorClss = c('value', valueType);
|
|
105
107
|
const pathStringDataAttr = path.map(e => e.toString()).join('.');
|
|
106
|
-
return _jsxs("span", { className: valueEditorClss, "data-path": pathStringDataAttr, children: [_jsxs(Select, { className: c('type'), onChange: handleTypeSelectChange, children: [_jsx("option", { value: 'string',
|
|
108
|
+
return _jsxs("span", { className: valueEditorClss, "data-path": pathStringDataAttr, children: [_jsxs(Select, { className: c('type'), value: valueType, onChange: handleTypeSelectChange, children: [_jsx("option", { value: 'string', children: "string" }), _jsx("option", { value: 'number', children: "number" }), _jsx("option", { value: 'boolean', children: "boolean" }), _jsx("option", { value: 'null', children: "null" }), _jsx("option", { value: 'record', children: "record" }), _jsx("option", { value: 'array', children: "array" })] }), typeof value === 'string' && _jsx(StringEditor, { type: 'textarea', defaultValue: value, onChange: handleStringValueChange }), typeof value === 'number' && _jsx(NumberEditor, { defaultValue: value, onChange: handleNumberValueChange }), typeof value === 'boolean' && _jsx(BooleanEditor, { defaultValue: value, onChange: handleBooleanValueChange }), value === null && _jsx(NullEditor, { defaultValue: value }), isNonNullObject(value) && !Array.isArray(value) && _jsx(RecordEditor, { defaultValue: value, onChange: handleRecordValueChange, path: path }), Array.isArray(value) && _jsx(ArrayEditor, { defaultValue: value, onChange: handleArrayValueChange, path: path })] });
|
|
107
109
|
};
|
|
108
110
|
/* * * * * * * * * * * * * * * * *
|
|
109
111
|
*
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { WithClassName } from '../utils/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the {@link ListLoaderControlled} component.
|
|
5
|
+
*
|
|
6
|
+
* @template T - The item type carried by each page.
|
|
7
|
+
*
|
|
8
|
+
* @property pages - Page positions the consumer wants rendered. Entries outside
|
|
9
|
+
* `firstPagePos`–`lastPagePos` are ignored, as are entries absent from `itemsPages`.
|
|
10
|
+
* @property firstPagePos - Lowest page position that exists. No load button is
|
|
11
|
+
* ever rendered below it.
|
|
12
|
+
* @property lastPagePos - Highest page position that exists. No load button is
|
|
13
|
+
* ever rendered above it.
|
|
14
|
+
* @property itemsPages - Already-loaded items, keyed by page position. The
|
|
15
|
+
* component holds no data of its own and renders only what this map contains.
|
|
16
|
+
* @property filter - Decides whether an item is rendered. Applied before deduplication.
|
|
17
|
+
* @property display - Renders a single item.
|
|
18
|
+
* @property getIdentifier - Item identity, used as React key and to deduplicate.
|
|
19
|
+
* When two rendered items share an identifier, only the later one in page order
|
|
20
|
+
* survives. Returning `undefined` opts an item out of deduplication, and falls
|
|
21
|
+
* back to a positional key.
|
|
22
|
+
* @property loadingPages - Page positions currently being fetched. Exposed on the
|
|
23
|
+
* root element as `data-loading-pages`.
|
|
24
|
+
* @property onLoadPageClick - Called with the page position a load button targets,
|
|
25
|
+
* either on click or on viewport entry when auto-loading is enabled.
|
|
26
|
+
* @property autoLoadPrevWhenVisible - Wraps the leading load button in an
|
|
27
|
+
* {@link IntersectionObserverComponent} and fires `onLoadPageClick` when it enters the viewport.
|
|
28
|
+
* @property autoLoadNextWhenVisible - Same, for the trailing load button.
|
|
29
|
+
* @property className - Additional class name(s) applied to the root element.
|
|
30
|
+
*/
|
|
31
|
+
export type Props<T> = WithClassName<{
|
|
32
|
+
pages: number[];
|
|
33
|
+
firstPagePos: number;
|
|
34
|
+
lastPagePos: number;
|
|
35
|
+
itemsPages: Map<number, T[]>;
|
|
36
|
+
filter: (item: T) => boolean;
|
|
37
|
+
display: (item: T) => ReactNode;
|
|
38
|
+
getIdentifier?: (item: T) => string | undefined;
|
|
39
|
+
loadingPages?: number[];
|
|
40
|
+
onLoadPageClick?: (pagePos: number) => void;
|
|
41
|
+
autoLoadPrevWhenVisible?: boolean;
|
|
42
|
+
autoLoadNextWhenVisible?: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Presentational layer of the paginated list. Renders already-loaded pages as a
|
|
46
|
+
* single flat item list, and interleaves load buttons wherever a page is missing.
|
|
47
|
+
*
|
|
48
|
+
* This component holds no state and performs no fetching. Loaded pages are sorted
|
|
49
|
+
* by position and flattened, so items appear in page order then in item order,
|
|
50
|
+
* with no per-page wrapper element.
|
|
51
|
+
*
|
|
52
|
+
* ### Load buttons
|
|
53
|
+
* One button is rendered per missing page position:
|
|
54
|
+
* - before the first loaded page, unless it is already `firstPagePos`,
|
|
55
|
+
* - in place of each page missing between two loaded pages,
|
|
56
|
+
* - after the last loaded page, unless it is already `lastPagePos`.
|
|
57
|
+
*
|
|
58
|
+
* ### CSS elements
|
|
59
|
+
* - `item` — wraps each rendered item. Carries `data-page`.
|
|
60
|
+
* - `load` — a load button. Rendered empty, so its label belongs in CSS.
|
|
61
|
+
* Carries `data-page` and a `prev`, `next` or `gap` modifier.
|
|
62
|
+
* - `load-observer` — the intersection observer wrapping an auto-loading button.
|
|
63
|
+
* Present only when `autoLoadPrevWhenVisible` or `autoLoadNextWhenVisible` is on.
|
|
64
|
+
* Carries a `prev` or `next` modifier.
|
|
65
|
+
*
|
|
66
|
+
* ### Data attributes on the root element
|
|
67
|
+
* - `data-loading-pages` — comma-separated ascending list of the pages being
|
|
68
|
+
* fetched, e.g. `"1,3,6"`. Absent entirely when nothing is loading.
|
|
69
|
+
*
|
|
70
|
+
* @param props - Component properties.
|
|
71
|
+
* @see {@link Props}
|
|
72
|
+
* @returns A flat list of items with load buttons in place of missing pages.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* Deduplication runs after `filter`, so an item hidden by `filter` never evicts
|
|
76
|
+
* an earlier duplicate.
|
|
77
|
+
*/
|
|
78
|
+
export declare const ListLoaderControlled: <T>({ className, pages, firstPagePos, lastPagePos, itemsPages, filter, display, getIdentifier, loadingPages, onLoadPageClick, autoLoadPrevWhenVisible, autoLoadNextWhenVisible }: Props<T>) => ReactNode;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { clss } from '../../agnostic/css/clss/index.js';
|
|
3
|
+
import { IntersectionObserverComponent } from '../IntersectionObserver/index.js';
|
|
4
|
+
import { mergeClassNames } from '../utils/index.js';
|
|
5
|
+
import { listLoader as publicClassName } from '../public-classnames.js';
|
|
6
|
+
import { rangeBetween } from './utils.js';
|
|
7
|
+
import cssModule from './styles.module.css';
|
|
8
|
+
/**
|
|
9
|
+
* Presentational layer of the paginated list. Renders already-loaded pages as a
|
|
10
|
+
* single flat item list, and interleaves load buttons wherever a page is missing.
|
|
11
|
+
*
|
|
12
|
+
* This component holds no state and performs no fetching. Loaded pages are sorted
|
|
13
|
+
* by position and flattened, so items appear in page order then in item order,
|
|
14
|
+
* with no per-page wrapper element.
|
|
15
|
+
*
|
|
16
|
+
* ### Load buttons
|
|
17
|
+
* One button is rendered per missing page position:
|
|
18
|
+
* - before the first loaded page, unless it is already `firstPagePos`,
|
|
19
|
+
* - in place of each page missing between two loaded pages,
|
|
20
|
+
* - after the last loaded page, unless it is already `lastPagePos`.
|
|
21
|
+
*
|
|
22
|
+
* ### CSS elements
|
|
23
|
+
* - `item` — wraps each rendered item. Carries `data-page`.
|
|
24
|
+
* - `load` — a load button. Rendered empty, so its label belongs in CSS.
|
|
25
|
+
* Carries `data-page` and a `prev`, `next` or `gap` modifier.
|
|
26
|
+
* - `load-observer` — the intersection observer wrapping an auto-loading button.
|
|
27
|
+
* Present only when `autoLoadPrevWhenVisible` or `autoLoadNextWhenVisible` is on.
|
|
28
|
+
* Carries a `prev` or `next` modifier.
|
|
29
|
+
*
|
|
30
|
+
* ### Data attributes on the root element
|
|
31
|
+
* - `data-loading-pages` — comma-separated ascending list of the pages being
|
|
32
|
+
* fetched, e.g. `"1,3,6"`. Absent entirely when nothing is loading.
|
|
33
|
+
*
|
|
34
|
+
* @param props - Component properties.
|
|
35
|
+
* @see {@link Props}
|
|
36
|
+
* @returns A flat list of items with load buttons in place of missing pages.
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* Deduplication runs after `filter`, so an item hidden by `filter` never evicts
|
|
40
|
+
* an earlier duplicate.
|
|
41
|
+
*/
|
|
42
|
+
export const ListLoaderControlled = ({ className, pages, firstPagePos, lastPagePos, itemsPages, filter, display, getIdentifier, loadingPages, onLoadPageClick, autoLoadPrevWhenVisible, autoLoadNextWhenVisible }) => {
|
|
43
|
+
const inBoundsPages = pages.filter(pagePos => pagePos >= firstPagePos && pagePos <= lastPagePos);
|
|
44
|
+
const filteredItems = Array.from(itemsPages)
|
|
45
|
+
.filter(([pagePos]) => inBoundsPages.includes(pagePos))
|
|
46
|
+
.sort(([pageA], [pageB]) => pageA - pageB)
|
|
47
|
+
.flatMap(([pagePos, items]) => items.map((item, itemPos) => ({ item, pagePos, itemPos })))
|
|
48
|
+
.filter(({ item }) => filter(item));
|
|
49
|
+
const identifiers = filteredItems.map(({ item }) => getIdentifier?.(item));
|
|
50
|
+
const displayedItems = filteredItems.filter((_, pos) => {
|
|
51
|
+
const identifier = identifiers[pos];
|
|
52
|
+
if (identifier === undefined)
|
|
53
|
+
return true;
|
|
54
|
+
return identifiers.lastIndexOf(identifier) === pos;
|
|
55
|
+
});
|
|
56
|
+
const loadedPages = Array.from(itemsPages.keys())
|
|
57
|
+
.filter(pagePos => inBoundsPages.includes(pagePos))
|
|
58
|
+
.sort((a, b) => a - b);
|
|
59
|
+
const firstLoadedPage = loadedPages[0];
|
|
60
|
+
const lastLoadedPage = loadedPages[loadedPages.length - 1];
|
|
61
|
+
const gapPages = loadedPages.flatMap((pagePos, pos) => {
|
|
62
|
+
const prevPage = loadedPages[pos - 1];
|
|
63
|
+
if (prevPage === undefined)
|
|
64
|
+
return [];
|
|
65
|
+
return rangeBetween(prevPage + 1, pagePos - 1);
|
|
66
|
+
});
|
|
67
|
+
const slots = [
|
|
68
|
+
...firstLoadedPage !== undefined && firstLoadedPage > firstPagePos
|
|
69
|
+
? [{ pagePos: firstLoadedPage - 1, kind: 'prev' }]
|
|
70
|
+
: [],
|
|
71
|
+
...loadedPages.map(pagePos => ({ pagePos, kind: 'items' })),
|
|
72
|
+
...gapPages.map(pagePos => ({ pagePos, kind: 'gap' })),
|
|
73
|
+
...lastLoadedPage !== undefined && lastLoadedPage < lastPagePos
|
|
74
|
+
? [{ pagePos: lastLoadedPage + 1, kind: 'next' }]
|
|
75
|
+
: []
|
|
76
|
+
].sort((a, b) => a.pagePos - b.pagePos);
|
|
77
|
+
const sortedLoadingPages = [...loadingPages ?? []]
|
|
78
|
+
.filter(pagePos => inBoundsPages.includes(pagePos))
|
|
79
|
+
.sort((a, b) => a - b);
|
|
80
|
+
const c = clss(publicClassName, { cssModule });
|
|
81
|
+
const rootClss = mergeClassNames(c(null), className);
|
|
82
|
+
const renderLoadButton = (pagePos, kind) => {
|
|
83
|
+
const button = _jsx("button", { className: c('load', kind), "data-page": pagePos, onClick: () => onLoadPageClick?.(pagePos) }, `load/${pagePos}`);
|
|
84
|
+
const autoLoads = (kind === 'prev' && autoLoadPrevWhenVisible === true)
|
|
85
|
+
|| (kind === 'next' && autoLoadNextWhenVisible === true);
|
|
86
|
+
if (!autoLoads)
|
|
87
|
+
return button;
|
|
88
|
+
return _jsx(IntersectionObserverComponent, { className: c('load-observer', kind), onIntersected: ({ ioEntry }) => {
|
|
89
|
+
if (ioEntry?.isIntersecting !== true)
|
|
90
|
+
return;
|
|
91
|
+
onLoadPageClick?.(pagePos);
|
|
92
|
+
}, children: button }, `load/${pagePos}`);
|
|
93
|
+
};
|
|
94
|
+
return _jsx("div", { className: rootClss, "data-loading-pages": sortedLoadingPages.length === 0 ? undefined : sortedLoadingPages.join(','), children: slots.map(({ pagePos, kind }) => kind === 'items'
|
|
95
|
+
? displayedItems
|
|
96
|
+
.filter(entry => entry.pagePos === pagePos)
|
|
97
|
+
.map(({ item, itemPos }) => _jsx("div", { className: c('item'), "data-page": pagePos, children: display(item) }, getIdentifier?.(item) ?? `${pagePos}/${itemPos}`))
|
|
98
|
+
: renderLoadButton(pagePos, kind)) });
|
|
99
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type Props as ControlledProps } from './index.controlled.js';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the {@link ListLoader} component.
|
|
5
|
+
*
|
|
6
|
+
* Extends {@link ControlledProps} — minus the data it derives itself — with
|
|
7
|
+
* fetching, staleness and page-set management.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The item type carried by each page.
|
|
10
|
+
*
|
|
11
|
+
* @property pages - Page positions to keep loaded. When provided, the component
|
|
12
|
+
* is fully controlled: load buttons only report clicks and never change the set
|
|
13
|
+
* themselves. When omitted, the set is managed internally.
|
|
14
|
+
* @property defaultPage - Page loaded first in uncontrolled mode. Clamped into
|
|
15
|
+
* `firstPagePos`–`lastPagePos`, and defaults to `firstPagePos`. Ignored when
|
|
16
|
+
* `pages` is provided.
|
|
17
|
+
* @property fillGaps - When `true` (the default), any page missing between the
|
|
18
|
+
* lowest and highest requested page is requested automatically, so the loaded
|
|
19
|
+
* range stays contiguous. Ignored when `pages` is provided.
|
|
20
|
+
* @property dropPagesFurtherThan - Maximum distance, in pages, kept around a page
|
|
21
|
+
* loaded through a load button. Pages further away are dropped from state and
|
|
22
|
+
* from the DOM. Applies to load-button activations only, never to retries or
|
|
23
|
+
* stale reloads. Ignored when `pages` is provided.
|
|
24
|
+
* @property fetch - Fetches one page's items. Rejections are reported through
|
|
25
|
+
* `onFetchError` and retried according to `fetchRetriesNb`.
|
|
26
|
+
* @property staleAfterMs - Delay after which a loaded page is refetched, counted
|
|
27
|
+
* from its own last successful load. When omitted, pages are never refreshed.
|
|
28
|
+
* @property onFetchSuccess - Called after a page's items have been stored. Not
|
|
29
|
+
* called for a page dropped while its request was in flight.
|
|
30
|
+
* @property onFetchError - Called on every failed attempt, not only once retries
|
|
31
|
+
* are exhausted. When omitted, failures are logged with `console.warn`.
|
|
32
|
+
* @property fetchRetriesNb - Number of retries after a failed fetch. Defaults to
|
|
33
|
+
* `Infinity`, so a page keeps retrying until it succeeds.
|
|
34
|
+
* @property fetchRetriesDelayMs - Delay between two attempts. Defaults to `1000`.
|
|
35
|
+
*/
|
|
36
|
+
export type Props<T> = Omit<ControlledProps<T>, 'itemsPages' | 'loadingPages' | 'pages'> & {
|
|
37
|
+
pages?: number[];
|
|
38
|
+
defaultPage?: number;
|
|
39
|
+
fillGaps?: boolean;
|
|
40
|
+
dropPagesFurtherThan?: number;
|
|
41
|
+
fetch: (page: number) => Promise<T[]>;
|
|
42
|
+
staleAfterMs?: number;
|
|
43
|
+
onFetchSuccess?: (pagePos: number, items: T[]) => void;
|
|
44
|
+
onFetchError?: (pagePos: number, error: Error) => void;
|
|
45
|
+
fetchRetriesNb?: number;
|
|
46
|
+
fetchRetriesDelayMs?: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Paginated list abstraction. Fetches the pages it is asked for, keeps them
|
|
50
|
+
* fresh, and drives a {@link ListLoaderControlled} with the result.
|
|
51
|
+
*
|
|
52
|
+
* @param props - Component properties.
|
|
53
|
+
* @see {@link Props}
|
|
54
|
+
* @see {@link ListLoaderControlled} for the rendered markup and CSS elements.
|
|
55
|
+
* @returns A {@link ListLoaderControlled} fed with the loaded pages.
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* - In controlled mode (`pages` defined), the page set is entirely driven by the
|
|
59
|
+
* parent. `fillGaps` and `dropPagesFurtherThan` are inert, and load buttons only
|
|
60
|
+
* report through `onLoadPageClick`.
|
|
61
|
+
* - In uncontrolled mode, internal state is initialized from `defaultPage` and load
|
|
62
|
+
* buttons extend the set themselves. `onLoadPageClick` still fires, after the
|
|
63
|
+
* internal state has been updated.
|
|
64
|
+
* - A page removed from the effective set is dropped from memory, and a request
|
|
65
|
+
* still in flight for it is discarded on arrival rather than re-inserted.
|
|
66
|
+
* - No page outside `firstPagePos`–`lastPagePos` is ever fetched, whichever mode
|
|
67
|
+
* is in use.
|
|
68
|
+
*/
|
|
69
|
+
export declare const ListLoader: <T>({ className, pages, defaultPage, fillGaps, dropPagesFurtherThan, autoLoadPrevWhenVisible, autoLoadNextWhenVisible, firstPagePos, lastPagePos, fetch, filter, display, getIdentifier, onLoadPageClick, staleAfterMs, onFetchSuccess, onFetchError, fetchRetriesNb, fetchRetriesDelayMs }: Props<T>) => ReactNode;
|