Skip to content

Instantly share code, notes, and snippets.

@markhowellsmead
Created December 6, 2023 16:07
Show Gist options
  • Save markhowellsmead/01c8c29937162e93a11e21c8209872d1 to your computer and use it in GitHub Desktop.
Save markhowellsmead/01c8c29937162e93a11e21c8209872d1 to your computer and use it in GitHub Desktop.
Add page accent color controls
import { PanelRow, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption } from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { useCallback, useEffect, useState } from '@wordpress/element';
import { withSelect, withDispatch, useSelect, useDispatch } from '@wordpress/data';
import { PluginPostStatusInfo } from '@wordpress/edit-post';
import { __ } from '@wordpress/i18n';
import { Icon, check } from '@wordpress/icons';
import { registerPlugin } from '@wordpress/plugins';
/**
* Define the available colors here
*/
const colors = ['blue-grey-25', 'blue-grey-50', 'blue-80', 'blue-grey', 'blue', 'green-grey-50', 'green-grey', 'green-80', 'green'];
/**
* usePostMeta
*
* Hook that allows you to easily consume and update Post Meta values
*
* @return {Object} meta values and setMetaValue function
*/
function usePostMeta(fieldName) {
const { editPost } = useDispatch('core/editor');
const value = useSelect((select) => select('core/editor').getEditedPostAttribute('meta')?.[fieldName], [fieldName]);
const editValue = useCallback(
(newValue) => {
editPost({ meta: { [fieldName]: newValue } });
},
[editPost, fieldName]
);
return [value, editValue];
}
const ShtAccentColors = ({ postType }) => {
const [iframe, setIframe] = useState(null);
if (!['page', 'post'].includes(postType)) {
return null;
}
const addColorToIframe = (iframe, color, delay) => {
iframe?.contentDocument?.body?.classList?.add(color);
iframe?.contentDocument?.body?.classList?.add(color, 'is-with-accent');
};
const [color, setColor] = usePostMeta('sht_post_accentcolor');
useEffect(() => {
const add_interval = setInterval(() => {
addColorToIframe(iframe, color, true);
if (iframe?.contentDocument?.body?.classList?.contains('is-with-accent')) {
clearInterval(add_interval);
}
}, 50);
}, [iframe]);
useEffect(() => {
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (!!mutation.target.querySelector('[name="editor-canvas"]')) {
setIframe(mutation.target.querySelector('[name="editor-canvas"]'));
observer.disconnect();
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
return () => {
observer.disconnect(); // Clean up the observer on component unmount
};
}, []);
useEffect(() => {
colors.forEach((availableColor) => {
if (iframe) {
iframe.contentDocument.body.classList.remove('is-with-accent', `is-${availableColor}-accent`);
}
document.body.classList.remove('is-with-accent', `is-${availableColor}-accent`);
});
addColorToIframe(iframe, color);
document.body.classList.add(color, 'is-with-accent');
}, [color]);
const checkIcon = <Icon icon={check} size={28} />;
return (
<PluginPostStatusInfo>
<PanelRow className="components-sht-accent-accent-colors-row">
<ToggleGroupControl
value={color}
className="components-sht-accent-accent-colors"
onChange={(newColor) => {
setColor(newColor);
}}
label={__('Akzentfarbe', 'sha')}
isBlock
>
{colors.map((availableColor) => {
const className = `is-${availableColor}-accent`;
return <ToggleGroupControlOption className={className} value={className} label={color == className ? checkIcon : null} />;
})}
</ToggleGroupControl>
</PanelRow>
</PluginPostStatusInfo>
);
};
const ShtAccentColorswithSelect = compose([
withSelect((select) => {
return {
postType: select('core/editor').getCurrentPostType(),
};
}),
withDispatch((dispatch) => {
const { editPost } = dispatch('core/editor');
return { editPost };
}),
])(ShtAccentColors);
registerPlugin('sht-accent-colors', { render: ShtAccentColorswithSelect });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment