Skip to content
This repository was archived by the owner on Dec 18, 2025. It is now read-only.

Commit 164562e

Browse files
authored
Merge pull request #83 from creode/feature/tabs-block
Feature/tabs block
2 parents d335cf4 + 9b580b6 commit 164562e

10 files changed

Lines changed: 629 additions & 1 deletion

File tree

blocks/all.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ function ( array $categories ) {
4848
require_once plugin_dir_path( __FILE__ ) . 'mobile-menu/class-mobile-menu-block.php';
4949
require_once plugin_dir_path( __FILE__ ) . 'post-listing/class-post-listing-block.php';
5050
require_once plugin_dir_path( __FILE__ ) . 'search-and-filter/class-search-and-filter-block.php';
51+
require_once plugin_dir_path( __FILE__ ) . 'tabs/class-tabs-block.php';

blocks/tabs/assets/_tabs.scss

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
@use '/scss/globals';
2+
@use '/scss/extenders/container';
3+
4+
@mixin render {
5+
.tabs__outer-wrapper {
6+
@extend %container__outer-wrapper;
7+
}
8+
9+
.tabs__wrapper {
10+
@extend %container__wrapper;
11+
}
12+
13+
.tabs__wrapper--reduce-bottom-space {
14+
@extend %container__wrapper--reduce-bottom-space;
15+
}
16+
17+
.tabs__inner {
18+
@extend %container__inner;
19+
}
20+
21+
.tabs__tabs {
22+
display: flex;
23+
}
24+
25+
.tabs__tab-outer-wrapper,
26+
.wp-block-acf-tabs-tab {
27+
background-color: lightgray;
28+
}
29+
30+
.tabs__tab {
31+
padding: globals.$space-top globals.$space-right 0 globals.$space-left;
32+
background-color: transparent;
33+
border: none;
34+
cursor: pointer;
35+
}
36+
37+
.tabs__tab--active {
38+
background-color: gray;
39+
}
40+
41+
.tabs__pattern {
42+
&[hidden],
43+
&[aria-hidden="true"] {
44+
display: none;
45+
}
46+
}
47+
}

blocks/tabs/assets/admin.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
class Tabs extends AdminBlock {
2+
3+
setup() {
4+
this.setActiveTab(parseInt(this.getAttribute('active_tab')));
5+
this.setEventListeners();
6+
}
7+
8+
setEventListeners() {
9+
this.blockDiv.on(
10+
'click',
11+
'.tabs__tab',
12+
(event) => {
13+
const index = this.blockDiv.find('.tabs__tab').index(event.currentTarget);
14+
15+
this.capturePatterns();
16+
this.setActiveTab(index);
17+
}
18+
);
19+
20+
this.addListener(
21+
(path, originalValue, newValue) => {
22+
// Check if path matches pattern: innerBlocks[n].attributes.data.field_tabs_block_pattern
23+
const regex = /^innerBlocks\[\d+\]\.attributes\.data\.field_tabs_block_pattern$/;
24+
if (!regex.test(path)) {
25+
return;
26+
}
27+
28+
this.capturePatterns();
29+
}
30+
);
31+
}
32+
33+
setActiveTab(index) {
34+
this.blockDiv.find('.tabs__tab').removeClass('tabs__tab--active');
35+
this.blockDiv.find('.tabs__tab').eq(index).addClass('tabs__tab--active');
36+
this.setAttribute('active_tab', index);
37+
}
38+
39+
capturePatterns() {
40+
this.loadBlock();
41+
42+
let patterns = [];
43+
44+
for (const i in this.block.innerBlocks) {
45+
patterns[i] = '';
46+
if (typeof this.block.innerBlocks[i].attributes == 'undefined') {
47+
continue;
48+
}
49+
if (typeof this.block.innerBlocks[i].attributes.data == 'undefined') {
50+
continue;
51+
}
52+
if (typeof this.block.innerBlocks[i].attributes.data.field_tabs_block_pattern !== 'undefined') {
53+
patterns[i] = this.block.innerBlocks[i].attributes.data.field_tabs_block_pattern;
54+
}
55+
if (typeof this.block.innerBlocks[i].attributes.data.pattern !== 'undefined') {
56+
patterns[i] = this.block.innerBlocks[i].attributes.data.pattern;
57+
}
58+
}
59+
60+
this.setAttribute('patterns', patterns.join(','));
61+
}
62+
}
63+
64+
new AdminBlockInitializer(
65+
'.wp-block-acf-tabs',
66+
(blockDiv) => {
67+
window.mytest = new Tabs(blockDiv);
68+
}
69+
);

blocks/tabs/assets/tabs.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
class Tabs {
2+
3+
elements = {};
4+
5+
constructor(wrapper) {
6+
this.loadElements(wrapper);
7+
this.setTabActiveState();
8+
this.addEventListeners();
9+
}
10+
11+
loadElements(wrapper) {
12+
this.elements.wrapper = wrapper;
13+
this.elements.tab = wrapper.find('.tabs__tab');
14+
this.elements.pattern = wrapper.next().find('.tabs__pattern');
15+
}
16+
17+
setTabActiveState() {
18+
this.elements.tab.removeClass('tabs__tab--active');
19+
this.elements.pattern.prop('hidden', true);
20+
this.elements.pattern.attr('aria-hidden', true);
21+
22+
const index = this.elements.wrapper.data('active-tab');
23+
const tab = this.elements.tab.eq(index);
24+
const pattern = this.elements.pattern.eq(index);
25+
26+
tab.addClass('tabs__tab--active');
27+
pattern.prop('hidden', false);
28+
pattern.attr('aria-hidden', false);
29+
}
30+
31+
addEventListeners() {
32+
this.elements.tab.on(
33+
'click',
34+
() => {
35+
const index = this.elements.tab.index(event.currentTarget);
36+
this.setActiveTab(index);
37+
this.setTabActiveState();
38+
}
39+
);
40+
}
41+
42+
setActiveTab(index) {
43+
this.elements.wrapper.data('active-tab', index);
44+
}
45+
}
46+
47+
jQuery(document).ready(
48+
() => {
49+
const wrappers = jQuery('.tabs__wrapper');
50+
51+
wrappers.each(
52+
(index) => {
53+
new Tabs(wrappers.eq(index));
54+
}
55+
);
56+
}
57+
);

blocks/tabs/class-tabs-block.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
/**
3+
* Tabs block class.
4+
*
5+
* @package Creode Blocks
6+
*/
7+
8+
namespace Creode_Blocks;
9+
10+
/**
11+
* Tabs block class.
12+
*
13+
* @wordpress-block-version 2.6.0
14+
*/
15+
class Tabs_Block extends Block {
16+
17+
use Trait_Block_Pattern_Options;
18+
use Trait_Has_Reduce_Bottom_Space_Option;
19+
20+
/**
21+
* The blocks icon from https://developer.wordpress.org/resource/dashicons/ or an inline SVG.
22+
*
23+
* @var string
24+
*/
25+
protected $icon = 'table-row-after';
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
protected function name(): string {
31+
return 'tabs';
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
protected function label(): string {
38+
return 'Tabs';
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
protected function additional_attributes(): array {
45+
return array(
46+
'active_tab' => array(
47+
'type' => 'number',
48+
'default' => 0,
49+
),
50+
'patterns' => array(
51+
'type' => 'string',
52+
'default' => array(),
53+
),
54+
);
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
protected function child_blocks(): array {
61+
return array(
62+
new Child_Block(
63+
'tab',
64+
'Tab',
65+
array(
66+
array(
67+
'key' => 'field_tabs_block_pattern',
68+
'name' => 'pattern',
69+
'label' => 'Pattern',
70+
'type' => 'select',
71+
'choices' => $this->get_block_pattern_choices(),
72+
),
73+
),
74+
__DIR__ . '/templates/tab.php',
75+
array(),
76+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" context="list-view" aria-hidden="true" focusable="false"><path d="M19 6H6c-1.1 0-2 .9-2 2v9c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zM6 17.5c-.3 0-.5-.2-.5-.5V8c0-.3.2-.5.5-.5h3v10H6zm13.5-.5c0 .3-.2.5-.5.5h-3v-10h3c.3 0 .5.2.5.5v9z"></path></svg>',
77+
array(
78+
'mode' => false,
79+
'color' => array(
80+
'text' => false,
81+
'background' => true,
82+
),
83+
)
84+
),
85+
);
86+
}
87+
88+
/**
89+
* {@inheritdoc}
90+
*/
91+
protected function template(): string {
92+
return __DIR__ . '/templates/block.php';
93+
}
94+
95+
/**
96+
* {@inheritdoc}
97+
*/
98+
protected function use_default_wrapper_template(): bool {
99+
return false;
100+
}
101+
102+
/**
103+
* {@inheritdoc}
104+
*/
105+
protected function supports(): array {
106+
return array(
107+
'mode' => false,
108+
'color' => array(
109+
'text' => false,
110+
'background' => true,
111+
),
112+
);
113+
}
114+
115+
/**
116+
* {@inheritdoc}
117+
*/
118+
protected function admin_scripts(): array {
119+
return array(
120+
new Script(
121+
'tabs-block',
122+
plugin_dir_url( __FILE__ ) . 'assets/admin.js',
123+
array( 'jquery', 'admin-block-initializer', 'admin-block' ),
124+
'1.0.0'
125+
),
126+
);
127+
}
128+
129+
/**
130+
* {@inheritdoc}
131+
*/
132+
protected function scripts(): array {
133+
return array(
134+
new Script(
135+
'tabs-block',
136+
plugin_dir_url( __FILE__ ) . 'assets/tabs.js',
137+
array( 'jquery' ),
138+
'1.0.0'
139+
),
140+
);
141+
}
142+
}

0 commit comments

Comments
 (0)