@wordpress/element 6.30.0 → 6.30.1-next.836ecdcae.0

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.
Files changed (55) hide show
  1. package/README.md +10 -14
  2. package/build/create-interpolate-element.js +28 -53
  3. package/build/create-interpolate-element.js.map +1 -1
  4. package/build/index.js.map +1 -1
  5. package/build/platform.js +21 -5
  6. package/build/platform.js.map +1 -1
  7. package/build/raw-html.js +4 -2
  8. package/build/raw-html.js.map +1 -1
  9. package/build/react-platform.js.map +1 -1
  10. package/build/react.js +9 -22
  11. package/build/react.js.map +1 -1
  12. package/build/serialize.js +36 -89
  13. package/build/serialize.js.map +1 -1
  14. package/build/utils.js +2 -2
  15. package/build/utils.js.map +1 -1
  16. package/build-module/create-interpolate-element.js +28 -54
  17. package/build-module/create-interpolate-element.js.map +1 -1
  18. package/build-module/index.js.map +1 -1
  19. package/build-module/platform.js +21 -5
  20. package/build-module/platform.js.map +1 -1
  21. package/build-module/raw-html.js +4 -2
  22. package/build-module/raw-html.js.map +1 -1
  23. package/build-module/react-platform.js.map +1 -1
  24. package/build-module/react.js +9 -22
  25. package/build-module/react.js.map +1 -1
  26. package/build-module/serialize.js +36 -89
  27. package/build-module/serialize.js.map +1 -1
  28. package/build-module/utils.js +2 -2
  29. package/build-module/utils.js.map +1 -1
  30. package/build-types/create-interpolate-element.d.ts +8 -42
  31. package/build-types/create-interpolate-element.d.ts.map +1 -1
  32. package/build-types/index.d.ts +7 -7
  33. package/build-types/index.d.ts.map +1 -1
  34. package/build-types/platform.d.ts +48 -5
  35. package/build-types/platform.d.ts.map +1 -1
  36. package/build-types/raw-html.d.ts +7 -5
  37. package/build-types/raw-html.d.ts.map +1 -1
  38. package/build-types/react-platform.d.ts +62 -9
  39. package/build-types/react-platform.d.ts.map +1 -1
  40. package/build-types/react.d.ts +185 -58
  41. package/build-types/react.d.ts.map +1 -1
  42. package/build-types/serialize.d.ts +61 -43
  43. package/build-types/serialize.d.ts.map +1 -1
  44. package/build-types/utils.d.ts +7 -1
  45. package/build-types/utils.d.ts.map +1 -1
  46. package/package.json +3 -3
  47. package/src/{create-interpolate-element.js → create-interpolate-element.ts} +95 -64
  48. package/src/{platform.js → platform.ts} +27 -4
  49. package/src/{raw-html.js → raw-html.ts} +11 -3
  50. package/src/{react.js → react.ts} +40 -37
  51. package/src/{serialize.js → serialize.ts} +131 -144
  52. package/src/{utils.js → utils.ts} +4 -4
  53. package/tsconfig.tsbuildinfo +1 -1
  54. /package/src/{index.js → index.ts} +0 -0
  55. /package/src/{react-platform.js → react-platform.ts} +0 -0
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import { createElement, cloneElement, Fragment, isValidElement } from './react';
4
+ import {
5
+ createElement,
6
+ cloneElement,
7
+ Fragment,
8
+ isValidElement,
9
+ type Element as ReactElement,
10
+ } from './react';
5
11
 
6
- /**
7
- * Object containing a React element.
8
- *
9
- * @typedef {import('react').ReactElement} Element
10
- */
11
-
12
- let indoc, offset, output, stack;
12
+ let indoc: string;
13
+ let offset: number;
14
+ let output: ( string | ReactElement )[];
15
+ let stack: Frame[];
13
16
 
14
17
  /**
15
18
  * Matches tags in the localized string
@@ -23,28 +26,40 @@ let indoc, offset, output, stack;
23
26
  * isClosing: The closing slash, if it exists.
24
27
  * name: The name portion of the tag (strong, br) (if )
25
28
  * isSelfClosed: The slash on a self closing tag, if it exists.
26
- *
27
- * @type {RegExp}
28
29
  */
29
30
  const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g;
30
31
 
31
- /**
32
- * The stack frame tracking parse progress.
33
- *
34
- * @typedef Frame
35
- *
36
- * @property {Element} element A parent element which may still have
37
- * @property {number} tokenStart Offset at which parent element first
38
- * appears.
39
- * @property {number} tokenLength Length of string marking start of parent
40
- * element.
41
- * @property {number} [prevOffset] Running offset at which parsing should
42
- * continue.
43
- * @property {number} [leadingTextStart] Offset at which last closing element
44
- * finished, used for finding text between
45
- * elements.
46
- * @property {Element[]} children Children.
47
- */
32
+ interface Frame {
33
+ /**
34
+ * A parent element which may still have nested children not yet parsed.
35
+ */
36
+ element: ReactElement;
37
+
38
+ /**
39
+ * Offset at which parent element first appears.
40
+ */
41
+ tokenStart: number;
42
+
43
+ /**
44
+ * Length of string marking start of parent element.
45
+ */
46
+ tokenLength: number;
47
+
48
+ /**
49
+ * Running offset at which parsing should continue.
50
+ */
51
+ prevOffset?: number;
52
+
53
+ /**
54
+ * Offset at which last closing element finished, used for finding text between elements.
55
+ */
56
+ leadingTextStart?: number | null;
57
+
58
+ /**
59
+ * Children.
60
+ */
61
+ children: ( string | ReactElement )[];
62
+ }
48
63
 
49
64
  /**
50
65
  * Tracks recursive-descent parse state.
@@ -53,27 +68,27 @@ const tokenizer = /<(\/)?(\w+)\s*(\/)?>/g;
53
68
  * parsed.
54
69
  *
55
70
  * @private
56
- * @param {Element} element A parent element which may still have
57
- * nested children not yet parsed.
58
- * @param {number} tokenStart Offset at which parent element first
59
- * appears.
60
- * @param {number} tokenLength Length of string marking start of parent
61
- * element.
62
- * @param {number} [prevOffset] Running offset at which parsing should
63
- * continue.
64
- * @param {number} [leadingTextStart] Offset at which last closing element
65
- * finished, used for finding text between
66
- * elements.
71
+ * @param element A parent element which may still have
72
+ * nested children not yet parsed.
73
+ * @param tokenStart Offset at which parent element first
74
+ * appears.
75
+ * @param tokenLength Length of string marking start of parent
76
+ * element.
77
+ * @param prevOffset Running offset at which parsing should
78
+ * continue.
79
+ * @param leadingTextStart Offset at which last closing element
80
+ * finished, used for finding text between
81
+ * elements.
67
82
  *
68
- * @return {Frame} The stack frame tracking parse progress.
83
+ * @return The stack frame tracking parse progress.
69
84
  */
70
85
  function createFrame(
71
- element,
72
- tokenStart,
73
- tokenLength,
74
- prevOffset,
75
- leadingTextStart
76
- ) {
86
+ element: ReactElement,
87
+ tokenStart: number,
88
+ tokenLength: number,
89
+ prevOffset?: number,
90
+ leadingTextStart?: number | null
91
+ ): Frame {
77
92
  return {
78
93
  element,
79
94
  tokenStart,
@@ -105,13 +120,16 @@ function createFrame(
105
120
  * }
106
121
  * ```
107
122
  *
108
- * @param {string} interpolatedString The interpolation string to be parsed.
109
- * @param {Record<string, Element>} conversionMap The map used to convert the string to
110
- * a react element.
123
+ * @param interpolatedString The interpolation string to be parsed.
124
+ * @param conversionMap The map used to convert the string to
125
+ * a react element.
111
126
  * @throws {TypeError}
112
- * @return {Element} A wp element.
127
+ * @return A wp element.
113
128
  */
114
- const createInterpolateElement = ( interpolatedString, conversionMap ) => {
129
+ const createInterpolateElement = (
130
+ interpolatedString: string,
131
+ conversionMap: Record< string, ReactElement >
132
+ ): ReactElement => {
115
133
  indoc = interpolatedString;
116
134
  offset = 0;
117
135
  output = [];
@@ -138,35 +156,48 @@ const createInterpolateElement = ( interpolatedString, conversionMap ) => {
138
156
  *
139
157
  * @private
140
158
  *
141
- * @param {Object} conversionMap The map being validated.
159
+ * @param conversionMap The map being validated.
142
160
  *
143
- * @return {boolean} True means the map is valid.
161
+ * @return True means the map is valid.
144
162
  */
145
- const isValidConversionMap = ( conversionMap ) => {
146
- const isObject = typeof conversionMap === 'object';
163
+ const isValidConversionMap = (
164
+ conversionMap: Record< string, ReactElement >
165
+ ): boolean => {
166
+ const isObject =
167
+ typeof conversionMap === 'object' && conversionMap !== null;
147
168
  const values = isObject && Object.values( conversionMap );
148
169
  return (
149
170
  isObject &&
150
- values.length &&
171
+ values.length > 0 &&
151
172
  values.every( ( element ) => isValidElement( element ) )
152
173
  );
153
174
  };
154
175
 
176
+ type TokenType = 'no-more-tokens' | 'self-closed' | 'opener' | 'closer';
177
+ type TokenResult =
178
+ | [ TokenType & 'no-more-tokens' ]
179
+ | [
180
+ TokenType & ( 'self-closed' | 'opener' | 'closer' ),
181
+ string,
182
+ number,
183
+ number,
184
+ ];
185
+
155
186
  /**
156
187
  * This is the iterator over the matches in the string.
157
188
  *
158
189
  * @private
159
190
  *
160
- * @param {Object} conversionMap The conversion map for the string.
191
+ * @param conversionMap The conversion map for the string.
161
192
  *
162
- * @return {boolean} true for continuing to iterate, false for finished.
193
+ * @return true for continuing to iterate, false for finished.
163
194
  */
164
- function proceed( conversionMap ) {
195
+ function proceed( conversionMap: Record< string, ReactElement > ): boolean {
165
196
  const next = nextToken();
166
197
  const [ tokenType, name, startOffset, tokenLength ] = next;
167
198
  const stackDepth = stack.length;
168
199
  const leadingTextStart = startOffset > offset ? offset : null;
169
- if ( ! conversionMap[ name ] ) {
200
+ if ( name && ! conversionMap[ name ] ) {
170
201
  addText();
171
202
  return false;
172
203
  }
@@ -254,9 +285,9 @@ function proceed( conversionMap ) {
254
285
  *
255
286
  * @private
256
287
  *
257
- * @return {Array} An array of details for the token matched.
288
+ * @return An array of details for the token matched.
258
289
  */
259
- function nextToken() {
290
+ function nextToken(): TokenResult {
260
291
  const matches = tokenizer.exec( indoc );
261
292
  // We have no more tokens.
262
293
  if ( null === matches ) {
@@ -281,7 +312,7 @@ function nextToken() {
281
312
  *
282
313
  * @private
283
314
  */
284
- function addText() {
315
+ function addText(): void {
285
316
  const length = indoc.length - offset;
286
317
  if ( 0 === length ) {
287
318
  return;
@@ -298,7 +329,7 @@ function addText() {
298
329
  * @param {Frame} frame The Frame containing the child element and it's
299
330
  * token information.
300
331
  */
301
- function addChild( frame ) {
332
+ function addChild( frame: Frame ): void {
302
333
  const { element, tokenStart, tokenLength, prevOffset, children } = frame;
303
334
  const parent = stack[ stack.length - 1 ];
304
335
  const text = indoc.substr(
@@ -326,7 +357,7 @@ function addChild( frame ) {
326
357
  * helps capture any remaining nested text nodes in
327
358
  * the element.
328
359
  */
329
- function closeOuterElement( endOffset ) {
360
+ function closeOuterElement( endOffset: number ): void {
330
361
  const { element, leadingTextStart, prevOffset, tokenStart, children } =
331
362
  stack.pop();
332
363
 
@@ -6,11 +6,15 @@
6
6
  * Copyright (c) 2015-present, Facebook, Inc.
7
7
  *
8
8
  */
9
- const Platform = {
10
- OS: 'web',
11
- select: ( spec ) => ( 'web' in spec ? spec.web : spec.default ),
12
- isWeb: true,
9
+
10
+ /**
11
+ * Specification for platform-specific value selection.
12
+ */
13
+ type PlatformSelectSpec< T > = {
14
+ web?: T;
15
+ default?: T;
13
16
  };
17
+
14
18
  /**
15
19
  * Component used to detect the current Platform being used.
16
20
  * Use Platform.OS === 'web' to detect if running on web environment.
@@ -30,4 +34,23 @@ const Platform = {
30
34
  * } );
31
35
  * ```
32
36
  */
37
+ const Platform = {
38
+ /** Platform identifier. Will always be `'web'` in this module. */
39
+ OS: 'web' as const,
40
+
41
+ /**
42
+ * Select a value based on the platform.
43
+ *
44
+ * @template T
45
+ * @param spec - Object with optional platform-specific values.
46
+ * @return The selected value.
47
+ */
48
+ select< T >( spec: PlatformSelectSpec< T > ): T | undefined {
49
+ return 'web' in spec ? spec.web : spec.default;
50
+ },
51
+
52
+ /** Whether the platform is web */
53
+ isWeb: true,
54
+ };
55
+
33
56
  export default Platform;
@@ -3,7 +3,12 @@
3
3
  */
4
4
  import { Children, createElement } from './react';
5
5
 
6
- /** @typedef {{children: string} & import('react').ComponentPropsWithoutRef<'div'>} RawHTMLProps */
6
+ /**
7
+ * Props for the RawHTML component.
8
+ */
9
+ export type RawHTMLProps = {
10
+ children: string | string[];
11
+ } & React.ComponentPropsWithoutRef< 'div' >;
7
12
 
8
13
  /**
9
14
  * Component used to render unescaped HTML.
@@ -24,9 +29,12 @@ import { Children, createElement } from './react';
24
29
  * of strings. Other props will be passed through
25
30
  * to the div wrapper.
26
31
  *
27
- * @return {JSX.Element} Dangerously-rendering component.
32
+ * @return Dangerously-rendering component.
28
33
  */
29
- export default function RawHTML( { children, ...props } ) {
34
+ export default function RawHTML( {
35
+ children,
36
+ ...props
37
+ }: RawHTMLProps ): JSX.Element {
30
38
  let rawHtml = '';
31
39
 
32
40
  // Cast children as an array, and concatenate each element if it is a string.
@@ -34,45 +34,37 @@ import {
34
34
  lazy,
35
35
  Suspense,
36
36
  } from 'react';
37
+ import type { ReactNode } from 'react';
37
38
 
38
39
  /**
39
40
  * Object containing a React element.
40
- *
41
- * @typedef {import('react').ReactElement} Element
42
41
  */
42
+ export type Element = React.ReactElement;
43
43
 
44
44
  /**
45
45
  * Object containing a React component.
46
- *
47
- * @typedef {import('react').ComponentType} ComponentType
48
46
  */
47
+ export type ComponentType< T = any > = React.ComponentType< T >;
49
48
 
50
49
  /**
51
50
  * Object containing a React synthetic event.
52
- *
53
- * @typedef {import('react').SyntheticEvent} SyntheticEvent
54
51
  */
52
+ export type SyntheticEvent< T = Element > = React.SyntheticEvent< T >;
55
53
 
56
54
  /**
57
55
  * Object containing a React ref object.
58
- *
59
- * @template T
60
- * @typedef {import('react').RefObject<T>} RefObject<T>
61
56
  */
57
+ export type RefObject< T > = React.RefObject< T >;
62
58
 
63
59
  /**
64
60
  * Object containing a React ref callback.
65
- *
66
- * @template T
67
- * @typedef {import('react').RefCallback<T>} RefCallback<T>
68
61
  */
62
+ export type RefCallback< T > = React.RefCallback< T >;
69
63
 
70
64
  /**
71
65
  * Object containing a React ref.
72
- *
73
- * @template T
74
- * @typedef {import('react').Ref<T>} Ref<T>
75
66
  */
67
+ export type Ref< T > = React.Ref< T >;
76
68
 
77
69
  /**
78
70
  * Object that provides utilities for dealing with React children.
@@ -261,41 +253,52 @@ export { PureComponent };
261
253
  /**
262
254
  * Concatenate two or more React children objects.
263
255
  *
264
- * @param {...?Object} childrenArguments Array of children arguments (array of arrays/strings/objects) to concatenate.
265
- *
266
- * @return {Array} The concatenated value.
267
- */
268
- export function concatChildren( ...childrenArguments ) {
269
- return childrenArguments.reduce( ( accumulator, children, i ) => {
270
- Children.forEach( children, ( child, j ) => {
271
- if ( child && 'string' !== typeof child ) {
272
- child = cloneElement( child, {
273
- key: [ i, j ].join(),
274
- } );
275
- }
276
-
277
- accumulator.push( child );
278
- } );
279
-
280
- return accumulator;
281
- }, [] );
256
+ * @param childrenArguments - Array of children arguments (array of arrays/strings/objects) to concatenate.
257
+ * @return The concatenated value.
258
+ */
259
+ export function concatChildren(
260
+ ...childrenArguments: ReactNode[][]
261
+ ): ReactNode[] {
262
+ return childrenArguments.reduce< ReactNode[] >(
263
+ ( accumulator, children, i ) => {
264
+ Children.forEach( children, ( child, j ) => {
265
+ if ( isValidElement( child ) && typeof child !== 'string' ) {
266
+ child = cloneElement( child, {
267
+ key: [ i, j ].join(),
268
+ } );
269
+ }
270
+
271
+ accumulator.push( child );
272
+ } );
273
+
274
+ return accumulator;
275
+ },
276
+ []
277
+ );
282
278
  }
283
279
 
284
280
  /**
285
281
  * Switches the nodeName of all the elements in the children object.
286
282
  *
287
- * @param {?Object} children Children object.
288
- * @param {string} nodeName Node name.
283
+ * @param children Children object.
284
+ * @param nodeName Node name.
289
285
  *
290
- * @return {?Object} The updated children object.
286
+ * @return The updated children object.
291
287
  */
292
- export function switchChildrenNodeName( children, nodeName ) {
288
+ export function switchChildrenNodeName(
289
+ children: ReactNode,
290
+ nodeName: string
291
+ ): ReactNode {
293
292
  return (
294
293
  children &&
295
294
  Children.map( children, ( elt, index ) => {
296
295
  if ( typeof elt?.valueOf() === 'string' ) {
297
296
  return createElement( nodeName, { key: index }, elt );
298
297
  }
298
+ if ( ! isValidElement( elt ) ) {
299
+ return elt;
300
+ }
301
+
299
302
  const { children: childrenProp, ...props } = elt.props;
300
303
  return createElement(
301
304
  nodeName,