Skip to content

Commit f35da15

Browse files
committed
Constrain to accessible contrast
1 parent 018bded commit f35da15

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

packages/gui/src/lib/color.ts

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,89 @@
1-
import { isBoolean, isNumber, isObject, isString, sample } from 'lodash-es'
1+
import {
2+
cloneDeep,
3+
isBoolean,
4+
isNumber,
5+
isObject,
6+
isString,
7+
sample,
8+
} from 'lodash-es'
9+
import getContrast from 'get-contrast'
210
import { ThemeColor } from '../components/primitives/ColorPicker/PalettePicker'
311
import { RegenOptions } from '../components/schemas/types'
412
import { Color } from '../types/css'
13+
import { themeGet } from './theme'
14+
15+
const CONTRAST_THRESHOLD = 4.5
16+
const CONTRAST_PROPERTY_MAP: Record<string, string> = {
17+
color: 'backgroundColor',
18+
backgroundColor: 'color',
19+
}
20+
21+
const getColorToContrastWith = (
22+
property: string,
23+
ruleset: Record<string, any>,
24+
theme?: any
25+
) => {
26+
const valueOrPath = ruleset[CONTRAST_PROPERTY_MAP[property]]
27+
return themeGet({
28+
theme,
29+
path: valueOrPath.path || valueOrPath,
30+
property: 'color',
31+
})
32+
}
33+
34+
const hasContrastToCheck = (
35+
property?: string,
36+
ruleset?: Record<string, any>,
37+
theme?: any
38+
) => {
39+
if (!property || !ruleset) {
40+
return false
41+
}
42+
43+
return !!getColorToContrastWith(property, ruleset, theme)
44+
}
545

646
export function randomColor({
747
theme,
848
ruleset,
949
property,
1050
}: RegenOptions<Color | ThemeColor>) {
11-
console.log('!!!!', ruleset, property)
12-
if (theme && theme.colors) {
13-
const path = sample(Object.keys(flatten(theme.colors)))
51+
if (!theme?.colors) {
52+
return randomHexColor()
53+
}
54+
55+
const allColors = cloneDeep(theme.colors)
56+
// @ts-ignore
57+
delete allColors.modes
1458

15-
return path
59+
const colors = flatten(allColors)
60+
61+
if (!hasContrastToCheck(property, ruleset, theme)) {
62+
return sample(Object.keys(colors))
1663
}
1764

18-
return randomHexColor()
65+
const colorToContrastWith = getColorToContrastWith(property!, ruleset, theme)
66+
const colorsWithContrast = Object.entries(colors).reduce(
67+
(acc: string[], curr) => {
68+
const [path, value] = curr
69+
70+
try {
71+
if (
72+
getContrast.ratio(value, colorToContrastWith) >= CONTRAST_THRESHOLD
73+
) {
74+
console.log(getContrast.ratio(value, colorToContrastWith))
75+
return [...acc, path]
76+
}
77+
} catch (e) {}
78+
79+
return acc
80+
},
81+
[]
82+
)
83+
84+
return colorsWithContrast.length
85+
? sample(colorsWithContrast)
86+
: sample(Object.keys(colors))
1987
}
2088

2189
export function randomHexColor() {

packages/gui/src/types/modules.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
declare module 'culori'
22
declare module 'escape-html'
3+
declare module 'get-contrast'

0 commit comments

Comments
 (0)