diff --git a/src/components/LabelCustomColor/LabelCustomColor.stories.mdx b/src/components/LabelCustomColor/LabelCustomColor.stories.mdx deleted file mode 100644 index 709505b..0000000 --- a/src/components/LabelCustomColor/LabelCustomColor.stories.mdx +++ /dev/null @@ -1,56 +0,0 @@ -import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks'; -import { LabelCustomColor } from './LabelCustomColor'; -import { - LabelCustomColorPicker, - LabelCustomColorExamples, - LabelCustomColorPerfTest, -} from './LabelCustomColor.stories.tsx'; -import GithubLink from '../../../.storybook/helpers/GithubLink'; - - - -# LabelCustomColor - -A wrapper for PatternFly's Label component that supports -arbitrary custom CSS colors (e.g. hexadecimal) and ensures text will always be readable. - -Applying an arbitrary color to a label presents the possibility of unreadable text due to insufficient color contrast. -This component solves the issue by applying the given color as a border color and using the -[tinycolor2](https://www.npmjs.com/package/tinycolor2) library to determine a lightened background color and darkened -text color (if necessary) in order to reach a color contrast ratio of at least 7:1. This ratio meets the "level AAA" -requirement of the [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced). - -**Note: This adjustment means that multiple labels with very similar colors (especially dark colors) may be adjusted to look almost identical.** - -All props of PatternFly's Label component are supported except the `variant` prop (only the default "filled" variant is supported). - -## Examples - -### Arbitrary Color Picker - -Choose any color here to see how the readability adjustments apply to it. - - - - - -### Color Examples - - - - - -### Performance Test - -The component maintains a global cache of the readability adjustments it makes for each color. -If labels of the same color are rendered multiple times on a page, each color only needs to be processed once. - - - - - -## Props - - - - diff --git a/src/components/LabelCustomColor/LabelCustomColor.stories.tsx b/src/components/LabelCustomColor/LabelCustomColor.stories.tsx deleted file mode 100644 index 8389a83..0000000 --- a/src/components/LabelCustomColor/LabelCustomColor.stories.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import * as React from 'react'; -import { SketchPicker } from 'react-color'; -import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; -import { - global_palette_black_1000 as black, - global_palette_black_500 as gray, - global_palette_blue_300 as blue, - global_palette_green_300 as green, - global_palette_cyan_300 as cyan, - global_palette_purple_600 as purple, - global_palette_gold_300 as gold, - global_palette_orange_300 as orange, -} from '@patternfly/react-tokens'; - -import { LabelCustomColor } from './LabelCustomColor'; - -export const LabelCustomColorPicker: React.FC = () => { - const [color, setColor] = React.useState('#4A90E2'); - return ( - <> - Label Text Here -
-
- setColor(newColor.hex)} /> - - ); -}; - -// Colors from https://sashamaps.net/docs/resources/20-colors/ with some colors removed for being too bright -// and PF global pallete colors used in place of their closest counterparts -const EXAMPLE_COLORS = [ - '#D95F55', // Red (PF red is weird because 100 is too close to Maroon and 50 is too bright) - green.value, // Green - gold.value, // Gold - blue.value, // Blue - orange.value, // Orange - purple.value, // Purple - cyan.value, // Cyan - '#F032E6', // Magenta - '#BFEF45', // Lime - '#469990', // Teal - '#9A6324', // Brown - '#800000', // Maroon - '#808000', // Olive - '#000075', // Navy - gray.value, // Gray - black.value, // Black -]; - -export const LabelCustomColorExamples: React.FC = () => ( - <> - {EXAMPLE_COLORS.map((color) => ( - - {color} - - ))} - -); - -export const LabelCustomColorPerfTest: React.FC = () => ( - <> - {[ - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ...EXAMPLE_COLORS, - ].map((color, index) => ( - - {color} - - ))} - -); diff --git a/src/components/LabelCustomColor/LabelCustomColor.tsx b/src/components/LabelCustomColor/LabelCustomColor.tsx deleted file mode 100644 index fe53ff2..0000000 --- a/src/components/LabelCustomColor/LabelCustomColor.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import * as React from 'react'; -import { Label, LabelProps } from '@patternfly/react-core'; -import tinycolor from 'tinycolor2'; - -// Omit the variant prop, we won't support the outline variant -export interface ILabelCustomColorProps extends Omit { - color: string; -} - -const globalColorCache: Record< - string, - { borderColor: string; backgroundColor: string; textColor: string } -> = {}; - -export const LabelCustomColor: React.FC = ({ color, ...props }) => { - const { borderColor, backgroundColor, textColor } = React.useMemo(() => { - if (globalColorCache[color]) return globalColorCache[color]; - // Lighten the background 30%, and lighten it further if necessary until it can support readable text - const bgColorObj = tinycolor(color).lighten(30); - const blackTextReadability = () => tinycolor.readability(bgColorObj, '#000000'); - const whiteTextReadability = () => tinycolor.readability(bgColorObj, '#FFFFFF'); - while (blackTextReadability() < 9 && whiteTextReadability() < 9) { - bgColorObj.lighten(5); - } - // Darken or lighten the text color until it is sufficiently readable - const textColorObj = tinycolor(color); - while (tinycolor.readability(bgColorObj, textColorObj) < 7) { - if (blackTextReadability() > whiteTextReadability()) { - textColorObj.darken(5); - } else { - textColorObj.lighten(5); - } - } - globalColorCache[color] = { - borderColor: color, - backgroundColor: bgColorObj.toString(), - textColor: textColorObj.toString(), - }; - return globalColorCache[color]; - }, [color]); - return ( -