From 2fd13b663ef82778e0f4fcfe963ff178fa0e0b6d Mon Sep 17 00:00:00 2001 From: Enrique Piqueras Date: Mon, 2 Dec 2019 08:05:54 -0800 Subject: [PATCH] Use Colors: Add text color detection support. (#18547) * Use Colors: Add text color detection support. * Use Colors: Support specific selectors for color detection. * Use Colors: Pass down refs to contrast checker to avoid stale values. * Heading: Detect inherited text color for contrast checking. --- .../src/components/colors/use-colors.js | 130 ++++++++++++------ packages/block-library/src/heading/edit.js | 6 +- 2 files changed, 90 insertions(+), 46 deletions(-) diff --git a/packages/block-editor/src/components/colors/use-colors.js b/packages/block-editor/src/components/colors/use-colors.js index 51b0b82ba5748..7aea89c4cd4ab 100644 --- a/packages/block-editor/src/components/colors/use-colors.js +++ b/packages/block-editor/src/components/colors/use-colors.js @@ -3,7 +3,7 @@ */ import memoize from 'memize'; import classnames from 'classnames'; -import { map, kebabCase, camelCase, startCase } from 'lodash'; +import { map, kebabCase, camelCase, castArray, startCase } from 'lodash'; /** * WordPress dependencies @@ -48,7 +48,8 @@ const ColorPanel = ( { colorSettings, colorPanelProps, contrastCheckers, - detectedBackgroundColor, + detectedBackgroundColorRef, + detectedColorRef, panelChildren, } ) => ( - contrastCheckers && - ( Array.isArray( contrastCheckers ) ? - contrastCheckers.some( - ( { backgroundColor } ) => backgroundColor === true - ) : - contrastCheckers.backgroundColor === true ) && - withFallbackStyles( ( node, { querySelector } ) => { - if ( querySelector ) { - node = node.parentNode.querySelector( querySelector ); - } - let backgroundColor = getComputedStyle( node ).backgroundColor; - while ( backgroundColor === 'rgba(0, 0, 0, 0)' && node.parentNode ) { - node = node.parentNode; - backgroundColor = getComputedStyle( node ).backgroundColor; + const detectedColorRef = useRef(); + const ColorDetector = useMemo( () => { + let needsBackgroundColor = false; + let needsColor = false; + for ( const { backgroundColor, textColor } of castArray( contrastCheckers ) ) { + if ( ! needsBackgroundColor ) { + needsBackgroundColor = backgroundColor === true; + } + if ( ! needsColor ) { + needsColor = textColor === true; + } + if ( needsBackgroundColor && needsColor ) { + break; + } + } + return ( + ( needsBackgroundColor || needsColor ) && + withFallbackStyles( + ( + node, + { + querySelector, + backgroundColorSelector = querySelector, + textColorSelector = querySelector, + } + ) => { + let backgroundColorNode = node; + let textColorNode = node; + if ( backgroundColorSelector ) { + backgroundColorNode = node.parentNode.querySelector( + backgroundColorSelector + ); + } + if ( textColorSelector ) { + textColorNode = node.parentNode.querySelector( textColorSelector ); + } + let backgroundColor; + const color = getComputedStyle( textColorNode ).color; + if ( needsBackgroundColor ) { + backgroundColor = getComputedStyle( backgroundColorNode ) + .backgroundColor; + while ( + backgroundColor === 'rgba(0, 0, 0, 0)' && + backgroundColorNode.parentNode + ) { + backgroundColorNode = backgroundColorNode.parentNode; + backgroundColor = getComputedStyle( backgroundColorNode ) + .backgroundColor; + } + } + detectedBackgroundColorRef.current = backgroundColor; + detectedColorRef.current = color; + return { backgroundColor, color }; } - detectedBackgroundColorRef.current = backgroundColor; - return { backgroundColor }; - } )( () => <> ), - [ - colorConfigs.reduce( - ( acc, colorConfig ) => - `${ acc } | ${ attributes[ colorConfig.name ] } | ${ - attributes[ camelCase( `custom ${ colorConfig.name }` ) ] - }`, - '' - ), - ...deps, - ] - ); + )( () => <> ) + ); + }, [ + colorConfigs.reduce( + ( acc, colorConfig ) => + `${ acc } | ${ attributes[ colorConfig.name ] } | ${ + attributes[ camelCase( `custom ${ colorConfig.name }` ) ] + }`, + '' + ), + ...deps, + ] ); return useMemo( () => { const colorSettings = {}; @@ -249,9 +290,9 @@ export default function __experimentalUseColors( const customColor = attributes[ camelCase( `custom ${ name }` ) ]; // We memoize the non-primitives to avoid unnecessary updates // when they are used as props for other components. - const _color = ! customColor ? - colors.find( ( __color ) => __color.slug === color ) : - undefined; + const _color = customColor ? + undefined : + colors.find( ( __color ) => __color.slug === color ); acc[ componentName ] = createComponent( name, property, @@ -261,7 +302,9 @@ export default function __experimentalUseColors( customColor ); acc[ componentName ].displayName = componentName; - acc[ componentName ].color = customColor ? customColor : ( _color && _color.color ); + acc[ componentName ].color = customColor ? + customColor : + _color && _color.color; acc[ componentName ].slug = color; acc[ componentName ].setColor = createSetColor( name, colors ); @@ -287,7 +330,8 @@ export default function __experimentalUseColors( colorSettings, colorPanelProps, contrastCheckers, - detectedBackgroundColor: detectedBackgroundColorRef.current, + detectedBackgroundColorRef, + detectedColorRef, panelChildren, }; return { @@ -296,7 +340,7 @@ export default function __experimentalUseColors( InspectorControlsColorPanel: ( ), - BackgroundColorDetector, + ColorDetector, }; - }, [ attributes, setAttributes, detectedBackgroundColorRef.current, ...deps ] ); + }, [ attributes, setAttributes, ...deps ] ); } diff --git a/packages/block-library/src/heading/edit.js b/packages/block-library/src/heading/edit.js index 0f7393fde7e66..fd7b336ba1afd 100644 --- a/packages/block-library/src/heading/edit.js +++ b/packages/block-library/src/heading/edit.js @@ -29,10 +29,10 @@ function HeadingEdit( { onReplace, className, } ) { - const { TextColor, InspectorControlsColorPanel, BackgroundColorDetector } = __experimentalUseColors( + const { TextColor, InspectorControlsColorPanel, ColorDetector } = __experimentalUseColors( [ { name: 'textColor', property: 'color' } ], { - contrastCheckers: { backgroundColor: true }, + contrastCheckers: { backgroundColor: true, textColor: true }, }, [] ); @@ -56,7 +56,7 @@ function HeadingEdit( { { InspectorControlsColorPanel } - +