@wordpress/block-library 9.43.0 → 9.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/code/edit.cjs +2 -1
  3. package/build/code/edit.cjs.map +2 -2
  4. package/build/cover/edit/color-utils.cjs +1 -1
  5. package/build/cover/edit/color-utils.cjs.map +2 -2
  6. package/build/cover/edit/index.cjs +39 -26
  7. package/build/cover/edit/index.cjs.map +2 -2
  8. package/build/cover/embed-video-utils.cjs +9 -7
  9. package/build/cover/embed-video-utils.cjs.map +2 -2
  10. package/build/embed/embed-preview.cjs +2 -1
  11. package/build/embed/embed-preview.cjs.map +2 -2
  12. package/build/file/utils/index.cjs +1 -1
  13. package/build/file/utils/index.cjs.map +2 -2
  14. package/build/form/view.cjs +1 -1
  15. package/build/form/view.cjs.map +2 -2
  16. package/build/icon/edit.cjs +1 -3
  17. package/build/icon/edit.cjs.map +2 -2
  18. package/build/image/image.cjs +32 -9
  19. package/build/image/image.cjs.map +2 -2
  20. package/build/navigation-link/link-ui/index.cjs +12 -1
  21. package/build/navigation-link/link-ui/index.cjs.map +2 -2
  22. package/build/navigation-link/link-ui/page-creator.cjs +1 -1
  23. package/build/navigation-link/link-ui/page-creator.cjs.map +2 -2
  24. package/build/navigation-link/shared/update-attributes.cjs +1 -1
  25. package/build/navigation-link/shared/update-attributes.cjs.map +2 -2
  26. package/build/navigation-link/shared/use-link-preview.cjs +1 -1
  27. package/build/navigation-link/shared/use-link-preview.cjs.map +2 -2
  28. package/build/paragraph/use-enter.cjs +4 -5
  29. package/build/paragraph/use-enter.cjs.map +2 -2
  30. package/build/pattern/edit.cjs +1 -1
  31. package/build/pattern/edit.cjs.map +2 -2
  32. package/build/search/block.json +5 -5
  33. package/build/search/edit.cjs +8 -33
  34. package/build/search/edit.cjs.map +2 -2
  35. package/build/separator/transforms.cjs +12 -4
  36. package/build/separator/transforms.cjs.map +2 -2
  37. package/build/tab/add-tab-toolbar-control.cjs +5 -17
  38. package/build/tab/add-tab-toolbar-control.cjs.map +2 -2
  39. package/build/tab/block.json +2 -1
  40. package/build/tab/remove-tab-toolbar-control.cjs +1 -4
  41. package/build/tab/remove-tab-toolbar-control.cjs.map +2 -2
  42. package/build/tabs/edit.cjs +45 -45
  43. package/build/tabs/edit.cjs.map +2 -2
  44. package/build/tabs-menu/block.json +1 -2
  45. package/build/tabs-menu-item/block.json +0 -6
  46. package/build/tabs-menu-item/edit.cjs +2 -8
  47. package/build/tabs-menu-item/edit.cjs.map +2 -2
  48. package/build-module/code/edit.mjs +2 -1
  49. package/build-module/code/edit.mjs.map +2 -2
  50. package/build-module/cover/edit/color-utils.mjs +1 -1
  51. package/build-module/cover/edit/color-utils.mjs.map +2 -2
  52. package/build-module/cover/edit/index.mjs +47 -29
  53. package/build-module/cover/edit/index.mjs.map +2 -2
  54. package/build-module/cover/embed-video-utils.mjs +8 -6
  55. package/build-module/cover/embed-video-utils.mjs.map +2 -2
  56. package/build-module/embed/embed-preview.mjs +2 -1
  57. package/build-module/embed/embed-preview.mjs.map +2 -2
  58. package/build-module/file/utils/index.mjs +1 -1
  59. package/build-module/file/utils/index.mjs.map +2 -2
  60. package/build-module/form/view.mjs +1 -1
  61. package/build-module/form/view.mjs.map +2 -2
  62. package/build-module/icon/edit.mjs +1 -3
  63. package/build-module/icon/edit.mjs.map +2 -2
  64. package/build-module/image/image.mjs +32 -9
  65. package/build-module/image/image.mjs.map +2 -2
  66. package/build-module/navigation-link/link-ui/index.mjs +12 -1
  67. package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
  68. package/build-module/navigation-link/link-ui/page-creator.mjs +1 -1
  69. package/build-module/navigation-link/link-ui/page-creator.mjs.map +2 -2
  70. package/build-module/navigation-link/shared/update-attributes.mjs +1 -1
  71. package/build-module/navigation-link/shared/update-attributes.mjs.map +2 -2
  72. package/build-module/navigation-link/shared/use-link-preview.mjs +1 -1
  73. package/build-module/navigation-link/shared/use-link-preview.mjs.map +2 -2
  74. package/build-module/paragraph/use-enter.mjs +4 -5
  75. package/build-module/paragraph/use-enter.mjs.map +2 -2
  76. package/build-module/pattern/edit.mjs +1 -1
  77. package/build-module/pattern/edit.mjs.map +2 -2
  78. package/build-module/search/block.json +5 -5
  79. package/build-module/search/edit.mjs +8 -33
  80. package/build-module/search/edit.mjs.map +2 -2
  81. package/build-module/separator/transforms.mjs +17 -5
  82. package/build-module/separator/transforms.mjs.map +2 -2
  83. package/build-module/tab/add-tab-toolbar-control.mjs +6 -18
  84. package/build-module/tab/add-tab-toolbar-control.mjs.map +2 -2
  85. package/build-module/tab/block.json +2 -1
  86. package/build-module/tab/remove-tab-toolbar-control.mjs +1 -4
  87. package/build-module/tab/remove-tab-toolbar-control.mjs.map +2 -2
  88. package/build-module/tabs/edit.mjs +45 -45
  89. package/build-module/tabs/edit.mjs.map +2 -2
  90. package/build-module/tabs-menu/block.json +1 -2
  91. package/build-module/tabs-menu-item/block.json +0 -6
  92. package/build-module/tabs-menu-item/edit.mjs +3 -9
  93. package/build-module/tabs-menu-item/edit.mjs.map +2 -2
  94. package/build-style/code/style-rtl.css +1 -1
  95. package/build-style/code/style.css +1 -1
  96. package/build-style/post-author-biography/style-rtl.css +1 -0
  97. package/build-style/post-author-biography/style.css +1 -0
  98. package/build-style/style-rtl.css +11 -16
  99. package/build-style/style.css +11 -16
  100. package/build-style/tabs-menu-item/style-rtl.css +9 -6
  101. package/build-style/tabs-menu-item/style.css +9 -6
  102. package/package.json +38 -38
  103. package/src/code/edit.js +1 -0
  104. package/src/code/style.scss +1 -1
  105. package/src/cover/edit/color-utils.js +1 -1
  106. package/src/cover/edit/index.js +72 -35
  107. package/src/cover/embed-video-utils.js +10 -8
  108. package/src/embed/embed-preview.js +6 -5
  109. package/src/embed/test/index.native.js +3 -2
  110. package/src/file/utils/index.js +1 -1
  111. package/src/form/view.js +1 -1
  112. package/src/icon/edit.js +1 -3
  113. package/src/image/image.js +56 -9
  114. package/src/image/index.php +4 -4
  115. package/src/navigation-link/link-ui/index.js +12 -1
  116. package/src/navigation-link/link-ui/page-creator.js +1 -1
  117. package/src/navigation-link/shared/update-attributes.js +1 -1
  118. package/src/navigation-link/shared/use-link-preview.js +1 -1
  119. package/src/paragraph/use-enter.js +5 -5
  120. package/src/pattern/edit.js +1 -1
  121. package/src/post-author-biography/style.scss +1 -0
  122. package/src/search/block.json +5 -5
  123. package/src/search/edit.js +4 -35
  124. package/src/search/index.php +23 -3
  125. package/src/separator/transforms.js +19 -5
  126. package/src/style.scss +0 -1
  127. package/src/tab/add-tab-toolbar-control.js +24 -42
  128. package/src/tab/block.json +2 -1
  129. package/src/tab/index.php +21 -4
  130. package/src/tab/remove-tab-toolbar-control.js +1 -9
  131. package/src/tabs/edit.js +59 -66
  132. package/src/tabs/index.php +14 -15
  133. package/src/tabs-menu/block.json +1 -2
  134. package/src/tabs-menu/index.php +6 -17
  135. package/src/tabs-menu-item/block.json +0 -6
  136. package/src/tabs-menu-item/edit.js +3 -15
  137. package/src/tabs-menu-item/style.scss +10 -8
  138. package/build-style/tabs-menu/style-rtl.css +0 -8
  139. package/build-style/tabs-menu/style.css +0 -8
  140. package/src/tabs-menu/style.scss +0 -8
@@ -1,6 +1,6 @@
1
1
  // packages/block-library/src/tabs-menu-item/edit.js
2
2
  import clsx from "clsx";
3
- import { __, sprintf } from "@wordpress/i18n";
3
+ import { __ } from "@wordpress/i18n";
4
4
  import {
5
5
  useBlockProps,
6
6
  store as blockEditorStore,
@@ -12,7 +12,6 @@ import Controls from "./controls.mjs";
12
12
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
13
  var EMPTY_ARRAY = [];
14
14
  function Edit({
15
- attributes,
16
15
  context,
17
16
  clientId,
18
17
  __unstableLayoutClassNames: layoutClassNames
@@ -51,8 +50,7 @@ function Edit({
51
50
  },
52
51
  [clientId, tabsList]
53
52
  );
54
- const tabAnchor = attributes.anchor?.replace(/-button$/, "") ?? "";
55
- const tab = tabAnchor && tabsList.find((t) => t.id === tabAnchor) || tabsList[menuItemIndex] || {};
53
+ const tab = tabsList[menuItemIndex] || {};
56
54
  const tabListIndex = tab.index ?? menuItemIndex;
57
55
  const tabId = tab.id || `tab-${menuItemIndex}`;
58
56
  const tabClientId = tab.clientId || "";
@@ -105,11 +103,7 @@ function Edit({
105
103
  {
106
104
  tagName: "span",
107
105
  withoutInteractiveFormatting: true,
108
- placeholder: sprintf(
109
- /* translators: %d is the tab index + 1 */
110
- __("Tab title %d"),
111
- menuItemIndex + 1
112
- ),
106
+ placeholder: __("Tab title"),
113
107
  value: label,
114
108
  onChange: handleLabelChange
115
109
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/tabs-menu-item/edit.js"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { __, sprintf } from '@wordpress/i18n';\nimport {\n\tuseBlockProps,\n\tstore as blockEditorStore,\n\tRichText,\n} from '@wordpress/block-editor';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useMemo, useCallback } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport Controls from './controls';\n\nconst EMPTY_ARRAY = [];\n\nfunction Edit( {\n\tattributes,\n\tcontext,\n\tclientId,\n\t__unstableLayoutClassNames: layoutClassNames,\n} ) {\n\tconst tabsList = context[ 'core/tabs-list' ] || EMPTY_ARRAY;\n\tconst activeTabIndex = context[ 'core/tabs-activeTabIndex' ] ?? 0;\n\tconst editorActiveTabIndex = context[ 'core/tabs-editorActiveTabIndex' ];\n\n\tconst effectiveActiveIndex = useMemo( () => {\n\t\treturn editorActiveTabIndex ?? activeTabIndex;\n\t}, [ editorActiveTabIndex, activeTabIndex ] );\n\n\tconst { menuItemIndex, tabsClientId, selectedTabClientId } = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tgetBlockOrder,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t\tgetSelectedBlockClientIds,\n\t\t\t\thasSelectedInnerBlock,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst _tabsMenuClientId = getBlockRootClientId( clientId );\n\t\t\tconst _tabsClientId = _tabsMenuClientId\n\t\t\t\t? getBlockRootClientId( _tabsMenuClientId )\n\t\t\t\t: null;\n\n\t\t\tconst siblings = getBlockOrder( _tabsMenuClientId );\n\t\t\tconst _menuItemIndex = siblings.indexOf( clientId );\n\n\t\t\t// Find which tab panel block is currently selected.\n\t\t\tconst selectedIds = getSelectedBlockClientIds();\n\t\t\tlet _selectedTabClientId = null;\n\t\t\tfor ( const tab of tabsList ) {\n\t\t\t\tif (\n\t\t\t\t\tselectedIds.includes( tab.clientId ) ||\n\t\t\t\t\thasSelectedInnerBlock( tab.clientId, true )\n\t\t\t\t) {\n\t\t\t\t\t_selectedTabClientId = tab.clientId;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tmenuItemIndex: _menuItemIndex,\n\t\t\t\ttabsClientId: _tabsClientId,\n\t\t\t\tselectedTabClientId: _selectedTabClientId,\n\t\t\t};\n\t\t},\n\t\t[ clientId, tabsList ]\n\t);\n\n\t// Find the corresponding tab's anchor from this menu item's anchor\n\t// attribute (e.g., \"tab-1-button\" \u2192 \"tab-1\"), then look it up in tabsList.\n\t// Falls back to positional lookup when no anchor is set.\n\tconst tabAnchor = attributes.anchor?.replace( /-button$/, '' ) ?? '';\n\tconst tab =\n\t\t( tabAnchor && tabsList.find( ( t ) => t.id === tabAnchor ) ) ||\n\t\ttabsList[ menuItemIndex ] ||\n\t\t{};\n\n\t// tabListIndex is the tab's position in tabsList, used for active-state\n\t// checks and click handling.\n\tconst tabListIndex = tab.index ?? menuItemIndex;\n\n\tconst tabId = tab.id || `tab-${ menuItemIndex }`;\n\tconst tabClientId = tab.clientId || '';\n\tconst label = tab.label || '';\n\n\tconst isActive = tabListIndex === effectiveActiveIndex;\n\tconst isSelected = tabClientId === selectedTabClientId;\n\n\tconst { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } =\n\t\tuseDispatch( blockEditorStore );\n\n\tconst handleTabClick = useCallback(\n\t\t( event ) => {\n\t\t\tevent.preventDefault();\n\t\t\tif ( tabsClientId && tabListIndex !== effectiveActiveIndex ) {\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\tupdateBlockAttributes( tabsClientId, {\n\t\t\t\t\teditorActiveTabIndex: tabListIndex,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\ttabsClientId,\n\t\t\ttabListIndex,\n\t\t\teffectiveActiveIndex,\n\t\t\tupdateBlockAttributes,\n\t\t\t__unstableMarkNextChangeAsNotPersistent,\n\t\t]\n\t);\n\n\tconst handleLabelChange = useCallback(\n\t\t( newLabel ) => {\n\t\t\tif ( tabClientId ) {\n\t\t\t\tupdateBlockAttributes( tabClientId, { label: newLabel } );\n\t\t\t}\n\t\t},\n\t\t[ tabClientId, updateBlockAttributes ]\n\t);\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: clsx( layoutClassNames, {\n\t\t\t'is-active': isActive,\n\t\t\t'is-selected': isSelected,\n\t\t} ),\n\t\t'aria-controls': tabId,\n\t\t'aria-selected': isActive,\n\t\tid: `${ tabId }--tab`,\n\t\trole: 'tab',\n\t\ttabIndex: -1,\n\t\tonClick: handleTabClick,\n\t} );\n\n\treturn (\n\t\t<>\n\t\t\t<Controls tabsClientId={ tabsClientId } />\n\t\t\t<button { ...blockProps } type=\"button\">\n\t\t\t\t<RichText\n\t\t\t\t\ttagName=\"span\"\n\t\t\t\t\twithoutInteractiveFormatting\n\t\t\t\t\tplaceholder={ sprintf(\n\t\t\t\t\t\t/* translators: %d is the tab index + 1 */\n\t\t\t\t\t\t__( 'Tab title %d' ),\n\t\t\t\t\t\tmenuItemIndex + 1\n\t\t\t\t\t) }\n\t\t\t\t\tvalue={ label }\n\t\t\t\t\tonChange={ handleLabelChange }\n\t\t\t\t/>\n\t\t\t</button>\n\t\t</>\n\t);\n}\n\nexport default Edit;\n"],
5
- "mappings": ";AAGA,OAAO,UAAU;AAKjB,SAAS,IAAI,eAAe;AAC5B;AAAA,EACC;AAAA,EACA,SAAS;AAAA,EACT;AAAA,OACM;AACP,SAAS,WAAW,mBAAmB;AACvC,SAAS,SAAS,mBAAmB;AAKrC,OAAO,cAAc;AA0HnB,mBACC,KADD;AAxHF,IAAM,cAAc,CAAC;AAErB,SAAS,KAAM;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,4BAA4B;AAC7B,GAAI;AACH,QAAM,WAAW,QAAS,gBAAiB,KAAK;AAChD,QAAM,iBAAiB,QAAS,0BAA2B,KAAK;AAChE,QAAM,uBAAuB,QAAS,gCAAiC;AAEvE,QAAM,uBAAuB,QAAS,MAAM;AAC3C,WAAO,wBAAwB;AAAA,EAChC,GAAG,CAAE,sBAAsB,cAAe,CAAE;AAE5C,QAAM,EAAE,eAAe,cAAc,oBAAoB,IAAI;AAAA,IAC5D,CAAE,WAAY;AACb,YAAM;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,IAAI,OAAQ,gBAAiB;AAE7B,YAAM,oBAAoB,qBAAsB,QAAS;AACzD,YAAM,gBAAgB,oBACnB,qBAAsB,iBAAkB,IACxC;AAEH,YAAM,WAAW,cAAe,iBAAkB;AAClD,YAAM,iBAAiB,SAAS,QAAS,QAAS;AAGlD,YAAM,cAAc,0BAA0B;AAC9C,UAAI,uBAAuB;AAC3B,iBAAYA,QAAO,UAAW;AAC7B,YACC,YAAY,SAAUA,KAAI,QAAS,KACnC,sBAAuBA,KAAI,UAAU,IAAK,GACzC;AACD,iCAAuBA,KAAI;AAC3B;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,eAAe;AAAA,QACf,cAAc;AAAA,QACd,qBAAqB;AAAA,MACtB;AAAA,IACD;AAAA,IACA,CAAE,UAAU,QAAS;AAAA,EACtB;AAKA,QAAM,YAAY,WAAW,QAAQ,QAAS,YAAY,EAAG,KAAK;AAClE,QAAM,MACH,aAAa,SAAS,KAAM,CAAE,MAAO,EAAE,OAAO,SAAU,KAC1D,SAAU,aAAc,KACxB,CAAC;AAIF,QAAM,eAAe,IAAI,SAAS;AAElC,QAAM,QAAQ,IAAI,MAAM,OAAQ,aAAc;AAC9C,QAAM,cAAc,IAAI,YAAY;AACpC,QAAM,QAAQ,IAAI,SAAS;AAE3B,QAAM,WAAW,iBAAiB;AAClC,QAAM,aAAa,gBAAgB;AAEnC,QAAM,EAAE,yCAAyC,sBAAsB,IACtE,YAAa,gBAAiB;AAE/B,QAAM,iBAAiB;AAAA,IACtB,CAAE,UAAW;AACZ,YAAM,eAAe;AACrB,UAAK,gBAAgB,iBAAiB,sBAAuB;AAC5D,gDAAwC;AACxC,8BAAuB,cAAc;AAAA,UACpC,sBAAsB;AAAA,QACvB,CAAE;AAAA,MACH;AAAA,IACD;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,oBAAoB;AAAA,IACzB,CAAE,aAAc;AACf,UAAK,aAAc;AAClB,8BAAuB,aAAa,EAAE,OAAO,SAAS,CAAE;AAAA,MACzD;AAAA,IACD;AAAA,IACA,CAAE,aAAa,qBAAsB;AAAA,EACtC;AAEA,QAAM,aAAa,cAAe;AAAA,IACjC,WAAW,KAAM,kBAAkB;AAAA,MAClC,aAAa;AAAA,MACb,eAAe;AAAA,IAChB,CAAE;AAAA,IACF,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,IAAI,GAAI,KAAM;AAAA,IACd,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACV,CAAE;AAEF,SACC,iCACC;AAAA,wBAAC,YAAS,cAA8B;AAAA,IACxC,oBAAC,YAAS,GAAG,YAAa,MAAK,UAC9B;AAAA,MAAC;AAAA;AAAA,QACA,SAAQ;AAAA,QACR,8BAA4B;AAAA,QAC5B,aAAc;AAAA;AAAA,UAEb,GAAI,cAAe;AAAA,UACnB,gBAAgB;AAAA,QACjB;AAAA,QACA,OAAQ;AAAA,QACR,UAAW;AAAA;AAAA,IACZ,GACD;AAAA,KACD;AAEF;AAEA,IAAO,eAAQ;",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport {\n\tuseBlockProps,\n\tstore as blockEditorStore,\n\tRichText,\n} from '@wordpress/block-editor';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useMemo, useCallback } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport Controls from './controls';\n\nconst EMPTY_ARRAY = [];\n\nfunction Edit( {\n\tcontext,\n\tclientId,\n\t__unstableLayoutClassNames: layoutClassNames,\n} ) {\n\tconst tabsList = context[ 'core/tabs-list' ] || EMPTY_ARRAY;\n\tconst activeTabIndex = context[ 'core/tabs-activeTabIndex' ] ?? 0;\n\tconst editorActiveTabIndex = context[ 'core/tabs-editorActiveTabIndex' ];\n\n\tconst effectiveActiveIndex = useMemo( () => {\n\t\treturn editorActiveTabIndex ?? activeTabIndex;\n\t}, [ editorActiveTabIndex, activeTabIndex ] );\n\n\tconst { menuItemIndex, tabsClientId, selectedTabClientId } = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tgetBlockOrder,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t\tgetSelectedBlockClientIds,\n\t\t\t\thasSelectedInnerBlock,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst _tabsMenuClientId = getBlockRootClientId( clientId );\n\t\t\tconst _tabsClientId = _tabsMenuClientId\n\t\t\t\t? getBlockRootClientId( _tabsMenuClientId )\n\t\t\t\t: null;\n\n\t\t\tconst siblings = getBlockOrder( _tabsMenuClientId );\n\t\t\tconst _menuItemIndex = siblings.indexOf( clientId );\n\n\t\t\t// Find which tab panel block is currently selected.\n\t\t\tconst selectedIds = getSelectedBlockClientIds();\n\t\t\tlet _selectedTabClientId = null;\n\t\t\tfor ( const tab of tabsList ) {\n\t\t\t\tif (\n\t\t\t\t\tselectedIds.includes( tab.clientId ) ||\n\t\t\t\t\thasSelectedInnerBlock( tab.clientId, true )\n\t\t\t\t) {\n\t\t\t\t\t_selectedTabClientId = tab.clientId;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tmenuItemIndex: _menuItemIndex,\n\t\t\t\ttabsClientId: _tabsClientId,\n\t\t\t\tselectedTabClientId: _selectedTabClientId,\n\t\t\t};\n\t\t},\n\t\t[ clientId, tabsList ]\n\t);\n\n\tconst tab = tabsList[ menuItemIndex ] || {};\n\n\t// tabListIndex is the tab's position in tabsList, used for active-state\n\t// checks and click handling.\n\tconst tabListIndex = tab.index ?? menuItemIndex;\n\n\tconst tabId = tab.id || `tab-${ menuItemIndex }`;\n\tconst tabClientId = tab.clientId || '';\n\tconst label = tab.label || '';\n\n\tconst isActive = tabListIndex === effectiveActiveIndex;\n\tconst isSelected = tabClientId === selectedTabClientId;\n\n\tconst { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } =\n\t\tuseDispatch( blockEditorStore );\n\n\tconst handleTabClick = useCallback(\n\t\t( event ) => {\n\t\t\tevent.preventDefault();\n\t\t\tif ( tabsClientId && tabListIndex !== effectiveActiveIndex ) {\n\t\t\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\t\t\tupdateBlockAttributes( tabsClientId, {\n\t\t\t\t\teditorActiveTabIndex: tabListIndex,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\ttabsClientId,\n\t\t\ttabListIndex,\n\t\t\teffectiveActiveIndex,\n\t\t\tupdateBlockAttributes,\n\t\t\t__unstableMarkNextChangeAsNotPersistent,\n\t\t]\n\t);\n\n\tconst handleLabelChange = useCallback(\n\t\t( newLabel ) => {\n\t\t\tif ( tabClientId ) {\n\t\t\t\tupdateBlockAttributes( tabClientId, { label: newLabel } );\n\t\t\t}\n\t\t},\n\t\t[ tabClientId, updateBlockAttributes ]\n\t);\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: clsx( layoutClassNames, {\n\t\t\t'is-active': isActive,\n\t\t\t'is-selected': isSelected,\n\t\t} ),\n\t\t'aria-controls': tabId,\n\t\t'aria-selected': isActive,\n\t\tid: `${ tabId }--tab`,\n\t\trole: 'tab',\n\t\ttabIndex: -1,\n\t\tonClick: handleTabClick,\n\t} );\n\n\treturn (\n\t\t<>\n\t\t\t<Controls tabsClientId={ tabsClientId } />\n\t\t\t<button { ...blockProps } type=\"button\">\n\t\t\t\t<RichText\n\t\t\t\t\ttagName=\"span\"\n\t\t\t\t\twithoutInteractiveFormatting\n\t\t\t\t\tplaceholder={ __( 'Tab title' ) }\n\t\t\t\t\tvalue={ label }\n\t\t\t\t\tonChange={ handleLabelChange }\n\t\t\t\t/>\n\t\t\t</button>\n\t\t</>\n\t);\n}\n\nexport default Edit;\n"],
5
+ "mappings": "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",
6
6
  "names": ["tab"]
7
7
  }
@@ -5,7 +5,7 @@
5
5
  display: block;
6
6
  font-family: inherit;
7
7
  overflow-wrap: break-word;
8
- white-space: pre-wrap;
8
+ white-space: break-spaces;
9
9
  direction: ltr;
10
10
  text-align: initial;
11
11
  }
@@ -5,7 +5,7 @@
5
5
  display: block;
6
6
  font-family: inherit;
7
7
  overflow-wrap: break-word;
8
- white-space: pre-wrap;
8
+ white-space: break-spaces;
9
9
  /*!rtl:begin:ignore*/
10
10
  direction: ltr;
11
11
  text-align: initial;
@@ -1,3 +1,4 @@
1
1
  .wp-block-post-author-biography {
2
2
  box-sizing: border-box;
3
+ white-space: pre-wrap;
3
4
  }
@@ -1,3 +1,4 @@
1
1
  .wp-block-post-author-biography {
2
2
  box-sizing: border-box;
3
+ white-space: pre-wrap;
3
4
  }
@@ -427,7 +427,7 @@
427
427
  display: block;
428
428
  font-family: inherit;
429
429
  overflow-wrap: break-word;
430
- white-space: pre-wrap;
430
+ white-space: break-spaces;
431
431
  direction: ltr;
432
432
  text-align: initial;
433
433
  }
@@ -3632,6 +3632,7 @@ p.has-text-align-left[style*="writing-mode:vertical-lr"] {
3632
3632
 
3633
3633
  .wp-block-post-author-biography {
3634
3634
  box-sizing: border-box;
3635
+ white-space: pre-wrap;
3635
3636
  }
3636
3637
 
3637
3638
  :where(.wp-block-post-comments-form textarea),
@@ -4918,15 +4919,6 @@ ul.wp-block-rss.is-grid li {
4918
4919
  display: none;
4919
4920
  }
4920
4921
 
4921
- .wp-block-tabs-menu {
4922
- display: flex;
4923
- align-items: flex-end;
4924
- min-width: fit-content;
4925
- border-bottom-width: 1px;
4926
- border-bottom-style: solid;
4927
- border-bottom-color: #000;
4928
- }
4929
-
4930
4922
  .wp-block-tabs-menu-item {
4931
4923
  box-sizing: border-box;
4932
4924
  color: inherit;
@@ -4936,6 +4928,7 @@ ul.wp-block-rss.is-grid li {
4936
4928
  cursor: pointer;
4937
4929
  flex-basis: inherit !important;
4938
4930
  flex-grow: inherit !important;
4931
+ position: relative;
4939
4932
  border: none;
4940
4933
  background: none;
4941
4934
  appearance: none;
@@ -4950,12 +4943,14 @@ ul.wp-block-rss.is-grid li {
4950
4943
  text-transform: inherit;
4951
4944
  text-align: inherit;
4952
4945
  }
4953
- .wp-block-tabs-menu-item:focus-visible {
4954
- outline-offset: 2px;
4955
- }
4956
- .wp-block-tabs-menu-item[aria-selected=true], .wp-block-tabs-menu-item.is-active {
4957
- background-color: #000;
4958
- color: #fff;
4946
+ .wp-block-tabs-menu-item[aria-selected=true]::before, .wp-block-tabs-menu-item.is-active::before {
4947
+ content: "";
4948
+ position: absolute;
4949
+ border-bottom: 2px solid currentColor;
4950
+ pointer-events: none;
4951
+ right: 0;
4952
+ width: 100%;
4953
+ bottom: 0;
4959
4954
  }
4960
4955
 
4961
4956
  .wp-block-term-count {
@@ -430,7 +430,7 @@
430
430
  display: block;
431
431
  font-family: inherit;
432
432
  overflow-wrap: break-word;
433
- white-space: pre-wrap;
433
+ white-space: break-spaces;
434
434
  /*!rtl:begin:ignore*/
435
435
  direction: ltr;
436
436
  text-align: initial;
@@ -3662,6 +3662,7 @@ p.has-text-align-left[style*="writing-mode:vertical-lr"] {
3662
3662
 
3663
3663
  .wp-block-post-author-biography {
3664
3664
  box-sizing: border-box;
3665
+ white-space: pre-wrap;
3665
3666
  }
3666
3667
 
3667
3668
  :where(.wp-block-post-comments-form textarea),
@@ -4951,15 +4952,6 @@ ul.wp-block-rss.is-grid li {
4951
4952
  display: none;
4952
4953
  }
4953
4954
 
4954
- .wp-block-tabs-menu {
4955
- display: flex;
4956
- align-items: flex-end;
4957
- min-width: fit-content;
4958
- border-bottom-width: 1px;
4959
- border-bottom-style: solid;
4960
- border-bottom-color: #000;
4961
- }
4962
-
4963
4955
  .wp-block-tabs-menu-item {
4964
4956
  box-sizing: border-box;
4965
4957
  color: inherit;
@@ -4969,6 +4961,7 @@ ul.wp-block-rss.is-grid li {
4969
4961
  cursor: pointer;
4970
4962
  flex-basis: inherit !important;
4971
4963
  flex-grow: inherit !important;
4964
+ position: relative;
4972
4965
  border: none;
4973
4966
  background: none;
4974
4967
  appearance: none;
@@ -4983,12 +4976,14 @@ ul.wp-block-rss.is-grid li {
4983
4976
  text-transform: inherit;
4984
4977
  text-align: inherit;
4985
4978
  }
4986
- .wp-block-tabs-menu-item:focus-visible {
4987
- outline-offset: 2px;
4988
- }
4989
- .wp-block-tabs-menu-item[aria-selected=true], .wp-block-tabs-menu-item.is-active {
4990
- background-color: #000;
4991
- color: #fff;
4979
+ .wp-block-tabs-menu-item[aria-selected=true]::before, .wp-block-tabs-menu-item.is-active::before {
4980
+ content: "";
4981
+ position: absolute;
4982
+ border-bottom: 2px solid currentColor;
4983
+ pointer-events: none;
4984
+ left: 0;
4985
+ width: 100%;
4986
+ bottom: 0;
4992
4987
  }
4993
4988
 
4994
4989
  .wp-block-term-count {
@@ -7,6 +7,7 @@
7
7
  cursor: pointer;
8
8
  flex-basis: inherit !important;
9
9
  flex-grow: inherit !important;
10
+ position: relative;
10
11
  border: none;
11
12
  background: none;
12
13
  appearance: none;
@@ -21,10 +22,12 @@
21
22
  text-transform: inherit;
22
23
  text-align: inherit;
23
24
  }
24
- .wp-block-tabs-menu-item:focus-visible {
25
- outline-offset: 2px;
26
- }
27
- .wp-block-tabs-menu-item[aria-selected=true], .wp-block-tabs-menu-item.is-active {
28
- background-color: #000;
29
- color: #fff;
25
+ .wp-block-tabs-menu-item[aria-selected=true]::before, .wp-block-tabs-menu-item.is-active::before {
26
+ content: "";
27
+ position: absolute;
28
+ border-bottom: 2px solid currentColor;
29
+ pointer-events: none;
30
+ right: 0;
31
+ width: 100%;
32
+ bottom: 0;
30
33
  }
@@ -7,6 +7,7 @@
7
7
  cursor: pointer;
8
8
  flex-basis: inherit !important;
9
9
  flex-grow: inherit !important;
10
+ position: relative;
10
11
  border: none;
11
12
  background: none;
12
13
  appearance: none;
@@ -21,10 +22,12 @@
21
22
  text-transform: inherit;
22
23
  text-align: inherit;
23
24
  }
24
- .wp-block-tabs-menu-item:focus-visible {
25
- outline-offset: 2px;
26
- }
27
- .wp-block-tabs-menu-item[aria-selected=true], .wp-block-tabs-menu-item.is-active {
28
- background-color: #000;
29
- color: #fff;
25
+ .wp-block-tabs-menu-item[aria-selected=true]::before, .wp-block-tabs-menu-item.is-active::before {
26
+ content: "";
27
+ position: absolute;
28
+ border-bottom: 2px solid currentColor;
29
+ pointer-events: none;
30
+ left: 0;
31
+ width: 100%;
32
+ bottom: 0;
30
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-library",
3
- "version": "9.43.0",
3
+ "version": "9.44.0",
4
4
  "description": "Block library for the WordPress editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -95,42 +95,42 @@
95
95
  ],
96
96
  "dependencies": {
97
97
  "@arraypress/waveform-player": "1.2.1",
98
- "@wordpress/a11y": "^4.43.0",
99
- "@wordpress/api-fetch": "^7.43.0",
100
- "@wordpress/autop": "^4.43.0",
101
- "@wordpress/base-styles": "^6.19.0",
102
- "@wordpress/blob": "^4.43.0",
103
- "@wordpress/block-editor": "^15.16.0",
104
- "@wordpress/blocks": "^15.16.0",
105
- "@wordpress/components": "^32.5.0",
106
- "@wordpress/compose": "^7.43.0",
107
- "@wordpress/core-data": "^7.43.0",
108
- "@wordpress/data": "^10.43.0",
109
- "@wordpress/date": "^5.43.0",
110
- "@wordpress/deprecated": "^4.43.0",
111
- "@wordpress/dom": "^4.43.0",
112
- "@wordpress/element": "^6.43.0",
113
- "@wordpress/escape-html": "^3.43.0",
114
- "@wordpress/hooks": "^4.43.0",
115
- "@wordpress/html-entities": "^4.43.0",
116
- "@wordpress/i18n": "^6.16.0",
117
- "@wordpress/icons": "^12.1.0",
118
- "@wordpress/interactivity": "^6.43.0",
119
- "@wordpress/interactivity-router": "^2.43.0",
120
- "@wordpress/keyboard-shortcuts": "^5.43.0",
121
- "@wordpress/keycodes": "^4.43.0",
122
- "@wordpress/latex-to-mathml": "^1.11.0",
123
- "@wordpress/notices": "^5.43.0",
124
- "@wordpress/patterns": "^2.43.0",
125
- "@wordpress/primitives": "^4.43.0",
126
- "@wordpress/private-apis": "^1.43.0",
127
- "@wordpress/reusable-blocks": "^5.43.0",
128
- "@wordpress/rich-text": "^7.43.0",
129
- "@wordpress/server-side-render": "^6.19.0",
130
- "@wordpress/upload-media": "^0.28.0",
131
- "@wordpress/url": "^4.43.0",
132
- "@wordpress/viewport": "^6.43.0",
133
- "@wordpress/wordcount": "^4.43.0",
98
+ "@wordpress/a11y": "^4.44.0",
99
+ "@wordpress/api-fetch": "^7.44.0",
100
+ "@wordpress/autop": "^4.44.0",
101
+ "@wordpress/base-styles": "^6.20.0",
102
+ "@wordpress/blob": "^4.44.0",
103
+ "@wordpress/block-editor": "^15.17.0",
104
+ "@wordpress/blocks": "^15.17.0",
105
+ "@wordpress/components": "^32.6.0",
106
+ "@wordpress/compose": "^7.44.0",
107
+ "@wordpress/core-data": "^7.44.0",
108
+ "@wordpress/data": "^10.44.0",
109
+ "@wordpress/date": "^5.44.0",
110
+ "@wordpress/deprecated": "^4.44.0",
111
+ "@wordpress/dom": "^4.44.0",
112
+ "@wordpress/element": "^6.44.0",
113
+ "@wordpress/escape-html": "^3.44.0",
114
+ "@wordpress/hooks": "^4.44.0",
115
+ "@wordpress/html-entities": "^4.44.0",
116
+ "@wordpress/i18n": "^6.17.0",
117
+ "@wordpress/icons": "^12.2.0",
118
+ "@wordpress/interactivity": "^6.44.0",
119
+ "@wordpress/interactivity-router": "^2.44.0",
120
+ "@wordpress/keyboard-shortcuts": "^5.44.0",
121
+ "@wordpress/keycodes": "^4.44.0",
122
+ "@wordpress/latex-to-mathml": "^1.12.0",
123
+ "@wordpress/notices": "^5.44.0",
124
+ "@wordpress/patterns": "^2.44.0",
125
+ "@wordpress/primitives": "^4.44.0",
126
+ "@wordpress/private-apis": "^1.44.0",
127
+ "@wordpress/reusable-blocks": "^5.44.0",
128
+ "@wordpress/rich-text": "^7.44.0",
129
+ "@wordpress/server-side-render": "^6.20.0",
130
+ "@wordpress/upload-media": "^0.29.0",
131
+ "@wordpress/url": "^4.44.0",
132
+ "@wordpress/viewport": "^6.44.0",
133
+ "@wordpress/wordcount": "^4.44.0",
134
134
  "change-case": "^4.1.2",
135
135
  "clsx": "^2.1.1",
136
136
  "colord": "^2.7.0",
@@ -151,5 +151,5 @@
151
151
  "publishConfig": {
152
152
  "access": "public"
153
153
  },
154
- "gitHead": "2cea90674d11aa521ec3f71652fb3a6a4c383969"
154
+ "gitHead": "b862d8c84121a47bbeff882f6c87e61681ce2e0d"
155
155
  }
package/src/code/edit.js CHANGED
@@ -29,6 +29,7 @@ export default function CodeEdit( {
29
29
  __unstableOnSplitAtDoubleLineEnd={ () =>
30
30
  insertBlocksAfter( createBlock( getDefaultBlockName() ) )
31
31
  }
32
+ style={ { whiteSpace: 'break-spaces' } }
32
33
  />
33
34
  </pre>
34
35
  );
@@ -8,7 +8,7 @@
8
8
  display: block;
9
9
  font-family: inherit;
10
10
  overflow-wrap: break-word;
11
- white-space: pre-wrap;
11
+ white-space: break-spaces;
12
12
  // Set direction and avoid inheriting alignment from a parent element.
13
13
  /*!rtl:begin:ignore*/
14
14
  direction: ltr;
@@ -92,7 +92,7 @@ export const getMediaColor = memoize( async ( url ) => {
92
92
  crossOrigin: imgCrossOrigin,
93
93
  } );
94
94
  return color.hex;
95
- } catch ( error ) {
95
+ } catch {
96
96
  // If there's an error return the fallback color.
97
97
  return DEFAULT_BACKGROUND_COLOR;
98
98
  }
@@ -7,8 +7,13 @@ import clsx from 'clsx';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useEntityProp, store as coreStore } from '@wordpress/core-data';
10
- import { useEffect, useMemo, useRef } from '@wordpress/element';
11
- import { Placeholder, Spinner } from '@wordpress/components';
10
+ import {
11
+ useEffect,
12
+ useLayoutEffect,
13
+ useMemo,
14
+ useRef,
15
+ } from '@wordpress/element';
16
+ import { Placeholder, SandBox, Spinner } from '@wordpress/components';
12
17
  import { compose, useResizeObserver } from '@wordpress/compose';
13
18
  import {
14
19
  withColors,
@@ -49,7 +54,7 @@ import {
49
54
  DEFAULT_OVERLAY_COLOR,
50
55
  } from './color-utils';
51
56
  import { DEFAULT_MEDIA_SIZE_SLUG } from '../constants';
52
- import { getIframeSrc, getBackgroundVideoSrc } from '../embed-video-utils';
57
+ import { getBackgroundEmbedHtml } from '../embed-video-utils';
53
58
 
54
59
  function getInnerBlocksTemplate( attributes ) {
55
60
  return [
@@ -121,6 +126,14 @@ function CoverEdit( {
121
126
 
122
127
  const { __unstableMarkNextChangeAsNotPersistent } =
123
128
  useDispatch( blockEditorStore );
129
+
130
+ // Ref to access latest values after async operations (e.g. getMediaColor),
131
+ // avoiding stale values that could overwrite concurrent remote changes.
132
+ const propsRef = useRef( { attributes, overlayColor } );
133
+ useLayoutEffect( () => {
134
+ propsRef.current = { attributes, overlayColor };
135
+ } );
136
+
124
137
  const { media } = useSelect(
125
138
  ( select ) => {
126
139
  return {
@@ -155,26 +168,37 @@ function CoverEdit( {
155
168
 
156
169
  const averageBackgroundColor = await getMediaColor( mediaUrl );
157
170
 
158
- let newOverlayColor = overlayColor.color;
159
- if ( ! isUserOverlayColor ) {
171
+ // Read latest values after await to avoid stale closures.
172
+ const { attributes: currentAttrs, overlayColor: currentOverlay } =
173
+ propsRef.current;
174
+
175
+ let newOverlayColor = currentOverlay.color;
176
+ if ( ! currentAttrs.isUserOverlayColor ) {
160
177
  newOverlayColor = averageBackgroundColor;
161
178
  __unstableMarkNextChangeAsNotPersistent();
162
179
  setOverlayColor( newOverlayColor );
163
180
  }
164
181
 
165
182
  const newIsDark = compositeIsDark(
166
- dimRatio,
183
+ currentAttrs.dimRatio,
167
184
  newOverlayColor,
168
185
  averageBackgroundColor
169
186
  );
170
187
  __unstableMarkNextChangeAsNotPersistent();
171
188
  setAttributes( {
172
189
  isDark: newIsDark,
173
- isUserOverlayColor: isUserOverlayColor || false,
190
+ isUserOverlayColor: currentAttrs.isUserOverlayColor || false,
174
191
  } );
175
192
  } )();
176
193
  // Update the block only when the featured image changes.
177
- }, [ mediaUrl ] );
194
+ // The other dependencies are stable references (dispatch actions / setters).
195
+ }, [
196
+ mediaUrl,
197
+ __unstableMarkNextChangeAsNotPersistent,
198
+ setAttributes,
199
+ setOverlayColor,
200
+ useFeaturedImage,
201
+ ] );
178
202
 
179
203
  // instead of destructuring the attributes
180
204
  // we define the url and background type
@@ -201,8 +225,12 @@ function CoverEdit( {
201
225
  isImage ? newMedia?.url : undefined
202
226
  );
203
227
 
204
- let newOverlayColor = overlayColor.color;
205
- if ( ! isUserOverlayColor ) {
228
+ // Read latest values to avoid stale closures.
229
+ const { attributes: currentAttrs, overlayColor: currentOverlay } =
230
+ propsRef.current;
231
+
232
+ let newOverlayColor = currentOverlay.color;
233
+ if ( ! currentAttrs.isUserOverlayColor ) {
206
234
  newOverlayColor = averageBackgroundColor;
207
235
  setOverlayColor( newOverlayColor );
208
236
 
@@ -214,7 +242,9 @@ function CoverEdit( {
214
242
  // to avoid resetting to 50 if it has been explicitly set to 100.
215
243
  // See issue #52835 for context.
216
244
  const newDimRatio =
217
- originalUrl === undefined && dimRatio === 100 ? 50 : dimRatio;
245
+ currentAttrs.url === undefined && currentAttrs.dimRatio === 100
246
+ ? 50
247
+ : currentAttrs.dimRatio;
218
248
 
219
249
  const newIsDark = compositeIsDark(
220
250
  newDimRatio,
@@ -256,7 +286,7 @@ function CoverEdit( {
256
286
  useFeaturedImage: undefined,
257
287
  dimRatio: newDimRatio,
258
288
  isDark: newIsDark,
259
- isUserOverlayColor: isUserOverlayColor || false,
289
+ isUserOverlayColor: currentAttrs.isUserOverlayColor || false,
260
290
  } );
261
291
  };
262
292
 
@@ -290,8 +320,12 @@ function CoverEdit( {
290
320
 
291
321
  const onSetOverlayColor = async ( newOverlayColor ) => {
292
322
  const averageBackgroundColor = await getMediaColor( url );
323
+
324
+ // Read latest dimRatio after await to avoid stale closure.
325
+ const { attributes: currentAttrs } = propsRef.current;
326
+
293
327
  const newIsDark = compositeIsDark(
294
- dimRatio,
328
+ currentAttrs.dimRatio,
295
329
  newOverlayColor,
296
330
  averageBackgroundColor
297
331
  );
@@ -309,9 +343,13 @@ function CoverEdit( {
309
343
 
310
344
  const onUpdateDimRatio = async ( newDimRatio ) => {
311
345
  const averageBackgroundColor = await getMediaColor( url );
346
+
347
+ // Read latest overlayColor after await to avoid stale closure.
348
+ const { overlayColor: currentOverlay } = propsRef.current;
349
+
312
350
  const newIsDark = compositeIsDark(
313
351
  newDimRatio,
314
- overlayColor.color,
352
+ currentOverlay.color,
315
353
  averageBackgroundColor
316
354
  );
317
355
 
@@ -365,23 +403,15 @@ function CoverEdit( {
365
403
  [ url, backgroundType ]
366
404
  );
367
405
 
368
- // Compute embedSrc on-the-fly from embed preview for editor display
369
- const embedSrc = useMemo( () => {
406
+ // Compute embed HTML for editor display via SandBox
407
+ const embedHtml = useMemo( () => {
370
408
  if (
371
409
  backgroundType !== EMBED_VIDEO_BACKGROUND_TYPE ||
372
410
  ! embedPreview?.html
373
411
  ) {
374
412
  return null;
375
413
  }
376
-
377
- // Extract iframe src from embed HTML
378
- const iframeSrc = getIframeSrc( embedPreview.html );
379
- if ( ! iframeSrc ) {
380
- return null;
381
- }
382
-
383
- // Modify the src to add background video parameters (provider auto-detected)
384
- return getBackgroundVideoSrc( iframeSrc );
414
+ return getBackgroundEmbedHtml( embedPreview.html );
385
415
  }, [ embedPreview, backgroundType ] );
386
416
 
387
417
  const isUploadingMedia = isTemporaryMedia( id, url );
@@ -477,11 +507,15 @@ function CoverEdit( {
477
507
  ? await getMediaColor( mediaUrl )
478
508
  : DEFAULT_BACKGROUND_COLOR;
479
509
 
480
- const newOverlayColor = ! isUserOverlayColor
510
+ // Read latest values after await to avoid stale closures.
511
+ const { attributes: currentAttrs, overlayColor: currentOverlay } =
512
+ propsRef.current;
513
+
514
+ const newOverlayColor = ! currentAttrs.isUserOverlayColor
481
515
  ? averageBackgroundColor
482
- : overlayColor.color;
516
+ : currentOverlay.color;
483
517
 
484
- if ( ! isUserOverlayColor ) {
518
+ if ( ! currentAttrs.isUserOverlayColor ) {
485
519
  if ( newUseFeaturedImage ) {
486
520
  setOverlayColor( newOverlayColor );
487
521
  } else {
@@ -492,7 +526,8 @@ function CoverEdit( {
492
526
  __unstableMarkNextChangeAsNotPersistent();
493
527
  }
494
528
 
495
- const newDimRatio = dimRatio === 100 ? 50 : dimRatio;
529
+ const newDimRatio =
530
+ currentAttrs.dimRatio === 100 ? 50 : currentAttrs.dimRatio;
496
531
  const newIsDark = compositeIsDark(
497
532
  newDimRatio,
498
533
  newOverlayColor,
@@ -668,21 +703,23 @@ function CoverEdit( {
668
703
  style={ mediaStyle }
669
704
  />
670
705
  ) }
671
- { isEmbedVideoBackground && embedSrc && (
706
+ { isEmbedVideoBackground && embedHtml && (
672
707
  <div
673
708
  ref={ mediaElement }
674
709
  className="wp-block-cover__video-background wp-block-cover__embed-background"
675
710
  style={ mediaStyle }
676
711
  >
677
- <iframe
678
- src={ embedSrc }
712
+ <SandBox
713
+ allowSameOrigin
714
+ html={ embedHtml }
679
715
  title="Background video"
680
- frameBorder="0"
681
- allow="autoplay; fullscreen"
716
+ styles={ [
717
+ 'iframe{position:fixed;top:0;left:0;width:100%;height:100%;}',
718
+ ] }
682
719
  />
683
720
  </div>
684
721
  ) }
685
- { isEmbedVideoBackground && ! embedSrc && isFetchingEmbed && (
722
+ { isEmbedVideoBackground && ! embedHtml && isFetchingEmbed && (
686
723
  <Spinner />
687
724
  ) }
688
725