UNPKG

@wordpress/components

Version:
100 lines (82 loc) 2.71 kB
/** * External dependencies */ import memoize from 'memize'; import tinycolor from 'tinycolor2'; /** @type {HTMLDivElement} */ let colorComputationNode; /** * @return {HTMLDivElement | undefined} The HTML element for color computation. */ function getColorComputationNode() { if ( typeof document === 'undefined' ) return; if ( ! colorComputationNode ) { // Create a temporary element for style computation. const el = document.createElement( 'div' ); el.setAttribute( 'data-g2-color-computation-node', '' ); // Inject for window computed style. document.body.appendChild( el ); colorComputationNode = el; } return colorComputationNode; } /** * @param {string | unknown} value * * @return {boolean} Whether the value is a valid color. */ function isColor( value ) { if ( typeof value !== 'string' ) return false; const test = tinycolor( value ); return test.isValid(); } /** * Retrieves the computed background color. This is useful for getting the * value of a CSS variable color. * * @param {string | unknown} backgroundColor The background color to compute. * * @return {string} The computed background color. */ function _getComputedBackgroundColor( backgroundColor ) { if ( typeof backgroundColor !== 'string' ) return ''; if ( isColor( backgroundColor ) ) return backgroundColor; if ( ! backgroundColor.includes( 'var(' ) ) return ''; if ( typeof document === 'undefined' ) return ''; // Attempts to gracefully handle CSS variables color values. const el = getColorComputationNode(); if ( ! el ) return ''; el.style.background = backgroundColor; // Grab the style const computedColor = window?.getComputedStyle( el ).background; // Reset el.style.background = ''; return computedColor || ''; } const getComputedBackgroundColor = memoize( _getComputedBackgroundColor ); /** * Get the text shade optimized for readability, based on a background color. * * @param {string | unknown} backgroundColor The background color. * * @return {string} The optimized text color (black or white). */ export function getOptimalTextColor( backgroundColor ) { const background = getComputedBackgroundColor( backgroundColor ); const isReadableWithBlackText = tinycolor.isReadable( background, '#000000' ); return isReadableWithBlackText ? '#000000' : '#ffffff'; } /** * Get the text shade optimized for readability, based on a background color. * * @param {string | unknown} backgroundColor The background color. * * @return {string} The optimized text shade (dark or light). */ export function getOptimalTextShade( backgroundColor ) { const result = getOptimalTextColor( backgroundColor ); return result === '#000000' ? 'dark' : 'light'; }