@wordpress/element 6.43.0 → 6.44.1-next.v.202604091042.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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 6.44.0-next.0 (2026-04-09)
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/types.ts"],
4
- "sourcesContent": ["import type { ReactElement } from 'react';\n\n/**\n * This type is used by @wordpress/i18n to make sprintf type-safe.\n *\n * We don't want to import from there directly to avoid a circular dependency.\n */\ntype TranslatableText< T extends string > = string & {\n\treadonly __translatableText: T;\n};\n\n/**\n * The input that can be passed to `createInterpolateElement`.\n */\nexport type InterpolationInput = string | TranslatableText< string >;\n\n/**\n * The literal string extracted from the input.\n */\nexport type InterpolationString< Input > = Input extends TranslatableText<\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"],
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,20 +1,19 @@
1
1
  import type { ReactElement } from 'react';
2
2
  /**
3
- * This type is used by @wordpress/i18n to make sprintf type-safe.
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 TranslatableText<T extends string> = string & {
8
- readonly __translatableText: T;
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 | TranslatableText<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 TranslatableText<infer Text> ? Text : Input;
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;;;;GAIG;AACH,KAAK,gBAAgB,CAAE,CAAC,SAAS,MAAM,IAAK,MAAM,GAAG;IACpD,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,gBAAgB,CAAE,MAAM,CAAE,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAE,KAAK,IAAK,KAAK,SAAS,gBAAgB,CACxE,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"}
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.43.0",
3
+ "version": "6.44.1-next.v.202604091042.0+668146787",
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.43.0",
50
+ "@wordpress/escape-html": "^3.43.1-next.v.202604091042.0+668146787",
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": "2cea90674d11aa521ec3f71652fb3a6a4c383969"
59
+ "gitHead": "73606df74f1c38a084bfa5db97205259ef817593"
60
60
  }
@@ -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 { ExtractTags, InterpolationString } from '../types';
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 TranslatableText input', () => {
231
- // Type-level test: verify InterpolationString unwraps TranslatableText.
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 __translatableText: '<a>link</a> and <em>emphasis</em>';
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/types.ts CHANGED
@@ -1,23 +1,22 @@
1
1
  import type { ReactElement } from 'react';
2
2
 
3
3
  /**
4
- * This type is used by @wordpress/i18n to make sprintf type-safe.
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 TranslatableText< T extends string > = string & {
9
- readonly __translatableText: T;
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 | TranslatableText< 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 TranslatableText<
19
+ export type InterpolationString< Input > = Input extends TransformedText<
21
20
  infer Text
22
21
  >
23
22
  ? Text