Skip to content

Commit

Permalink
Initial commit. Detecting the color of an A tag, if it exists and pas…
Browse files Browse the repository at this point in the history
…sing it to the ConstrastChecker

Added base logic and tests.
Very messy. To be optimzized. Don't hate me.
  • Loading branch information
ramonjd committed Jan 21, 2022
1 parent 210af7e commit 89651ee
Show file tree
Hide file tree
Showing 3 changed files with 304 additions and 33 deletions.
164 changes: 138 additions & 26 deletions packages/block-editor/src/components/contrast-checker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ import { useEffect } from '@wordpress/element';

extend( [ namesPlugin, a11yPlugin ] );

// @TODO move this to an external component.
function ContrastCheckerMessage( {
colordBackgroundColor,
colordTextColor,
colordLinkColor,
backgroundColor,
textColor,
linkColor,
shouldShowTransparencyWarning,
} ) {
let msg = '';
if ( shouldShowTransparencyWarning ) {
msg = __( 'Transparent text may be hard for people to read.' );
} else {
const backgroundColorBrightness = colordBackgroundColor.brightness();
msg =
colordBackgroundColor.brightness() < colordTextColor.brightness()
( colordTextColor &&
backgroundColorBrightness < colordTextColor.brightness() ) ||
( colordLinkColor &&
backgroundColorBrightness < colordLinkColor.brightness() )
? __(
'This color combination may be hard for people to read. Try using a darker background color and/or a brighter text color.'
)
Expand All @@ -45,7 +52,7 @@ function ContrastCheckerMessage( {
? __( 'Transparent text may be hard for people to read.' )
: __( 'This color combination may be hard for people to read.' );
speak( speakMsg );
}, [ backgroundColor, textColor ] );
}, [ backgroundColor, textColor, linkColor ] );

return (
<div className="block-editor-contrast-checker">
Expand All @@ -64,61 +71,166 @@ function ContrastChecker( {
backgroundColor,
fallbackBackgroundColor,
fallbackTextColor,
fallbackLinkColor,
fontSize, // font size value in pixels
isLargeText,
textColor,
linkColor,
enableAlphaChecker = false,
} ) {
if (
! ( backgroundColor || fallbackBackgroundColor ) ||
! ( textColor || fallbackTextColor )
) {
if ( ! ( backgroundColor || fallbackBackgroundColor ) ) {
return null;
}

const hasTextColor = !! ( textColor || fallbackTextColor );
const hasLinkColor = !! ( linkColor || fallbackLinkColor );

// Must have at least one text color.
if ( ! hasLinkColor && ! hasTextColor ) {
return null;
}

const colordBackgroundColor = colord(
backgroundColor || fallbackBackgroundColor
);
const colordTextColor = colord( textColor || fallbackTextColor );
const textColorHasTransparency = colordTextColor.alpha() < 1;
const colordLinkColor = colord( linkColor || fallbackLinkColor );
const textColorHasTransparency =
colordTextColor && colordTextColor.alpha() < 1;
const linkColorHasTransparency =
colordLinkColor && colordLinkColor.alpha() < 1;
const backgroundColorHasTransparency = colordBackgroundColor.alpha() < 1;

const hasTransparency =
textColorHasTransparency || backgroundColorHasTransparency;
const isReadable = colordTextColor.isReadable( colordBackgroundColor, {
level: 'AA',
size:
isLargeText || ( isLargeText !== false && fontSize >= 24 )
? 'large'
: 'small',
} );
backgroundColorHasTransparency ||
textColorHasTransparency ||
linkColorHasTransparency;

const textSize =
isLargeText || ( isLargeText !== false && fontSize >= 24 )
? 'large'
: 'small';

const isTextColorReadable =
hasTextColor &&
colordTextColor.isReadable( colordBackgroundColor, {
level: 'AA',
size: textSize,
} );

const isLinkColorReadable =
hasLinkColor &&
colordLinkColor.isReadable( colordBackgroundColor, {
level: 'AA',
size: textSize,
} );

// Don't show the message if the text is readable AND there's no transparency.
// This is the default.
if ( isReadable && ! hasTransparency ) {
return null;
if ( ! hasTransparency ) {
if ( ! hasLinkColor && isTextColorReadable ) {
return null;
}

if ( ! hasTextColor && isLinkColorReadable ) {
return null;
}

if ( isTextColorReadable && isLinkColorReadable ) {
return null;
}
}

if ( hasTransparency ) {
// If there's transparency, don't show the message if the alpha checker is disabled.
if ( ! enableAlphaChecker ) {
return null;
}

// If the background has transparency, don't show any warnings.
if (
backgroundColorHasTransparency &&
( ! textColorHasTransparency || ! linkColorHasTransparency )
) {
return null;
}

// Only text color.
if (
! hasLinkColor &&
isTextColorReadable &&
! textColorHasTransparency
) {
return null;
}

if (
! hasTextColor &&
isLinkColorReadable &&
! linkColorHasTransparency
) {
return null;
}

if (
// If there's transparency, don't show the message if the alpha checker is disabled.
! enableAlphaChecker ||
// If the alpha checker is enabled, we only show the warning if the text has transparency.
( isReadable && ! textColorHasTransparency )
isTextColorReadable &&
! textColorHasTransparency &&
isLinkColorReadable &&
! linkColorHasTransparency
) {
return null;
}
}

// Flag to warn about transparency only if the text is otherwise readable according to colord
// to ensure the readability warnings take precedence.
let shouldShowTransparencyWarning = false;

if ( ! hasLinkColor ) {
if ( isTextColorReadable && textColorHasTransparency ) {
shouldShowTransparencyWarning = true;
}
}

if ( ! hasTextColor ) {
if ( isLinkColorReadable && linkColorHasTransparency ) {
shouldShowTransparencyWarning = true;
}
}

if ( hasTextColor && hasLinkColor ) {
if ( linkColorHasTransparency && textColorHasTransparency ) {
shouldShowTransparencyWarning = true;
}

if (
isLinkColorReadable &&
linkColorHasTransparency &&
! textColorHasTransparency &&
isTextColorReadable
) {
shouldShowTransparencyWarning = true;
}

if (
isTextColorReadable &&
textColorHasTransparency &&
! linkColorHasTransparency &&
isLinkColorReadable
) {
shouldShowTransparencyWarning = true;
}
}

return (
<ContrastCheckerMessage
backgroundColor={ backgroundColor }
textColor={ textColor }
linkColor={ linkColor }
colordBackgroundColor={ colordBackgroundColor }
colordTextColor={ colordTextColor }
// Flag to warn about transparency only if the text is otherwise readable according to colord
// to ensure the readability warnings take precedence.
shouldShowTransparencyWarning={
isReadable && textColorHasTransparency
}
colordLinkColor={ colordLinkColor }
shouldShowTransparencyWarning={ shouldShowTransparencyWarning }
/>
);
}
Expand Down
Loading

0 comments on commit 89651ee

Please sign in to comment.