@wordpress/block-library 9.44.1-next.v.202604201441.0 → 9.45.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 (315) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/accordion/edit.cjs +0 -2
  3. package/build/accordion/edit.cjs.map +2 -2
  4. package/build/accordion-item/block.json +1 -0
  5. package/build/categories/edit.cjs +5 -1
  6. package/build/categories/edit.cjs.map +2 -2
  7. package/build/embed/edit.cjs +38 -34
  8. package/build/embed/edit.cjs.map +3 -3
  9. package/build/embed/transforms.cjs +3 -1
  10. package/build/embed/transforms.cjs.map +2 -2
  11. package/build/embed/util.cjs +13 -2
  12. package/build/embed/util.cjs.map +2 -2
  13. package/build/form/block.json +1 -1
  14. package/build/form-input/block.json +1 -1
  15. package/build/form-submission-notification/block.json +1 -1
  16. package/build/form-submit-button/block.json +1 -1
  17. package/build/image/edit.cjs +1 -1
  18. package/build/image/edit.cjs.map +2 -2
  19. package/build/image/image.cjs +29 -10
  20. package/build/image/image.cjs.map +3 -3
  21. package/build/index.cjs +4 -4
  22. package/build/index.cjs.map +2 -2
  23. package/build/math/edit.cjs +2 -2
  24. package/build/math/edit.cjs.map +2 -2
  25. package/build/navigation/edit/accessible-description.cjs +2 -2
  26. package/build/navigation/edit/accessible-description.cjs.map +2 -2
  27. package/build/navigation/edit/overlay-template-part-selector.cjs.map +2 -2
  28. package/build/navigation-link/edit.cjs +2 -1
  29. package/build/navigation-link/edit.cjs.map +2 -2
  30. package/build/navigation-link/link-ui/dialog-wrapper.cjs +2 -1
  31. package/build/navigation-link/link-ui/dialog-wrapper.cjs.map +2 -2
  32. package/build/navigation-link/link-ui/index.cjs +2 -1
  33. package/build/navigation-link/link-ui/index.cjs.map +2 -2
  34. package/build/post-author/edit.cjs.map +3 -3
  35. package/build/post-comments-form/edit.cjs +2 -2
  36. package/build/post-comments-form/edit.cjs.map +2 -2
  37. package/build/query/edit/inspector-controls/author-control.cjs +1 -1
  38. package/build/query/edit/inspector-controls/author-control.cjs.map +2 -2
  39. package/build/query/edit/inspector-controls/format-controls.cjs +1 -1
  40. package/build/query/edit/inspector-controls/format-controls.cjs.map +2 -2
  41. package/build/query/edit/inspector-controls/parent-control.cjs +1 -1
  42. package/build/query/edit/inspector-controls/parent-control.cjs.map +2 -2
  43. package/build/query/edit/inspector-controls/taxonomy-controls.cjs +1 -1
  44. package/build/query/edit/inspector-controls/taxonomy-controls.cjs.map +2 -2
  45. package/build/site-logo/edit.cjs +32 -18
  46. package/build/site-logo/edit.cjs.map +2 -2
  47. package/build/tab/block.json +23 -23
  48. package/build/tab/controls.cjs +5 -48
  49. package/build/tab/controls.cjs.map +3 -3
  50. package/build/tab/edit.cjs +77 -75
  51. package/build/tab/edit.cjs.map +3 -3
  52. package/build/tab/save.cjs +3 -3
  53. package/build/tab/save.cjs.map +2 -2
  54. package/{src/tabs-menu → build/tab-list}/block.json +3 -3
  55. package/build/{tabs-menu → tab-list}/edit.cjs +4 -4
  56. package/build/tab-list/edit.cjs.map +7 -0
  57. package/build/{tabs-menu → tab-list}/index.cjs +5 -5
  58. package/build/tab-list/index.cjs.map +7 -0
  59. package/build/{tabs-menu → tab-list}/save.cjs +1 -1
  60. package/build/{tabs-menu → tab-list}/save.cjs.map +1 -1
  61. package/build/{tab → tab-panel}/add-tab-toolbar-control.cjs +16 -16
  62. package/build/tab-panel/add-tab-toolbar-control.cjs.map +7 -0
  63. package/build/tab-panel/block.json +27 -37
  64. package/build/tab-panel/controls.cjs +89 -0
  65. package/build/tab-panel/controls.cjs.map +7 -0
  66. package/build/tab-panel/edit.cjs +90 -17
  67. package/build/tab-panel/edit.cjs.map +3 -3
  68. package/build/tab-panel/index.cjs +1 -1
  69. package/build/tab-panel/index.cjs.map +1 -1
  70. package/build/{tab → tab-panel}/init.cjs +1 -1
  71. package/build/{tab → tab-panel}/init.cjs.map +1 -1
  72. package/build/{tab → tab-panel}/remove-tab-toolbar-control.cjs +16 -16
  73. package/build/tab-panel/remove-tab-toolbar-control.cjs.map +7 -0
  74. package/build/tab-panel/save.cjs +4 -2
  75. package/build/tab-panel/save.cjs.map +2 -2
  76. package/build/tab-panels/block.json +66 -0
  77. package/build/{tabs-menu-item/controls.cjs → tab-panels/edit.cjs} +25 -11
  78. package/build/tab-panels/edit.cjs.map +7 -0
  79. package/build/{tabs-menu-item → tab-panels}/index.cjs +5 -5
  80. package/build/{tabs-menu → tab-panels}/index.cjs.map +2 -2
  81. package/build/{tabs-menu-item → tab-panels}/save.cjs +4 -6
  82. package/build/tab-panels/save.cjs.map +7 -0
  83. package/build/tabs/block.json +1 -1
  84. package/build/tabs/controls.cjs +2 -2
  85. package/build/tabs/controls.cjs.map +1 -1
  86. package/build/tabs/edit.cjs +24 -19
  87. package/build/tabs/edit.cjs.map +3 -3
  88. package/build/tabs/index.cjs +5 -5
  89. package/build/tabs/index.cjs.map +1 -1
  90. package/build/tabs/{use-tab-menu-sync.cjs → use-tab-list-sync.cjs} +78 -80
  91. package/build/tabs/use-tab-list-sync.cjs.map +7 -0
  92. package/build/terms-query/edit/inspector-controls/include-control.cjs +1 -1
  93. package/build/terms-query/edit/inspector-controls/include-control.cjs.map +2 -2
  94. package/build/video/tracks-editor.cjs +2 -2
  95. package/build/video/tracks-editor.cjs.map +2 -2
  96. package/build-module/accordion/edit.mjs +0 -2
  97. package/build-module/accordion/edit.mjs.map +2 -2
  98. package/build-module/accordion-item/block.json +1 -0
  99. package/build-module/categories/edit.mjs +5 -2
  100. package/build-module/categories/edit.mjs.map +2 -2
  101. package/build-module/embed/edit.mjs +45 -36
  102. package/build-module/embed/edit.mjs.map +2 -2
  103. package/build-module/embed/transforms.mjs +8 -2
  104. package/build-module/embed/transforms.mjs.map +2 -2
  105. package/build-module/embed/util.mjs +11 -1
  106. package/build-module/embed/util.mjs.map +2 -2
  107. package/build-module/form/block.json +1 -1
  108. package/build-module/form-input/block.json +1 -1
  109. package/build-module/form-submission-notification/block.json +1 -1
  110. package/build-module/form-submit-button/block.json +1 -1
  111. package/build-module/image/edit.mjs +1 -1
  112. package/build-module/image/edit.mjs.map +2 -2
  113. package/build-module/image/image.mjs +29 -10
  114. package/build-module/image/image.mjs.map +3 -3
  115. package/build-module/index.mjs +4 -4
  116. package/build-module/index.mjs.map +2 -2
  117. package/build-module/math/edit.mjs +2 -2
  118. package/build-module/math/edit.mjs.map +2 -2
  119. package/build-module/navigation/edit/accessible-description.mjs +1 -1
  120. package/build-module/navigation/edit/accessible-description.mjs.map +1 -1
  121. package/build-module/navigation/edit/overlay-template-part-selector.mjs +2 -2
  122. package/build-module/navigation/edit/overlay-template-part-selector.mjs.map +1 -1
  123. package/build-module/navigation-link/edit.mjs +2 -5
  124. package/build-module/navigation-link/edit.mjs.map +2 -2
  125. package/build-module/navigation-link/link-ui/dialog-wrapper.mjs +2 -1
  126. package/build-module/navigation-link/link-ui/dialog-wrapper.mjs.map +2 -2
  127. package/build-module/navigation-link/link-ui/index.mjs +1 -1
  128. package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
  129. package/build-module/post-author/edit.mjs +2 -2
  130. package/build-module/post-author/edit.mjs.map +2 -2
  131. package/build-module/post-comments-form/edit.mjs +1 -1
  132. package/build-module/post-comments-form/edit.mjs.map +2 -2
  133. package/build-module/query/edit/inspector-controls/author-control.mjs +1 -1
  134. package/build-module/query/edit/inspector-controls/author-control.mjs.map +2 -2
  135. package/build-module/query/edit/inspector-controls/format-controls.mjs +1 -1
  136. package/build-module/query/edit/inspector-controls/format-controls.mjs.map +2 -2
  137. package/build-module/query/edit/inspector-controls/parent-control.mjs +1 -1
  138. package/build-module/query/edit/inspector-controls/parent-control.mjs.map +2 -2
  139. package/build-module/query/edit/inspector-controls/taxonomy-controls.mjs +1 -1
  140. package/build-module/query/edit/inspector-controls/taxonomy-controls.mjs.map +2 -2
  141. package/build-module/site-logo/edit.mjs +32 -18
  142. package/build-module/site-logo/edit.mjs.map +2 -2
  143. package/build-module/tab/block.json +23 -23
  144. package/build-module/tab/controls.mjs +7 -57
  145. package/build-module/tab/controls.mjs.map +2 -2
  146. package/build-module/tab/edit.mjs +81 -79
  147. package/build-module/tab/edit.mjs.map +3 -3
  148. package/build-module/tab/save.mjs +4 -4
  149. package/build-module/tab/save.mjs.map +2 -2
  150. package/build-module/{tabs-menu → tab-list}/block.json +3 -3
  151. package/build-module/{tabs-menu → tab-list}/edit.mjs +4 -4
  152. package/build-module/tab-list/edit.mjs.map +7 -0
  153. package/build-module/{tabs-menu → tab-list}/index.mjs +2 -2
  154. package/build-module/tab-list/index.mjs.map +7 -0
  155. package/build-module/{tabs-menu → tab-list}/save.mjs +1 -1
  156. package/build-module/{tabs-menu → tab-list}/save.mjs.map +1 -1
  157. package/build-module/{tab → tab-panel}/add-tab-toolbar-control.mjs +16 -16
  158. package/build-module/tab-panel/add-tab-toolbar-control.mjs.map +7 -0
  159. package/build-module/tab-panel/block.json +27 -37
  160. package/build-module/tab-panel/controls.mjs +65 -0
  161. package/build-module/tab-panel/controls.mjs.map +7 -0
  162. package/build-module/tab-panel/edit.mjs +92 -19
  163. package/build-module/tab-panel/edit.mjs.map +2 -2
  164. package/build-module/tab-panel/index.mjs +1 -1
  165. package/build-module/tab-panel/index.mjs.map +1 -1
  166. package/build-module/{tab → tab-panel}/init.mjs +1 -1
  167. package/build-module/{tab → tab-panel}/init.mjs.map +1 -1
  168. package/build-module/{tab → tab-panel}/remove-tab-toolbar-control.mjs +16 -16
  169. package/build-module/tab-panel/remove-tab-toolbar-control.mjs.map +7 -0
  170. package/build-module/tab-panel/save.mjs +4 -2
  171. package/build-module/tab-panel/save.mjs.map +2 -2
  172. package/build-module/tab-panels/block.json +66 -0
  173. package/build-module/tab-panels/edit.mjs +33 -0
  174. package/build-module/tab-panels/edit.mjs.map +7 -0
  175. package/build-module/{tabs-menu-item → tab-panels}/index.mjs +2 -2
  176. package/build-module/{tabs-menu → tab-panels}/index.mjs.map +2 -2
  177. package/build-module/tab-panels/save.mjs +12 -0
  178. package/build-module/tab-panels/save.mjs.map +7 -0
  179. package/build-module/tabs/block.json +1 -1
  180. package/build-module/tabs/controls.mjs +2 -2
  181. package/build-module/tabs/controls.mjs.map +1 -1
  182. package/build-module/tabs/edit.mjs +24 -19
  183. package/build-module/tabs/edit.mjs.map +2 -2
  184. package/build-module/tabs/index.mjs +5 -5
  185. package/build-module/tabs/index.mjs.map +1 -1
  186. package/build-module/tabs/use-tab-list-sync.mjs +169 -0
  187. package/build-module/tabs/use-tab-list-sync.mjs.map +7 -0
  188. package/build-module/terms-query/edit/inspector-controls/include-control.mjs +1 -1
  189. package/build-module/terms-query/edit/inspector-controls/include-control.mjs.map +2 -2
  190. package/build-module/video/tracks-editor.mjs +2 -2
  191. package/build-module/video/tracks-editor.mjs.map +2 -2
  192. package/build-style/classic-rtl.css +14 -0
  193. package/build-style/classic.css +14 -0
  194. package/build-style/editor-rtl.css +9 -5
  195. package/build-style/editor.css +9 -5
  196. package/build-style/style-rtl.css +40 -40
  197. package/build-style/style.css +40 -40
  198. package/build-style/tab/editor-rtl.css +11 -0
  199. package/build-style/tab/editor.css +11 -0
  200. package/build-style/tab/style-rtl.css +29 -16
  201. package/build-style/tab/style.css +29 -16
  202. package/build-style/tab-list/editor-rtl.css +6 -0
  203. package/build-style/tab-list/editor.css +6 -0
  204. package/build-style/tab-panel/style-rtl.css +17 -1
  205. package/build-style/tab-panel/style.css +17 -1
  206. package/build-style/tab-panels/style-rtl.css +4 -0
  207. package/build-style/tab-panels/style.css +4 -0
  208. package/build-style/video/editor-rtl.css +4 -0
  209. package/build-style/video/editor.css +4 -0
  210. package/package.json +39 -38
  211. package/src/accordion/edit.js +0 -2
  212. package/src/accordion-item/block.json +1 -0
  213. package/src/categories/edit.js +3 -2
  214. package/src/classic.scss +25 -0
  215. package/src/editor.scss +2 -2
  216. package/src/embed/edit.js +61 -52
  217. package/src/embed/edit.native.js +71 -57
  218. package/src/embed/transforms.js +8 -2
  219. package/src/embed/util.js +17 -0
  220. package/src/form/block.json +1 -1
  221. package/src/form-input/block.json +1 -1
  222. package/src/form-submission-notification/block.json +1 -1
  223. package/src/form-submit-button/block.json +1 -1
  224. package/src/image/edit.js +5 -1
  225. package/src/image/edit.native.js +3 -3
  226. package/src/image/image.js +30 -5
  227. package/src/index.js +4 -4
  228. package/src/math/edit.js +3 -3
  229. package/src/navigation/edit/accessible-description.js +1 -1
  230. package/src/navigation/edit/overlay-template-part-selector.js +3 -3
  231. package/src/navigation-link/edit.js +2 -5
  232. package/src/navigation-link/link-ui/dialog-wrapper.js +2 -1
  233. package/src/navigation-link/link-ui/index.js +1 -1
  234. package/src/post-author/edit.js +3 -5
  235. package/src/post-comments-form/edit.js +1 -1
  236. package/src/query/edit/inspector-controls/author-control.js +1 -1
  237. package/src/query/edit/inspector-controls/format-controls.js +1 -1
  238. package/src/query/edit/inspector-controls/parent-control.js +1 -1
  239. package/src/query/edit/inspector-controls/taxonomy-controls.js +1 -1
  240. package/src/site-logo/edit.js +38 -18
  241. package/src/style.scss +1 -1
  242. package/src/tab/block.json +23 -23
  243. package/src/tab/controls.js +6 -52
  244. package/src/tab/edit.js +99 -103
  245. package/src/{tabs-menu-item → tab}/editor.scss +3 -3
  246. package/src/tab/index.php +32 -51
  247. package/src/tab/save.js +4 -4
  248. package/src/tab/style.scss +34 -17
  249. package/{build/tabs-menu → src/tab-list}/block.json +3 -3
  250. package/src/{tabs-menu → tab-list}/edit.js +3 -3
  251. package/src/{tabs-menu → tab-list}/editor.scss +2 -2
  252. package/src/{tabs-menu → tab-list}/index.js +1 -1
  253. package/src/tab-list/index.php +80 -0
  254. package/src/{tab → tab-panel}/add-tab-toolbar-control.js +19 -19
  255. package/src/tab-panel/block.json +27 -37
  256. package/src/tab-panel/controls.js +65 -0
  257. package/src/tab-panel/edit.js +123 -20
  258. package/src/tab-panel/index.js +1 -1
  259. package/src/tab-panel/index.php +88 -0
  260. package/src/{tab → tab-panel}/remove-tab-toolbar-control.js +20 -19
  261. package/src/tab-panel/save.js +4 -2
  262. package/src/tab-panel/style.scss +20 -1
  263. package/src/tab-panels/block.json +66 -0
  264. package/src/tab-panels/edit.js +42 -0
  265. package/src/{tabs-menu-item → tab-panels}/index.js +1 -1
  266. package/src/tab-panels/save.js +11 -0
  267. package/src/tab-panels/style.scss +4 -0
  268. package/src/tabs/block.json +1 -1
  269. package/src/tabs/controls.js +2 -2
  270. package/src/tabs/edit.js +25 -20
  271. package/src/tabs/index.js +5 -5
  272. package/src/tabs/index.php +5 -5
  273. package/src/tabs/use-tab-list-sync.js +237 -0
  274. package/src/terms-query/edit/inspector-controls/include-control.js +1 -1
  275. package/src/video/editor.scss +5 -0
  276. package/src/video/tracks-editor.js +2 -2
  277. package/build/tab/add-tab-toolbar-control.cjs.map +0 -7
  278. package/build/tab/remove-tab-toolbar-control.cjs.map +0 -7
  279. package/build/tabs/use-tab-menu-sync.cjs.map +0 -7
  280. package/build/tabs-menu/edit.cjs.map +0 -7
  281. package/build/tabs-menu-item/block.json +0 -56
  282. package/build/tabs-menu-item/controls.cjs.map +0 -7
  283. package/build/tabs-menu-item/edit.cjs +0 -135
  284. package/build/tabs-menu-item/edit.cjs.map +0 -7
  285. package/build/tabs-menu-item/index.cjs.map +0 -7
  286. package/build/tabs-menu-item/save.cjs.map +0 -7
  287. package/build-module/tab/add-tab-toolbar-control.mjs.map +0 -7
  288. package/build-module/tab/remove-tab-toolbar-control.mjs.map +0 -7
  289. package/build-module/tabs/use-tab-menu-sync.mjs +0 -171
  290. package/build-module/tabs/use-tab-menu-sync.mjs.map +0 -7
  291. package/build-module/tabs-menu/edit.mjs.map +0 -7
  292. package/build-module/tabs-menu-item/block.json +0 -56
  293. package/build-module/tabs-menu-item/controls.mjs +0 -15
  294. package/build-module/tabs-menu-item/controls.mjs.map +0 -7
  295. package/build-module/tabs-menu-item/edit.mjs +0 -108
  296. package/build-module/tabs-menu-item/edit.mjs.map +0 -7
  297. package/build-module/tabs-menu-item/index.mjs.map +0 -7
  298. package/build-module/tabs-menu-item/save.mjs +0 -14
  299. package/build-module/tabs-menu-item/save.mjs.map +0 -7
  300. package/build-style/tabs-menu/editor-rtl.css +0 -6
  301. package/build-style/tabs-menu/editor.css +0 -6
  302. package/build-style/tabs-menu-item/editor-rtl.css +0 -11
  303. package/build-style/tabs-menu-item/editor.css +0 -11
  304. package/build-style/tabs-menu-item/style-rtl.css +0 -33
  305. package/build-style/tabs-menu-item/style.css +0 -33
  306. package/src/tabs/use-tab-menu-sync.js +0 -239
  307. package/src/tabs-menu/index.php +0 -80
  308. package/src/tabs-menu-item/block.json +0 -56
  309. package/src/tabs-menu-item/controls.js +0 -19
  310. package/src/tabs-menu-item/edit.js +0 -141
  311. package/src/tabs-menu-item/index.php +0 -70
  312. package/src/tabs-menu-item/save.js +0 -13
  313. package/src/tabs-menu-item/style.scss +0 -40
  314. /package/src/{tabs-menu → tab-list}/save.js +0 -0
  315. /package/src/{tab → tab-panel}/init.js +0 -0
package/src/tab/index.php CHANGED
@@ -1,6 +1,6 @@
1
1
  <?php
2
2
  /**
3
- * Tabs Block
3
+ * Tab Block
4
4
  *
5
5
  * @package WordPress
6
6
  */
@@ -8,81 +8,62 @@
8
8
  /**
9
9
  * Render callback for core/tab.
10
10
  *
11
+ * Injects the tab label and IAPI directives into the saved button HTML.
12
+ * Per-item context (index, id, label) is provided by the parent tab-list
13
+ * render callback before this is called.
14
+ *
11
15
  * @since 7.0.0
12
16
  *
13
17
  * @param array $attributes Block attributes.
14
- * @param array $attributes Block attributes.
15
- * @param string $content Block content.
16
- * @param \WP_Block $block Block instance.
18
+ * @param string $content Block content (styled button from save.js).
19
+ * @param \WP_Block $block WP_Block instance.
17
20
  *
18
21
  * @return string Updated HTML.
19
22
  */
20
- function block_core_tab_render( array $attributes, string $content, \WP_Block $block ): string {
21
- $tabs_id = $block->context['core/tabs-id'] ?? '';
22
-
23
- static $tab_counters = array();
23
+ function block_core_tab_render_callback( array $attributes, string $content, \WP_Block $block ): string {
24
+ $tab_index = $block->context['core/tab-index'] ?? 0;
25
+ $tab_id = $block->context['core/tab-id'] ?? '';
26
+ $tab_label = $block->context['core/tab-label'] ?? '';
24
27
 
25
- if ( ! isset( $tab_counters[ $tabs_id ] ) ) {
26
- $tab_counters[ $tabs_id ] = 0;
28
+ if ( empty( $tab_id ) ) {
29
+ $tab_id = 'tab-' . $tab_index;
27
30
  }
28
31
 
29
- $tab_index = $tab_counters[ $tabs_id ];
30
- ++$tab_counters[ $tabs_id ];
31
-
32
+ // Add Interactivity API directives and tab-specific attributes to the button.
32
33
  $tag_processor = new WP_HTML_Tag_Processor( $content );
33
- $tag_processor->next_tag( array( 'class_name' => 'wp-block-tab' ) );
34
34
 
35
- // Use the user's custom anchor if present, otherwise fall back to
36
- // the generated position-based ID.
37
- $tab_id = (string) $tag_processor->get_attribute( 'id' );
38
- if ( empty( $tab_id ) ) {
39
- $tab_id = ! empty( $tabs_id )
40
- ? $tabs_id . '-tab-' . $tab_index
41
- : 'tab-' . $tab_index;
42
- $tag_processor->set_attribute( 'id', $tab_id );
35
+ if ( $tag_processor->next_tag() ) {
36
+ $tag_processor->set_attribute( 'id', 'tab__' . $tab_id );
37
+ $tag_processor->set_attribute( 'aria-controls', $tab_id );
38
+ $tag_processor->set_attribute( 'data-wp-on--click', 'actions.handleTabClick' );
39
+ $tag_processor->set_attribute( 'data-wp-on--keydown', 'actions.handleTabKeyDown' );
40
+ $tag_processor->set_attribute( 'data-wp-bind--aria-selected', 'state.isActiveTab' );
41
+ $tag_processor->set_attribute( 'data-wp-bind--tabindex', 'state.tabIndexAttribute' );
42
+ $tag_processor->set_attribute(
43
+ 'data-wp-context',
44
+ wp_json_encode( array( 'tabIndex' => $tab_index ) )
45
+ );
43
46
  }
44
47
 
45
- /**
46
- * Add interactivity to the tab element.
47
- */
48
- $tag_processor->set_attribute(
49
- 'data-wp-interactive',
50
- 'core/tabs/private'
48
+ // Inject the tab label into the button.
49
+ return preg_replace(
50
+ '/(<button\b[^>]*>).*?(<\/button>)/s',
51
+ '$1<span>' . wp_kses_post( $tab_label ) . '</span>$2',
52
+ $tag_processor->get_updated_html(),
53
+ 1
51
54
  );
52
- $tag_processor->set_attribute(
53
- 'data-wp-context',
54
- wp_json_encode(
55
- array(
56
- 'tab' => array(
57
- 'id' => $tab_id,
58
- ),
59
- )
60
- )
61
- );
62
-
63
- /**
64
- * Process accessibility and interactivity attributes.
65
- */
66
- $tag_processor->set_attribute( 'role', 'tabpanel' );
67
- $tag_processor->set_attribute( 'aria-labelledby', 'tab__' . $tab_id );
68
- $tag_processor->set_attribute( 'data-wp-bind--hidden', '!state.isActiveTab' );
69
- $tag_processor->set_attribute( 'tabindex', 0 );
70
-
71
- return (string) $tag_processor->get_updated_html();
72
55
  }
73
56
 
74
57
  /**
75
58
  * Registers the `core/tab` block on the server.
76
59
  *
77
- * @hook init
78
- *
79
60
  * @since 7.0.0
80
61
  */
81
62
  function register_block_core_tab() {
82
63
  register_block_type_from_metadata(
83
64
  __DIR__ . '/tab',
84
65
  array(
85
- 'render_callback' => 'block_core_tab_render',
66
+ 'render_callback' => 'block_core_tab_render_callback',
86
67
  )
87
68
  );
88
69
  }
package/src/tab/save.js CHANGED
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
4
+ import { useBlockProps } from '@wordpress/block-editor';
5
5
 
6
6
  export default function save() {
7
7
  const blockProps = useBlockProps.save( {
8
- role: 'tabpanel',
8
+ type: 'button',
9
+ role: 'tab',
9
10
  } );
10
- const innerBlocksProps = useInnerBlocksProps.save( blockProps );
11
11
 
12
- return <section { ...innerBlocksProps } />;
12
+ return <button { ...blockProps } />;
13
13
  }
@@ -1,23 +1,40 @@
1
1
  .wp-block-tab {
2
- max-width: 100%;
3
- flex-basis: 100%;
4
- flex-grow: 1;
5
2
  box-sizing: border-box;
3
+ color: inherit;
4
+ display: block;
5
+ width: max-content;
6
+ text-decoration: none;
7
+ cursor: pointer;
8
+ flex-basis: inherit !important;
9
+ flex-grow: inherit !important;
10
+ position: relative;
6
11
 
7
- & > *:first-child {
8
- margin-top: 0;
9
- }
10
- & > *:last-child {
11
- margin-bottom: 0;
12
- }
12
+ // Button reset
13
+ border: none;
14
+ background: none;
15
+ appearance: none;
16
+ -webkit-appearance: none;
13
17
 
14
- &[hidden],
15
- &:empty {
16
- display: none !important;
17
- }
18
- }
18
+ margin: 0;
19
+ padding: var(--wp--preset--spacing--20, 0.5em) var(--wp--preset--spacing--30, 1em);
20
+
21
+ // Inherit typography from parent
22
+ font-size: inherit;
23
+ font-family: inherit;
24
+ font-weight: inherit;
25
+ line-height: inherit;
26
+ letter-spacing: inherit;
27
+ text-transform: inherit;
28
+ text-align: inherit;
19
29
 
20
- .wp-block-tab.wp-block.has-background,
21
- .wp-block-tab:not(.wp-block).has-background {
22
- padding: var(--wp--preset--spacing--30);
30
+ &[aria-selected="true"]::before,
31
+ &.is-active::before {
32
+ content: "";
33
+ position: absolute;
34
+ border-bottom: 2px solid currentColor;
35
+ pointer-events: none;
36
+ left: 0;
37
+ width: 100%;
38
+ bottom: 0;
39
+ }
23
40
  }
@@ -2,13 +2,13 @@
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
3
  "__experimental": true,
4
4
  "apiVersion": 3,
5
- "name": "core/tabs-menu",
6
- "title": "Tabs Menu",
5
+ "name": "core/tab-list",
6
+ "title": "Tab List",
7
7
  "description": "Display the tab buttons for a tabbed interface.",
8
8
  "category": "design",
9
9
  "textdomain": "default",
10
10
  "parent": [ "core/tabs" ],
11
- "allowedBlocks": [ "core/tabs-menu-item" ],
11
+ "allowedBlocks": [ "core/tab" ],
12
12
  "usesContext": [ "core/tabs-list" ],
13
13
  "attributes": {},
14
14
  "supports": {
@@ -11,8 +11,8 @@ import { useSelect } from '@wordpress/data';
11
11
  /**
12
12
  * Internal dependencies
13
13
  */
14
- import AddTabToolbarControl from '../tab/add-tab-toolbar-control';
15
- import RemoveTabToolbarControl from '../tab/remove-tab-toolbar-control';
14
+ import AddTabToolbarControl from '../tab-panel/add-tab-toolbar-control';
15
+ import RemoveTabToolbarControl from '../tab-panel/remove-tab-toolbar-control';
16
16
 
17
17
  function Edit( { clientId } ) {
18
18
  const tabsClientId = useSelect(
@@ -24,7 +24,7 @@ function Edit( { clientId } ) {
24
24
  const blockProps = useBlockProps();
25
25
 
26
26
  const innerBlocksProps = useInnerBlocksProps( blockProps, {
27
- allowedBlocks: [ 'core/tabs-menu-item' ],
27
+ allowedBlocks: [ 'core/tab' ],
28
28
  orientation: 'horizontal',
29
29
  templateLock: false,
30
30
  renderAppender: false,
@@ -1,10 +1,10 @@
1
- .wp-block-tabs-menu {
1
+ .wp-block-tab-list {
2
2
  // Allow the inner block list to be displayed in the flex layout, so the tab buttons appear as direct flex children in the editor.
3
3
  > .block-editor-block-list__layout {
4
4
  display: contents;
5
5
  }
6
6
 
7
- .block-editor-block-list__block:has(> .wp-block-tabs-menu-item) {
7
+ .block-editor-block-list__block:has(> .wp-block-tab) {
8
8
  display: contents;
9
9
  }
10
10
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { tabsMenu as icon } from '@wordpress/icons';
4
+ import { tabList as icon } from '@wordpress/icons';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -0,0 +1,80 @@
1
+ <?php
2
+ /**
3
+ * Tab List Block
4
+ *
5
+ * @package WordPress
6
+ */
7
+
8
+ /**
9
+ * Render callback for core/tab-list.
10
+ *
11
+ * Re-renders each tab inner block with per-item context (index, id,
12
+ * label) injected from the tabs-list, so the tab render callback
13
+ * can add the correct IAPI directives for each button.
14
+ *
15
+ * @since 7.0.0
16
+ *
17
+ * @param array $attributes Block attributes.
18
+ * @param string $content Block content (rendered inner blocks from save.js).
19
+ * @param \WP_Block $block WP_Block instance.
20
+ *
21
+ * @return string Updated HTML.
22
+ */
23
+ function block_core_tab_list_render_callback( array $attributes, string $content, \WP_Block $block ): string {
24
+ $tabs_list = $block->context['core/tabs-list'] ?? array();
25
+
26
+ if ( empty( $tabs_list ) ) {
27
+ return $content;
28
+ }
29
+
30
+ // Re-render each tab with per-item context (index, id, label).
31
+ // Match by position so items align with their corresponding tabs.
32
+ $buttons_html = '';
33
+ $tab_position = 0;
34
+
35
+ foreach ( $block->parsed_block['innerBlocks'] ?? array() as $parsed_tab ) {
36
+ if ( 'core/tab' !== ( $parsed_tab['blockName'] ?? '' ) ) {
37
+ continue;
38
+ }
39
+
40
+ $tab = $tabs_list[ $tab_position ] ?? null;
41
+ $tab_index = $tab_position;
42
+ ++$tab_position;
43
+
44
+ // Skip tabs with no matching tab panel.
45
+ if ( null === $tab ) {
46
+ continue;
47
+ }
48
+
49
+ $item_context = array_merge(
50
+ $block->context,
51
+ array(
52
+ 'core/tab-index' => $tab_index,
53
+ 'core/tab-id' => $tab['id'] ?? '',
54
+ 'core/tab-label' => $tab['label'] ?? '',
55
+ )
56
+ );
57
+
58
+ $tab_block = new WP_Block( $parsed_tab, $item_context );
59
+ $buttons_html .= $tab_block->render();
60
+ }
61
+
62
+ // Rebuild the wrapper using get_block_wrapper_attributes().
63
+ $wrapper_attributes = get_block_wrapper_attributes( array( 'role' => 'tablist' ) );
64
+ return sprintf( '<div %s>%s</div>', $wrapper_attributes, $buttons_html );
65
+ }
66
+
67
+ /**
68
+ * Registers the `core/tab-list` block on the server.
69
+ *
70
+ * @since 7.0.0
71
+ */
72
+ function register_block_core_tab_list() {
73
+ register_block_type_from_metadata(
74
+ __DIR__ . '/tab-list',
75
+ array(
76
+ 'render_callback' => 'block_core_tab_list_render_callback',
77
+ )
78
+ );
79
+ }
80
+ add_action( 'init', 'register_block_core_tab_list' );
@@ -11,9 +11,9 @@ import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
11
11
  import { useDispatch, useSelect } from '@wordpress/data';
12
12
 
13
13
  /**
14
- * "Add tab" button in the block toolbar for the tab block.
15
- * Inserts a new core/tab into the tab-panel and a new core/tabs-menu-item
16
- * into the tabs-menu, keeping both in sync.
14
+ * "Add tab" button in the block toolbar for the tabs block.
15
+ * Inserts a new core/tab-panel into the tab-panels and a new core/tab
16
+ * into the tab-list, keeping both in sync.
17
17
  *
18
18
  * @param {Object} props
19
19
  * @param {string} props.tabsClientId The client ID of the parent tabs block.
@@ -22,44 +22,44 @@ import { useDispatch, useSelect } from '@wordpress/data';
22
22
  export default function AddTabToolbarControl( { tabsClientId } ) {
23
23
  const { insertBlock } = useDispatch( blockEditorStore );
24
24
 
25
- const { tabPanelClientId, tabsMenuClientId } = useSelect(
25
+ const { tabPanelsClientId, tabsListClientId } = useSelect(
26
26
  ( select ) => {
27
27
  if ( ! tabsClientId ) {
28
28
  return {
29
- tabPanelClientId: null,
30
- tabsMenuClientId: null,
29
+ tabPanelsClientId: null,
30
+ tabsListClientId: null,
31
31
  };
32
32
  }
33
33
  const { getBlocks } = select( blockEditorStore );
34
34
  const innerBlocks = getBlocks( tabsClientId );
35
- const tabPanel = innerBlocks.find(
36
- ( block ) => block.name === 'core/tab-panel'
35
+ const tabPanels = innerBlocks.find(
36
+ ( block ) => block.name === 'core/tab-panels'
37
37
  );
38
- const tabsMenu = innerBlocks.find(
39
- ( block ) => block.name === 'core/tabs-menu'
38
+ const tabList = innerBlocks.find(
39
+ ( block ) => block.name === 'core/tab-list'
40
40
  );
41
41
  return {
42
- tabPanelClientId: tabPanel?.clientId || null,
43
- tabsMenuClientId: tabsMenu?.clientId || null,
42
+ tabPanelsClientId: tabPanels?.clientId || null,
43
+ tabsListClientId: tabList?.clientId || null,
44
44
  };
45
45
  },
46
46
  [ tabsClientId ]
47
47
  );
48
48
 
49
49
  const addTab = () => {
50
- if ( ! tabPanelClientId ) {
50
+ if ( ! tabPanelsClientId ) {
51
51
  return;
52
52
  }
53
53
 
54
- const newTabBlock = createBlock( 'core/tab', {
54
+ const newTabPanelBlock = createBlock( 'core/tab-panel', {
55
55
  label: __( 'Tab' ),
56
56
  } );
57
- insertBlock( newTabBlock, undefined, tabPanelClientId );
57
+ insertBlock( newTabPanelBlock, undefined, tabPanelsClientId );
58
58
 
59
- // Insert a corresponding menu item into the tabs-menu.
60
- if ( tabsMenuClientId ) {
61
- const newMenuItemBlock = createBlock( 'core/tabs-menu-item', {} );
62
- insertBlock( newMenuItemBlock, undefined, tabsMenuClientId );
59
+ // Insert a corresponding tab into the tab-list.
60
+ if ( tabsListClientId ) {
61
+ const newTabBlock = createBlock( 'core/tab', {} );
62
+ insertBlock( newTabBlock, undefined, tabsListClientId );
63
63
  }
64
64
  };
65
65
 
@@ -4,62 +4,52 @@
4
4
  "apiVersion": 3,
5
5
  "name": "core/tab-panel",
6
6
  "title": "Tab Panel",
7
- "description": "Container for tab panel content in a tabbed interface.",
7
+ "description": "Content for a tab in a tabbed interface.",
8
8
  "category": "design",
9
9
  "textdomain": "default",
10
- "parent": [ "core/tabs" ],
11
- "allowedBlocks": [ "core/tab" ],
12
- "attributes": {},
10
+ "attributes": {
11
+ "label": {
12
+ "type": "string",
13
+ "default": ""
14
+ }
15
+ },
16
+ "parent": [ "core/tab-panels" ],
17
+ "usesContext": [
18
+ "core/tabs-activeTabIndex",
19
+ "core/tabs-editorActiveTabIndex",
20
+ "core/tabs-id"
21
+ ],
13
22
  "supports": {
14
- "anchor": false,
23
+ "anchor": true,
15
24
  "html": false,
16
25
  "reusable": false,
17
- "visibility": false,
18
- "lock": false,
19
- "dimensions": {
20
- "aspectRatio": false,
21
- "height": false,
22
- "minHeight": false,
23
- "width": false
24
- },
25
26
  "color": {
26
27
  "background": true,
27
28
  "text": true,
28
- "heading": true,
29
- "link": true,
30
29
  "__experimentalDefaultControls": {
31
30
  "background": true,
32
31
  "text": true
33
32
  }
34
33
  },
34
+ "layout": true,
35
35
  "spacing": {
36
- "blockGap": false,
36
+ "blockGap": true,
37
37
  "padding": true,
38
- "margin": true
38
+ "margin": false
39
39
  },
40
40
  "typography": {
41
41
  "fontSize": true,
42
- "__experimentalFontFamily": true
43
- },
44
- "layout": {
45
- "default": {
46
- "type": "flex",
47
- "flexWrap": "nowrap",
48
- "justifyContent": "stretch",
49
- "orientation": "vertical"
50
- },
51
- "allowSwitching": false,
52
- "allowVerticalAlignment": false,
53
- "allowOrientation": false,
54
- "allowJustification": true,
55
- "allowSizingOnChildren": false
42
+ "__experimentalFontFamily": true,
43
+ "__experimentalDefaultControls": {
44
+ "fontSize": true,
45
+ "__experimentalFontFamily": true
46
+ }
56
47
  },
57
- "__experimentalBorder": {
58
- "radius": true,
59
- "color": true,
60
- "width": true,
61
- "style": true
62
- }
48
+ "renaming": true,
49
+ "visibility": false
50
+ },
51
+ "providesContext": {
52
+ "core/tab-label": "label"
63
53
  },
64
54
  "editorScript": "file:./index.js",
65
55
  "style": "file:./style-index.css"
@@ -0,0 +1,65 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ InspectorControls,
6
+ store as blockEditorStore,
7
+ } from '@wordpress/block-editor';
8
+ import {
9
+ CheckboxControl,
10
+ __experimentalToolsPanel as ToolsPanel,
11
+ __experimentalToolsPanelItem as ToolsPanelItem,
12
+ } from '@wordpress/components';
13
+ import { __ } from '@wordpress/i18n';
14
+ import { useDispatch } from '@wordpress/data';
15
+
16
+ /**
17
+ * Internal dependencies
18
+ */
19
+ import AddTabToolbarControl from './add-tab-toolbar-control';
20
+ import RemoveTabToolbarControl from './remove-tab-toolbar-control';
21
+ import { useToolsPanelDropdownMenuProps } from '../utils/hooks';
22
+
23
+ export default function Controls( { tabsClientId, blockIndex, isDefaultTab } ) {
24
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
25
+ const dropdownMenuProps = useToolsPanelDropdownMenuProps();
26
+
27
+ return (
28
+ <>
29
+ <AddTabToolbarControl tabsClientId={ tabsClientId } />
30
+ <RemoveTabToolbarControl tabsClientId={ tabsClientId } />
31
+ <InspectorControls>
32
+ <ToolsPanel
33
+ label={ __( 'Settings' ) }
34
+ resetAll={ () => {
35
+ updateBlockAttributes( tabsClientId, {
36
+ activeTabIndex: 0,
37
+ } );
38
+ } }
39
+ dropdownMenuProps={ dropdownMenuProps }
40
+ >
41
+ <ToolsPanelItem
42
+ label={ __( 'Default tab' ) }
43
+ hasValue={ () => isDefaultTab && blockIndex !== 0 }
44
+ onDeselect={ () => {
45
+ updateBlockAttributes( tabsClientId, {
46
+ activeTabIndex: 0,
47
+ } );
48
+ } }
49
+ isShownByDefault
50
+ >
51
+ <CheckboxControl
52
+ label={ __( 'Default tab' ) }
53
+ checked={ isDefaultTab }
54
+ onChange={ ( value ) => {
55
+ updateBlockAttributes( tabsClientId, {
56
+ activeTabIndex: value ? blockIndex : 0,
57
+ } );
58
+ } }
59
+ />
60
+ </ToolsPanelItem>
61
+ </ToolsPanel>
62
+ </InspectorControls>
63
+ </>
64
+ );
65
+ }