diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index 0cc62b6aa9fa17..20126c5e4f4088 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -889,13 +889,14 @@ Add white space between blocks and customize its height. ([Source](https://githu
## Tab
-Tab container for content (use within the Tabs block). ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/tab))
+Single tab within a tabs block. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/tab))
- **Name:** core/tab
- **Experimental:** true
- **Category:** design
- **Parent:** core/tabs
-- **Supports:** ~~align~~, ~~html~~
+- **Supports:** ~~html~~, ~~inserter~~, ~~reusable~~
+- **Attributes:** title
## Table
@@ -924,7 +925,8 @@ Organize content into tabs. ([Source](https://github.com/WordPress/gutenberg/tre
- **Experimental:** true
- **Category:** design
- **Allowed Blocks:** core/tab
-- **Supports:** align (full, wide), layout (default, ~~allowJustification~~, ~~allowSwitching~~), shadow, spacing (margin, padding), ~~html~~
+- **Supports:** align (full, wide), interactivity, layout (default, ~~allowJustification~~, ~~allowSwitching~~), shadow, spacing (margin, padding), ~~html~~
+- **Attributes:** activeTab
## Tag Cloud
diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss
index 790e09535f4b69..86c35f43de2489 100644
--- a/packages/block-library/src/style.scss
+++ b/packages/block-library/src/style.scss
@@ -50,8 +50,10 @@
@import "./site-title/style.scss";
@import "./social-links/style.scss";
@import "./spacer/style.scss";
+@import "./tab/style.scss";
@import "./tag-cloud/style.scss";
@import "./table/style.scss";
+@import "./tabs/style.scss";
@import "./term-description/style.scss";
@import "./text-columns/style.scss";
@import "./verse/style.scss";
diff --git a/packages/block-library/src/tab/block.json b/packages/block-library/src/tab/block.json
index 802c014d5579af..fdabf177c2697b 100644
--- a/packages/block-library/src/tab/block.json
+++ b/packages/block-library/src/tab/block.json
@@ -19,6 +19,5 @@
"reusable": false
},
"usesContext": [ "tabs/activeTab" ],
- "editorScript": "file:./build/index.js",
- "style": "file:./build/style.css"
+ "style": "wp-block-tab"
}
diff --git a/packages/block-library/src/tab/edit.js b/packages/block-library/src/tab/edit.js
index 45b75750e156af..27757e0dc2af4c 100644
--- a/packages/block-library/src/tab/edit.js
+++ b/packages/block-library/src/tab/edit.js
@@ -1,25 +1,19 @@
/**
* WordPress dependencies
*/
-import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';
-import { __ } from '@wordpress/i18n';
+import {
+ InnerBlocks,
+ useBlockProps,
+ useInnerBlocksProps,
+} from '@wordpress/block-editor';
-export default function Edit( { context } ) {
- console.log( context );
- const isActive = context[ 'tabs/activeTab' ];
- return (
-
-
-
- );
+export default function Edit( { clientId, context } ) {
+ const isActive = context[ 'tabs/activeTab' ] === clientId;
+ const blockProps = useBlockProps( {
+ className: isActive ? 'is-active' : '',
+ } );
+ const innerBlocksProps = useInnerBlocksProps( blockProps, {
+ renderAppender: InnerBlocks.ButtonBlockAppender,
+ } );
+ return ;
}
diff --git a/packages/block-library/src/tab/index.js b/packages/block-library/src/tab/index.js
index 724198cd0d54cc..966216c39af911 100644
--- a/packages/block-library/src/tab/index.js
+++ b/packages/block-library/src/tab/index.js
@@ -7,8 +7,6 @@ import edit from './edit';
import save from './save';
// import icon from './icon';
-// import './style.scss';
-
const { name } = metadata;
export { metadata, name };
diff --git a/packages/block-library/src/tab/style.scss b/packages/block-library/src/tab/style.scss
new file mode 100644
index 00000000000000..a2051c5861ef6f
--- /dev/null
+++ b/packages/block-library/src/tab/style.scss
@@ -0,0 +1,8 @@
+.wp-block-tab {
+ display: none;
+
+ &.is-active {
+ display: block;
+ }
+}
+
diff --git a/packages/block-library/src/tabs/block.json b/packages/block-library/src/tabs/block.json
index 154ba0e9e6ada8..92422411ce30e0 100644
--- a/packages/block-library/src/tabs/block.json
+++ b/packages/block-library/src/tabs/block.json
@@ -10,8 +10,8 @@
"allowedBlocks": [ "core/tab" ],
"attributes": {
"activeTab": {
- "type": "number",
- "default": 0
+ "type": "string",
+ "default": ""
}
},
"providesContext": {
@@ -32,6 +32,5 @@
"padding": true
}
},
- "editorStyle": "wp-block-tabs-editor",
"style": "wp-block-tabs"
}
diff --git a/packages/block-library/src/tabs/edit.js b/packages/block-library/src/tabs/edit.js
index 481479b15f0550..d0f0f583e89805 100644
--- a/packages/block-library/src/tabs/edit.js
+++ b/packages/block-library/src/tabs/edit.js
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import clsx from 'clsx';
+
/**
* WordPress dependencies
*/
@@ -6,11 +11,16 @@ import {
useBlockProps,
useInnerBlocksProps,
store as blockEditorStore,
+ RichText,
} from '@wordpress/block-editor';
-import { useSelect } from '@wordpress/data';
-import { __ } from '@wordpress/i18n';
-import { useState } from '@wordpress/element';
-import clsx from 'clsx';
+import { Button } from '@wordpress/components';
+import { useDispatch, useSelect } from '@wordpress/data';
+import { useEffect } from '@wordpress/element';
+
+const initialTabsTemplate = [
+ [ 'core/tab', { title: 'Tab 1' } ],
+ [ 'core/tab', { title: 'Tab 2' } ],
+];
export default function Edit( { attributes, clientId, setAttributes } ) {
const { activeTab } = attributes;
@@ -19,28 +29,77 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
[ clientId ]
);
- const setActiveTab = ( index ) => {
- setAttributes( { activeTab: index } );
+ const blockProps = useBlockProps();
+
+ const innerBlockProps = useInnerBlocksProps(
+ {
+ className: 'wp-block-tabs__tab-content',
+ },
+ {
+ renderAppender: InnerBlocks.ButtonBlockAppender,
+ template: initialTabsTemplate,
+ }
+ );
+
+ const { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } =
+ useDispatch( blockEditorStore );
+
+ const setActiveTab = ( tabId ) => {
+ __unstableMarkNextChangeAsNotPersistent();
+ setAttributes( { activeTab: tabId } );
};
+ useEffect( () => {
+ // Initialize the first tab as active when the component mounts.
+ if ( innerBlocks.length ) {
+ setActiveTab( innerBlocks[ 0 ].clientId );
+ }
+ }, [] ); // eslint-disable-line react-hooks/exhaustive-deps -- only run effect once when component mounts.
+
+ // if ( ! innerBlocks || innerBlocks.length === 0 ) {
+ // return null;
+ // }
+
return (
-
-
- { innerBlocks.map( ( block, index ) => (
-
- ) ) }
-
-
-
-
+
+
+ { innerBlocks.map( ( block ) => {
+ const isActive = block.clientId === activeTab;
+ const tabIndex = isActive ? '0' : '-1';
+
+ // TODO: Add unique ids and aria attributes for accessibility.
+ // (Try the anchor generation functionality from the heading block?)
+ return (
+ -
+
+
+ );
+ } ) }
+
+
+
);
}
diff --git a/packages/block-library/src/tabs/index.js b/packages/block-library/src/tabs/index.js
index 724198cd0d54cc..966216c39af911 100644
--- a/packages/block-library/src/tabs/index.js
+++ b/packages/block-library/src/tabs/index.js
@@ -7,8 +7,6 @@ import edit from './edit';
import save from './save';
// import icon from './icon';
-// import './style.scss';
-
const { name } = metadata;
export { metadata, name };
diff --git a/packages/block-library/src/tabs/style.scss b/packages/block-library/src/tabs/style.scss
index bfdd07f54461ff..84ef2377c87af0 100644
--- a/packages/block-library/src/tabs/style.scss
+++ b/packages/block-library/src/tabs/style.scss
@@ -1,29 +1,6 @@
-.wp-block-tabs {
- .wp-block-tabs__tab-buttons {
- display: flex;
- border-bottom: 1px solid #ccc;
- }
-
- .wp-block-tabs__tab-button {
- background: none;
- border: none;
- padding: 10px 15px;
- cursor: pointer;
-
- &.is-active {
- border-bottom: 2px solid #007cba;
- }
- }
-
- .wp-block-tabs__content {
- padding: 15px 0;
- }
-}
-
-.wp-block-tab {
- display: none;
-
- &.is-active {
- display: block;
- }
+.wp-block-tabs__list {
+ display: flex;
+ gap: 10px;
+ list-style: none;
+ padding: 0;
}