Skip to content

Commit

Permalink
Block Editor: Fix block color contrast checker (#68799)
Browse files Browse the repository at this point in the history
* Block Editor: Fix block color contrast checker
* Use reducer hook
* Add comment

Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: juanfra <[email protected]>
Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: afercia <[email protected]>
  • Loading branch information
5 people authored Jan 23, 2025
1 parent 0d35e9f commit c093971
Showing 1 changed file with 64 additions and 30 deletions.
94 changes: 64 additions & 30 deletions packages/block-editor/src/hooks/contrast-checker.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,94 @@
/**
* WordPress dependencies
*/
import { useState, useEffect } from '@wordpress/element';
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 getComputedStyle( node ) {
return node.ownerDocument.defaultView.getComputedStyle( node );
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 [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
const [ detectedColor, setDetectedColor ] = useState();
const [ detectedLinkColor, setDetectedLinkColor ] = useState();
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.
useEffect( () => {
useLayoutEffect( () => {
if ( ! blockEl ) {
return;
}
setDetectedColor( getComputedStyle( blockEl ).color );

const firstLinkElement = blockEl.querySelector( 'a' );
if ( firstLinkElement && !! firstLinkElement.innerText ) {
setDetectedLinkColor( getComputedStyle( firstLinkElement ).color );
}

let backgroundColorNode = blockEl;
let backgroundColor =
getComputedStyle( backgroundColorNode ).backgroundColor;
while (
backgroundColor === 'rgba(0, 0, 0, 0)' &&
backgroundColorNode.parentNode &&
backgroundColorNode.parentNode.nodeType ===
backgroundColorNode.parentNode.ELEMENT_NODE
) {
backgroundColorNode = backgroundColorNode.parentNode;
backgroundColor =
getComputedStyle( backgroundColorNode ).backgroundColor;
function updateColors() {
setColors( getBlockElementColors( blockEl ) );
}

setDetectedBackgroundColor( backgroundColor );
}, [ 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={ detectedBackgroundColor }
textColor={ detectedColor }
backgroundColor={ colors.backgroundColor }
textColor={ colors.textColor }
linkColor={ colors.linkColor }
enableAlphaChecker
linkColor={ detectedLinkColor }
/>
);
}

0 comments on commit c093971

Please sign in to comment.