@wordpress/components
Version:
UI components for WordPress.
128 lines (108 loc) • 3.18 kB
JavaScript
/**
* External dependencies
*/
import memoize from 'memize';
import { colord, extend } from 'colord';
import namesPlugin from 'colord/plugins/names';
/** @type {HTMLDivElement} */
let colorComputationNode;
extend( [ namesPlugin ] );
/**
* Generating a CSS compliant rgba() color value.
*
* @param {string} hexValue The hex value to convert to rgba().
* @param {number} alpha The alpha value for opacity.
* @return {string} The converted rgba() color value.
*
* @example
* rgba( '#000000', 0.5 )
* // rgba(0, 0, 0, 0.5)
*/
export function rgba( hexValue = '', alpha = 1 ) {
return colord( hexValue ).alpha( alpha ).toRgbString();
}
/**
* @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 = colord( 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 );
return colord( background ).isLight() ? '#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';
}