@@ -637,4 +637,84 @@ public function data_layout_support_flag_renders_consistent_container_hash() {
637637 ),
638638 );
639639 }
640+
641+ /**
642+ * Tests that custom blocks include namespace in layout classnames.
643+ *
644+ * When layout support is enabled for custom blocks, the generated
645+ * layout classname should include the full block namespace to ensure
646+ * that CSS selectors match correctly.
647+ *
648+ * @ticket 63839
649+ * @covers ::wp_render_layout_support_flag
650+ *
651+ * @dataProvider data_layout_classname_with_custom_blocks
652+ */
653+ public function test_layout_classname_includes_namespace_for_custom_blocks ( $ block_name , $ layout_type , $ expected_class , $ should_not_contain ) {
654+ switch_theme ( 'default ' );
655+
656+ register_block_type (
657+ $ block_name ,
658+ array (
659+ 'supports ' => array (
660+ 'layout ' => true ,
661+ ),
662+ )
663+ );
664+
665+ $ block_content = '<div class="wp-block-test"><p>Content</p></div> ' ;
666+ $ block = array (
667+ 'blockName ' => $ block_name ,
668+ 'attrs ' => array (
669+ 'layout ' => array (
670+ 'type ' => $ layout_type ,
671+ ),
672+ ),
673+ );
674+
675+ $ output = wp_render_layout_support_flag ( $ block_content , $ block );
676+
677+ // Assert that the expected class is present.
678+ $ this ->assertStringContainsString ( $ expected_class , $ output );
679+
680+ // Assert that the old buggy class is not present.
681+ $ this ->assertStringNotContainsString ( $ should_not_contain , $ output );
682+
683+ // Clean up the registered block type.
684+ unregister_block_type ( $ block_name );
685+ }
686+
687+ /**
688+ * Data provider for test_layout_classname_includes_namespace_for_custom_blocks.
689+ *
690+ * @return array
691+ */
692+ public function data_layout_classname_with_custom_blocks () {
693+ return array (
694+ 'custom block with constrained layout ' => array (
695+ 'block_name ' => 'foo/bar ' ,
696+ 'layout_type ' => 'constrained ' ,
697+ 'expected_class ' => 'wp-block-foo-bar-is-layout-constrained ' ,
698+ 'should_not_contain ' => 'wp-block-bar-is-layout-constrained ' ,
699+ ),
700+ 'custom block with default layout ' => array (
701+ 'block_name ' => 'foo/bar ' ,
702+ 'layout_type ' => 'default ' ,
703+ 'expected_class ' => 'wp-block-foo-bar-is-layout-flow ' ,
704+ 'should_not_contain ' => 'wp-block-bar-is-layout-flow ' ,
705+ ),
706+ 'custom block with flex layout ' => array (
707+ 'block_name ' => 'foo/bar ' ,
708+ 'layout_type ' => 'flex ' ,
709+ 'expected_class ' => 'wp-block-foo-bar-is-layout-flex ' ,
710+ 'should_not_contain ' => 'wp-block-bar-is-layout-flex ' ,
711+ ),
712+ 'custom block with grid layout ' => array (
713+ 'block_name ' => 'foo/bar ' ,
714+ 'layout_type ' => 'grid ' ,
715+ 'expected_class ' => 'wp-block-foo-bar-is-layout-grid ' ,
716+ 'should_not_contain ' => 'wp-block-bar-is-layout-grid ' ,
717+ ),
718+ );
719+ }
640720}
0 commit comments