UNPKG

@wordpress/block-editor

Version:
95 lines (80 loc) 2.37 kB
/** * WordPress dependencies */ import { useLayoutEffect, useReducer } from '@wordpress/element'; /** * Internal dependencies */ import ContrastChecker from '../components/contrast-checker'; import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; function getComputedValue( node, property ) { return node.ownerDocument.defaultView .getComputedStyle( node ) .getPropertyValue( property ); } function getBlockElementColors( blockEl ) { if ( ! blockEl ) { return {}; } const firstLinkElement = blockEl.querySelector( 'a' ); const linkColor = !! firstLinkElement?.innerText ? getComputedValue( firstLinkElement, 'color' ) : undefined; const textColor = getComputedValue( blockEl, 'color' ); let backgroundColorNode = blockEl; let backgroundColor = getComputedValue( backgroundColorNode, 'background-color' ); while ( backgroundColor === 'rgba(0, 0, 0, 0)' && backgroundColorNode.parentNode && backgroundColorNode.parentNode.nodeType === backgroundColorNode.parentNode.ELEMENT_NODE ) { backgroundColorNode = backgroundColorNode.parentNode; backgroundColor = getComputedValue( backgroundColorNode, 'background-color' ); } return { textColor, backgroundColor, linkColor, }; } function reducer( prevColors, newColors ) { const hasChanged = Object.keys( newColors ).some( ( key ) => prevColors[ key ] !== newColors[ key ] ); // Do not re-render if the colors have not changed. return hasChanged ? newColors : prevColors; } export default function BlockColorContrastChecker( { clientId } ) { const blockEl = useBlockElement( clientId ); const [ colors, setColors ] = useReducer( reducer, {} ); // There are so many things that can change the color of a block // So we perform this check on every render. useLayoutEffect( () => { if ( ! blockEl ) { return; } function updateColors() { setColors( getBlockElementColors( blockEl ) ); } // Combine `useLayoutEffect` and two rAF calls to ensure that values are read // after the current paint but before the next paint. window.requestAnimationFrame( () => window.requestAnimationFrame( updateColors ) ); } ); return ( <ContrastChecker backgroundColor={ colors.backgroundColor } textColor={ colors.textColor } linkColor={ colors.linkColor } enableAlphaChecker /> ); }