@wordpress/element 6.43.0 → 6.44.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.
- package/CHANGELOG.md +6 -0
- package/build/react-platform.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build-module/react-platform.mjs.map +2 -2
- package/build-types/react-platform.d.ts.map +1 -1
- package/build-types/types.d.ts +6 -7
- package/build-types/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/react-platform.ts +2 -0
- package/src/test/create-interpolate-element.tsx +22 -4
- package/src/test/serialize.js +14 -2
- package/src/types.ts +6 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 6.44.0 (2026-04-15)
|
|
6
|
+
|
|
7
|
+
### Enhancement
|
|
8
|
+
|
|
9
|
+
- `createInterpolateElement` now infers tag names from `sprintf` return values, since `sprintf` returns `TransformedText<T>`. ([76974](https://github.com/WordPress/gutenberg/pull/76974))
|
|
10
|
+
|
|
5
11
|
## 6.43.0 (2026-04-01)
|
|
6
12
|
|
|
7
13
|
## 6.42.0 (2026-03-18)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/react-platform.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tcreatePortal,\n\tfindDOMNode,\n\tflushSync,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n} from 'react-dom';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\n\n/**\n * Creates a portal into which a component can be rendered.\n *\n * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235\n *\n * @param {React.ReactElement} child Any renderable child, such as an element,\n * string, or fragment.\n * @param {HTMLElement} container DOM node into which element should be rendered.\n */\nexport { createPortal };\n\n/**\n * Finds the dom node of a React component.\n *\n * @param {React.ComponentType} component Component's instance.\n */\nexport { findDOMNode };\n\n/**\n * Forces React to flush any updates inside the provided callback synchronously.\n *\n * @param {Function} callback Callback to run synchronously.\n */\nexport { flushSync };\n\n/**\n * Renders a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `createRoot` instead.\n * @see https://react.dev/reference/react-dom/render\n */\nexport { render };\n\n/**\n * Hydrates a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `hydrateRoot` instead.\n * @see https://react.dev/reference/react-dom/hydrate\n */\nexport { hydrate };\n\n/**\n * Creates a new React root for the target DOM node.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/createRoot\n */\nexport { createRoot };\n\n/**\n * Creates a new React root for the target DOM node and hydrates it with a pre-generated markup.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/hydrateRoot\n */\nexport { hydrateRoot };\n\n/**\n * Removes any mounted element from the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `root.unmount()` instead.\n * @see https://react.dev/reference/react-dom/unmountComponentAtNode\n */\nexport { unmountComponentAtNode };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tcreatePortal,\n\tfindDOMNode,\n\tflushSync,\n\t/* eslint-disable react/no-deprecated */\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\t/* eslint-enable react/no-deprecated */\n} from 'react-dom';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\n\n/**\n * Creates a portal into which a component can be rendered.\n *\n * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235\n *\n * @param {React.ReactElement} child Any renderable child, such as an element,\n * string, or fragment.\n * @param {HTMLElement} container DOM node into which element should be rendered.\n */\nexport { createPortal };\n\n/**\n * Finds the dom node of a React component.\n *\n * @param {React.ComponentType} component Component's instance.\n */\nexport { findDOMNode };\n\n/**\n * Forces React to flush any updates inside the provided callback synchronously.\n *\n * @param {Function} callback Callback to run synchronously.\n */\nexport { flushSync };\n\n/**\n * Renders a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `createRoot` instead.\n * @see https://react.dev/reference/react-dom/render\n */\nexport { render };\n\n/**\n * Hydrates a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `hydrateRoot` instead.\n * @see https://react.dev/reference/react-dom/hydrate\n */\nexport { hydrate };\n\n/**\n * Creates a new React root for the target DOM node.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/createRoot\n */\nexport { createRoot };\n\n/**\n * Creates a new React root for the target DOM node and hydrates it with a pre-generated markup.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/hydrateRoot\n */\nexport { hydrateRoot };\n\n/**\n * Removes any mounted element from the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `root.unmount()` instead.\n * @see https://react.dev/reference/react-dom/unmountComponentAtNode\n */\nexport { unmountComponentAtNode };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBASO;AACP,oBAAwC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/types.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/types.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ReactElement } from 'react';\n\n/**\n *
|
|
4
|
+
"sourcesContent": ["import type { ReactElement } from 'react';\n\n/**\n * Mirrors `TransformedText` from @wordpress/i18n.\n * We don't import directly to avoid a circular dependency.\n */\ntype TransformedText< T extends string > = string & {\n\treadonly __transformedText: T;\n};\n\n/**\n * The input that can be passed to `createInterpolateElement`.\n */\nexport type InterpolationInput = string | TransformedText< string >;\n\n/**\n * The literal string extracted from the input.\n */\nexport type InterpolationString< Input > = Input extends TransformedText<\n\tinfer Text\n>\n\t? Text\n\t: Input;\n\n/**\n * Recursively trims trailing spaces from a string type.\n * Matches the runtime tokenizer's `\\s*` before the closing `>` or `/>`.\n */\ntype TrimTrailingSpaces< S extends string > = S extends `${ infer Rest } `\n\t? TrimTrailingSpaces< Rest >\n\t: S;\n\n/**\n * Helper type to extract tag name and handle closing/self-closing indicators.\n * Filters out tags with spaces as they won't be parsed by the tokenizer.\n */\ntype ExtractTagName< T extends string > =\n\t// Skip closing tags like \"/div\"\n\tT extends `/${ string }`\n\t\t? never\n\t\t: TrimTrailingSpaces< T > extends infer Name extends string\n\t\t? Name extends ''\n\t\t\t? never // Empty tag name\n\t\t\t: Name extends `${ string } ${ string }`\n\t\t\t? never // Skip tags with inner spaces like \"spaced token\"\n\t\t\t: Name extends `${ infer Base }/`\n\t\t\t? Base // Self-closing tags like \"br/\"\n\t\t\t: Name // Regular opening tags like \"div\"\n\t\t: never;\n\n/**\n * Utility type to extract all tag names from a template literal string.\n * Only handles simple tags without attributes, matching the runtime tokenizer.\n */\nexport type ExtractTags< T extends string > =\n\tT extends `${ string }<${ infer Tag }>${ infer After }`\n\t\t? ExtractTagName< Tag > | ExtractTags< After >\n\t\t: never;\n\n/**\n * Utility type to create a conversion map that:\n * - Makes extracted tag keys optional\n * - Only allows properties for tags found in the template literal\n */\nexport type ConversionMap< T extends string > = Partial<\n\tRecord< ExtractTags< T >, ReactElement >\n>;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/react-platform.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tcreatePortal,\n\tfindDOMNode,\n\tflushSync,\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n} from 'react-dom';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\n\n/**\n * Creates a portal into which a component can be rendered.\n *\n * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235\n *\n * @param {React.ReactElement} child Any renderable child, such as an element,\n * string, or fragment.\n * @param {HTMLElement} container DOM node into which element should be rendered.\n */\nexport { createPortal };\n\n/**\n * Finds the dom node of a React component.\n *\n * @param {React.ComponentType} component Component's instance.\n */\nexport { findDOMNode };\n\n/**\n * Forces React to flush any updates inside the provided callback synchronously.\n *\n * @param {Function} callback Callback to run synchronously.\n */\nexport { flushSync };\n\n/**\n * Renders a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `createRoot` instead.\n * @see https://react.dev/reference/react-dom/render\n */\nexport { render };\n\n/**\n * Hydrates a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `hydrateRoot` instead.\n * @see https://react.dev/reference/react-dom/hydrate\n */\nexport { hydrate };\n\n/**\n * Creates a new React root for the target DOM node.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/createRoot\n */\nexport { createRoot };\n\n/**\n * Creates a new React root for the target DOM node and hydrates it with a pre-generated markup.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/hydrateRoot\n */\nexport { hydrateRoot };\n\n/**\n * Removes any mounted element from the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `root.unmount()` instead.\n * @see https://react.dev/reference/react-dom/unmountComponentAtNode\n */\nexport { unmountComponentAtNode };\n"],
|
|
5
|
-
"mappings": ";AAGA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tcreatePortal,\n\tfindDOMNode,\n\tflushSync,\n\t/* eslint-disable react/no-deprecated */\n\trender,\n\thydrate,\n\tunmountComponentAtNode,\n\t/* eslint-enable react/no-deprecated */\n} from 'react-dom';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\n\n/**\n * Creates a portal into which a component can be rendered.\n *\n * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235\n *\n * @param {React.ReactElement} child Any renderable child, such as an element,\n * string, or fragment.\n * @param {HTMLElement} container DOM node into which element should be rendered.\n */\nexport { createPortal };\n\n/**\n * Finds the dom node of a React component.\n *\n * @param {React.ComponentType} component Component's instance.\n */\nexport { findDOMNode };\n\n/**\n * Forces React to flush any updates inside the provided callback synchronously.\n *\n * @param {Function} callback Callback to run synchronously.\n */\nexport { flushSync };\n\n/**\n * Renders a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `createRoot` instead.\n * @see https://react.dev/reference/react-dom/render\n */\nexport { render };\n\n/**\n * Hydrates a given element into the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `hydrateRoot` instead.\n * @see https://react.dev/reference/react-dom/hydrate\n */\nexport { hydrate };\n\n/**\n * Creates a new React root for the target DOM node.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/createRoot\n */\nexport { createRoot };\n\n/**\n * Creates a new React root for the target DOM node and hydrates it with a pre-generated markup.\n *\n * @since 6.2.0 Introduced in WordPress core.\n * @see https://react.dev/reference/react-dom/client/hydrateRoot\n */\nexport { hydrateRoot };\n\n/**\n * Removes any mounted element from the target DOM node.\n *\n * @deprecated since WordPress 6.2.0. Use `root.unmount()` instead.\n * @see https://react.dev/reference/react-dom/unmountComponentAtNode\n */\nexport { unmountComponentAtNode };\n"],
|
|
5
|
+
"mappings": ";AAGA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AACP,SAAS,YAAY,mBAAmB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-platform.d.ts","sourceRoot":"","sources":["../src/react-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACN,YAAY,EACZ,WAAW,EACX,SAAS,
|
|
1
|
+
{"version":3,"file":"react-platform.d.ts","sourceRoot":"","sources":["../src/react-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACN,YAAY,EACZ,WAAW,EACX,SAAS,EAET,MAAM,EACN,OAAO,EACP,sBAAsB,EAEtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB;;;;;GAKG;AACH,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB;;;;;GAKG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;;;GAKG;AACH,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
package/build-types/types.d.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* We don't want to import from there directly to avoid a circular dependency.
|
|
3
|
+
* Mirrors `TransformedText` from @wordpress/i18n.
|
|
4
|
+
* We don't import directly to avoid a circular dependency.
|
|
6
5
|
*/
|
|
7
|
-
type
|
|
8
|
-
readonly
|
|
6
|
+
type TransformedText<T extends string> = string & {
|
|
7
|
+
readonly __transformedText: T;
|
|
9
8
|
};
|
|
10
9
|
/**
|
|
11
10
|
* The input that can be passed to `createInterpolateElement`.
|
|
12
11
|
*/
|
|
13
|
-
export type InterpolationInput = string |
|
|
12
|
+
export type InterpolationInput = string | TransformedText<string>;
|
|
14
13
|
/**
|
|
15
14
|
* The literal string extracted from the input.
|
|
16
15
|
*/
|
|
17
|
-
export type InterpolationString<Input> = Input extends
|
|
16
|
+
export type InterpolationString<Input> = Input extends TransformedText<infer Text> ? Text : Input;
|
|
18
17
|
/**
|
|
19
18
|
* Recursively trims trailing spaces from a string type.
|
|
20
19
|
* Matches the runtime tokenizer's `\s*` before the closing `>` or `/>`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C;;;GAGG;AACH,KAAK,eAAe,CAAE,CAAC,SAAS,MAAM,IAAK,MAAM,GAAG;IACnD,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,eAAe,CAAE,MAAM,CAAE,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAE,KAAK,IAAK,KAAK,SAAS,eAAe,CACvE,MAAM,IAAI,CACV,GACE,IAAI,GACJ,KAAK,CAAC;AAET;;;GAGG;AACH,KAAK,kBAAkB,CAAE,CAAC,SAAS,MAAM,IAAK,CAAC,SAAS,GAAI,MAAM,IAAK,GAAG,GACvE,kBAAkB,CAAE,IAAI,CAAE,GAC1B,CAAC,CAAC;AAEL;;;GAGG;AACH,KAAK,cAAc,CAAE,CAAC,SAAS,MAAM,IAEpC,CAAC,SAAS,IAAK,MAAO,EAAE,GACrB,KAAK,GACL,kBAAkB,CAAE,CAAC,CAAE,SAAS,MAAM,IAAI,SAAS,MAAM,GACzD,IAAI,SAAS,EAAE,GACd,KAAK,GACL,IAAI,SAAS,GAAI,MAAO,IAAK,MAAO,EAAE,GACtC,KAAK,GACL,IAAI,SAAS,GAAI,MAAM,IAAK,GAAG,GAC/B,IAAI,GACJ,IAAI,GACL,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAE,CAAC,SAAS,MAAM,IACxC,CAAC,SAAS,GAAI,MAAO,IAAK,MAAM,GAAI,IAAK,MAAM,KAAM,EAAE,GACpD,cAAc,CAAE,GAAG,CAAE,GAAG,WAAW,CAAE,KAAK,CAAE,GAC5C,KAAK,CAAC;AAEV;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAE,CAAC,SAAS,MAAM,IAAK,OAAO,CACtD,MAAM,CAAE,WAAW,CAAE,CAAC,CAAE,EAAE,YAAY,CAAE,CACxC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/element",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.44.0",
|
|
4
4
|
"description": "Element React module for WordPress.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@types/react": "^18.3.27",
|
|
49
49
|
"@types/react-dom": "^18.3.1",
|
|
50
|
-
"@wordpress/escape-html": "^3.
|
|
50
|
+
"@wordpress/escape-html": "^3.44.0",
|
|
51
51
|
"change-case": "^4.1.2",
|
|
52
52
|
"is-plain-object": "^5.0.0",
|
|
53
53
|
"react": "^18.3.0",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "b862d8c84121a47bbeff882f6c87e61681ce2e0d"
|
|
60
60
|
}
|
package/src/react-platform.ts
CHANGED
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
createPortal,
|
|
6
6
|
findDOMNode,
|
|
7
7
|
flushSync,
|
|
8
|
+
/* eslint-disable react/no-deprecated */
|
|
8
9
|
render,
|
|
9
10
|
hydrate,
|
|
10
11
|
unmountComponentAtNode,
|
|
12
|
+
/* eslint-enable react/no-deprecated */
|
|
11
13
|
} from 'react-dom';
|
|
12
14
|
import { createRoot, hydrateRoot } from 'react-dom/client';
|
|
13
15
|
|
|
@@ -8,7 +8,11 @@ import { render } from '@testing-library/react';
|
|
|
8
8
|
*/
|
|
9
9
|
import { createElement, Fragment, Component } from '../react';
|
|
10
10
|
import createInterpolateElement from '../create-interpolate-element';
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
ExtractTags,
|
|
13
|
+
InterpolationInput,
|
|
14
|
+
InterpolationString,
|
|
15
|
+
} from '../types';
|
|
12
16
|
|
|
13
17
|
describe( 'createInterpolateElement', () => {
|
|
14
18
|
it( 'throws an error when there is no conversion map', () => {
|
|
@@ -227,17 +231,31 @@ describe( 'createInterpolateElement', () => {
|
|
|
227
231
|
const tags: Tags[] = [ 'a', 'b', 'c' ];
|
|
228
232
|
expect( tags ).toHaveLength( 3 );
|
|
229
233
|
} );
|
|
230
|
-
it( 'extracts tags from a
|
|
231
|
-
// Type-level test: verify InterpolationString unwraps
|
|
234
|
+
it( 'extracts tags from a TransformedText input', () => {
|
|
235
|
+
// Type-level test: verify InterpolationString unwraps TransformedText.
|
|
232
236
|
type Text = InterpolationString<
|
|
233
237
|
string & {
|
|
234
|
-
readonly
|
|
238
|
+
readonly __transformedText: '<a>link</a> and <em>emphasis</em>';
|
|
235
239
|
}
|
|
236
240
|
>;
|
|
237
241
|
type Tags = ExtractTags< Text >;
|
|
238
242
|
const tags: Tags[] = [ 'a', 'em' ];
|
|
239
243
|
expect( tags ).toHaveLength( 2 );
|
|
240
244
|
} );
|
|
245
|
+
it( 'extracts tags from a sprintf (TransformedText) input', () => {
|
|
246
|
+
// Type-level test: sprintf returns TransformedText, so
|
|
247
|
+
// InterpolationString unwraps it for tag inference.
|
|
248
|
+
type SprintfResult = string & {
|
|
249
|
+
readonly __transformedText: '<Name>%1$s</Name> wrote <Link>%2$s</Link>';
|
|
250
|
+
};
|
|
251
|
+
const _check: InterpolationInput = '' as SprintfResult;
|
|
252
|
+
void _check;
|
|
253
|
+
|
|
254
|
+
type Text = InterpolationString< SprintfResult >;
|
|
255
|
+
type Tags = ExtractTags< Text >;
|
|
256
|
+
const tags: Tags[] = [ 'Name', 'Link' ];
|
|
257
|
+
expect( tags ).toHaveLength( 2 );
|
|
258
|
+
} );
|
|
241
259
|
it( 'handles parsing emojii correctly', () => {
|
|
242
260
|
const testString = '👳♀️<icon>🚨🤷♂️⛈️fully</icon> here';
|
|
243
261
|
const expectedElement = createElement(
|
package/src/test/serialize.js
CHANGED
|
@@ -183,7 +183,13 @@ describe( 'renderElement()', () => {
|
|
|
183
183
|
it( 'SVG attributes with dashes should be rendered as such - even with wrong casing', () => {
|
|
184
184
|
const result = renderElement(
|
|
185
185
|
<svg>
|
|
186
|
-
<rect
|
|
186
|
+
<rect
|
|
187
|
+
x="0"
|
|
188
|
+
y="0"
|
|
189
|
+
strokeWidth="5"
|
|
190
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
191
|
+
STROKELinejoin="miter"
|
|
192
|
+
></rect>
|
|
187
193
|
</svg>
|
|
188
194
|
);
|
|
189
195
|
|
|
@@ -194,7 +200,12 @@ describe( 'renderElement()', () => {
|
|
|
194
200
|
|
|
195
201
|
it( 'Case sensitive attributes should have the right casing - even with wrong casing', () => {
|
|
196
202
|
const result = renderElement(
|
|
197
|
-
<svg
|
|
203
|
+
<svg
|
|
204
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
205
|
+
ViEWBOx="0 0 1 1"
|
|
206
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
207
|
+
preserveAsPECTRatio="slice"
|
|
208
|
+
></svg>
|
|
198
209
|
);
|
|
199
210
|
|
|
200
211
|
expect( result ).toBe(
|
|
@@ -206,6 +217,7 @@ describe( 'renderElement()', () => {
|
|
|
206
217
|
const result = renderElement(
|
|
207
218
|
<svg
|
|
208
219
|
viewBox="0 0 1 1"
|
|
220
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
209
221
|
XLINKROLE="some-role"
|
|
210
222
|
xlinkShow="hello"
|
|
211
223
|
></svg>
|
package/src/types.ts
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* We don't want to import from there directly to avoid a circular dependency.
|
|
4
|
+
* Mirrors `TransformedText` from @wordpress/i18n.
|
|
5
|
+
* We don't import directly to avoid a circular dependency.
|
|
7
6
|
*/
|
|
8
|
-
type
|
|
9
|
-
readonly
|
|
7
|
+
type TransformedText< T extends string > = string & {
|
|
8
|
+
readonly __transformedText: T;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* The input that can be passed to `createInterpolateElement`.
|
|
14
13
|
*/
|
|
15
|
-
export type InterpolationInput = string |
|
|
14
|
+
export type InterpolationInput = string | TransformedText< string >;
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* The literal string extracted from the input.
|
|
19
18
|
*/
|
|
20
|
-
export type InterpolationString< Input > = Input extends
|
|
19
|
+
export type InterpolationString< Input > = Input extends TransformedText<
|
|
21
20
|
infer Text
|
|
22
21
|
>
|
|
23
22
|
? Text
|