| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Tab Block | |
| 3 | + * Tabs Block | |
| 4 | 4 | * |
| 5 | 5 | * @package WordPress |
| 6 | 6 | */ |
| 7 | 7 | |
| @@ -7,57 +7,59 @@ | ||
| 7 | 7 | |
| 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 | - * | |
| 15 | 11 | * @since 7.0.0 |
| 16 | 12 | * |
| 17 | 13 | * @param array $attributes Block attributes. |
| 18 | - * @param string $content Block content (styled button from save.js). | |
| 19 | - * @param \WP_Block $block WP_Block instance. | |
| 14 | + * @param string $content Block content. | |
| 20 | 15 | * |
| 21 | 16 | * @return string Updated HTML. |
| 22 | 17 | */ |
| 23 | -function gutenberg_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'] ?? ''; | |
| 27 | - | |
| 18 | +function gutenberg_block_core_tab_render( array $attributes, string $content ): string { | |
| 19 | + $tag_processor = new WP_HTML_Tag_Processor( $content ); | |
| 20 | + $tag_processor->next_tag( array( 'class_name' => 'wp-block-tab' ) ); | |
| 21 | + $tab_id = (string) $tag_processor->get_attribute( 'id' ); | |
| 22 | + // If no id, generate a unique one | |
| 28 | 23 | if ( empty( $tab_id ) ) { |
| 29 | - $tab_id = 'tab-' . $tab_index; | |
| 24 | + $tab_id = sanitize_title( $attributes['label'] ); | |
| 25 | + $tag_processor->set_attribute( 'id', $tab_id ); | |
| 30 | 26 | } |
| 31 | 27 | |
| 32 | - // Add Interactivity API directives and tab-specific attributes to the button. | |
| 33 | - $tag_processor = new WP_HTML_Tag_Processor( $content ); | |
| 28 | + /** | |
| 29 | + * Add interactivity to the tab element. | |
| 30 | + */ | |
| 31 | + $tag_processor->set_attribute( | |
| 32 | + 'data-wp-interactive', | |
| 33 | + 'core/tabs/private' | |
| 34 | + ); | |
| 35 | + $tag_processor->set_attribute( | |
| 36 | + 'data-wp-context', | |
| 37 | + wp_json_encode( | |
| 38 | + array( | |
| 39 | + 'tab' => array( | |
| 40 | + 'id' => $tab_id, | |
| 41 | + ), | |
| 42 | + ) | |
| 43 | + ) | |
| 44 | + ); | |
| 34 | 45 | |
| 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 | - ); | |
| 46 | - } | |
| 46 | + /** | |
| 47 | + * Process accessibility and interactivity attributes. | |
| 48 | + */ | |
| 49 | + $tag_processor->set_attribute( 'role', 'tabpanel' ); | |
| 50 | + $tag_processor->set_attribute( 'aria-labelledby', 'tab__' . $tab_id ); | |
| 51 | + $tag_processor->set_attribute( 'data-wp-bind--hidden', '!state.isActiveTab' ); | |
| 52 | + $tag_processor->set_attribute( 'tabindex', 0 ); | |
| 47 | 53 | |
| 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 | |
| 54 | - ); | |
| 54 | + return (string) $tag_processor->get_updated_html(); | |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | /** |
| 58 | 58 | * Registers the `core/tab` block on the server. |
| 59 | 59 | * |
| 60 | + * @hook init | |
| 61 | + * | |
| 60 | 62 | * @since 7.0.0 |
| 61 | 63 | */ |
| 62 | 64 | function gutenberg_register_block_core_tab() { |
| 63 | 65 | register_block_type_from_metadata( |
| @@ -62,9 +64,9 @@ | ||
| 62 | 64 | function gutenberg_register_block_core_tab() { |
| 63 | 65 | register_block_type_from_metadata( |
| 64 | 66 | __DIR__ . '/tab', |
| 65 | 67 | array( |
| 66 | - 'render_callback' => 'gutenberg_block_core_tab_render_callback', | |
| 68 | + 'render_callback' => 'gutenberg_block_core_tab_render', | |
| 67 | 69 | ) |
| 68 | 70 | ); |
| 69 | 71 | } |
| 70 | 72 | add_action( 'init', 'gutenberg_register_block_core_tab', 20 ); |