Skip to content

Instantly share code, notes, and snippets.

@5ally
Forked from hvt/tabbed-block.editor.js
Created January 25, 2024 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 5ally/411be82f51e351f64ab4d7df2590ac82 to your computer and use it in GitHub Desktop.
Save 5ally/411be82f51e351f64ab4d7df2590ac82 to your computer and use it in GitHub Desktop.
WordPress Gutenberg custom block example
(function(blocks, blockEditor, element) {
const el = element.createElement,
useRef = element.useRef,
useEffect = element.useEffect,
useBlockProps = blockEditor.useBlockProps,
InnerBlocks = blockEditor.InnerBlocks
;
blocks.registerBlockType(
'hvt/tabbed-block',
{
title: 'HVT tabbed block',
edit: ({attributes, setAttributes, clientId}) => {
const tabbedBlockTabsRef = useRef(null);
useEffect(
() => {
// This fails, because "initializeTabbedBlock()" also initializes the panes, which are InnerBlocks
HVT.initializeTabbedBlock(tabbedBlockTabsRef.current);
},
[]
);
let {blockId} = attributes;
if (!blockId) {
blockId = clientId;
setAttributes({blockId});
}
const blockProps = useBlockProps({
className: 'hvt-tabbed-block',
}),
tabs = [],
paneTemplates = []
;
for (const tab of attributes.tabs) {
tabs.push(
el(
'a',
{
className: 'hvt-tabbed-block-tab',
},
tab.title
)
);
paneTemplates.push(
[
'hvt/tabbed-block-tab',
{
blockId: blockId,
paneId: tab.paneTarget,
}
]
);
}
return el(
'div',
blockProps,
[
el(
'div',
{
className: 'hvt-tabbed-block-tabs',
ref: tabbedBlockTabsRef,
},
tabs
),
el(
'div',
{className: 'hvt-tabbed-block-panes'},
[
el(
InnerBlocks,
{
'template': paneTemplates,
'allowedBlocks': ['hvt/tabbed-block-tab'],
}
),
]
),
]
);
},
save: ({attributes}) => {
const blockProps = useBlockProps.save({
className: 'hvt-tabbed-block',
});
const tabs = [];
for (const tab of attributes.tabs) {
tabs.push(
el(
'a',
{
className: 'hvt-tabbed-block-tab',
},
tab.title,
)
);
}
return el(
'div',
blockProps,
[
el(
'div',
{
className: 'hvt-tabbed-block-tabs',
},
tabs
),
el(
'div',
{
className: 'hvt-tabbed-block-panes',
},
[
el(
InnerBlocks.Content
),
]
),
]
);
},
}
);
})(window.wp.blocks, window.wp.blockEditor, window.wp.element);
var HVT = {
initializeTabbedBlock: (tabbedBlockTabs, tabToSelect = 0) => {
const tabbedBlock = tabbedBlockTabs.closest('div.hvt-tabbed-block[data-hvt-tabbed-block-id]'),
tabs = tabbedBlock.querySelectorAll(':scope > div.hvt-tabbed-block-tabs > a.hvt-tabbed-block-tab')
;
for (const tab of tabs) {
tab.addEventListener('click', HVT.onTabbedBlockTabSelect);
}
tabs[0].click();
},
onTabbedBlockTabSelect: (event) => {
const selectedTab = event.currentTarget,
tabbedBlock = selectedTab.closest('div.dnv-tabbed-block'),
tabs = tabbedBlock.querySelectorAll(':scope > div.dnv-tabbed-block-tabs > a.dnv-tabbed-block-tab'),
panesBlock = tabbedBlock.querySelector(':scope > div.dnv-tabbed-block-panes'),
blockId = tabbedBlock.dataset.dnvTabbedBlockId,
panes = panesBlock.querySelectorAll(`div.dnv-tabbed-block-pane[data-dnv-tabbed-block-id="${blockId}"]`),
selectedPane = panesBlock.querySelector(`div.dnv-tabbed-block-pane[data-dnv-tabbed-block-id="${blockId}"][data-dnv-tabbed-block-pane-id="${selectedTab.dataset.dnvTabbedBlockPaneTarget}"]`)
;
for (const tab of tabs) {
tab.classList.remove('dnv-tabbed-block-tab-active');
}
selectedTab.classList.add('dnv-tabbed-block-tab-active');
for (const pane of panes) {
pane.style.display = 'none';
}
selectedPane.style.display = 'block'; // <== this fails eventually, because selectedPane does not exist
event.preventDefault();
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment