Skip to content

Instantly share code, notes, and snippets.

@fabiankaegy
Created December 17, 2024 21:40
Show Gist options
  • Save fabiankaegy/8fd3f87018afe2cd9c36cb700fad285b to your computer and use it in GitHub Desktop.
Save fabiankaegy/8fd3f87018afe2cd9c36cb700fad285b to your computer and use it in GitHub Desktop.
Responsive Text align options prototype
port { registerBlockExtension } from '@10up/block-components';
import { useSelect } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { InspectorControls } from '@wordpress/block-editor';
import { useState, useEffect } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import classnames from 'classnames';
const SUPPORTED_BLOCKS = ['core/heading'];
registerBlockExtension(SUPPORTED_BLOCKS, {
attributes: {
metadata: {
type: 'object',
default: {
responsive: {
mobile: {},
tablet: {},
},
},
},
},
Edit: ({ attributes, setAttributes }) => {
/**
* @type {string} deviceType - The current device type.
*/
const [deviceType] = useSelect((select) => [select(editorStore).getDeviceType()], []);
const [mainTextAlign, setMainTextAlign] = useState();
useEffect(() => {
if (deviceType === 'Desktop' && mainTextAlign !== attributes?.textAlign) {
// store the desktop value of the textAlign attribute
setMainTextAlign(attributes?.textAlign);
}
if (deviceType !== 'Desktop') {
if (attributes?.textAlign !== mainTextAlign) {
document.body.classList.add(`has-${deviceType.toLowerCase()}-override`);
/**
* reset the main textAlign value to the desktop value
* and store the selected value in the responsive object
* for the current device type
*/
setAttributes({
metadata: {
...attributes.metadata,
responsive: {
...attributes.metadata.responsive,
[deviceType.toLowerCase()]: {
...(attributes.metadata.responsive[deviceType] || {}),
textAlign: attributes?.textAlign,
},
},
},
textAlign: mainTextAlign,
});
}
}
}, [deviceType, attributes, mainTextAlign, setAttributes]);
return (
<InspectorControls>
<p>Responsive Heading</p>
<pre>{JSON.stringify(attributes, null, 2)}</pre>
</InspectorControls>
);
},
classNameGenerator: () => null,
inlineStyleGenerator: () => null,
extensionName: 'responsiveHeading',
});
/**
* addAdditionalPropertiesInEditor
*/
const addHeadingResponsiveClassesInEditor = createHigherOrderComponent((BlockList) => {
return (props) => {
const { name, attributes, className } = props;
// return early from the block modification
if (!SUPPORTED_BLOCKS.includes(name) || !attributes.metadata?.responsive) {
return <BlockList {...props} />;
}
const { responsive } = attributes?.metadata || {};
const mobileOptions = responsive?.mobile;
const tabletOptions = responsive?.tablet;
if (!mobileOptions && !tabletOptions) {
return <BlockList {...props} />;
}
const newClassName = classnames(className, {
[`has-text-align-${mobileOptions?.textAlign || 'left'}--mobile`]:
mobileOptions?.textAlign,
[`has-text-align-${tabletOptions?.textAlign || 'left'}--tablet`]:
tabletOptions?.textAlign,
});
return <BlockList {...props} className={newClassName} />;
};
}, 'addHeadingResponsiveClassesInEditor');
addFilter(
'editor.BlockListBlock',
`example/headig/responsive-text-align`,
addHeadingResponsiveClassesInEditor,
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment