TypeError: Cannot set property 'namedColors' of undefined
When I try to use this lib, I get that error: TypeError: Cannot set property 'namedColors' of undefined
(Regardless of whether I use the class or static method)
I can fix it by changing https://github.com/busterc/contrast-color/blob/main/lib/index.js#L211-L220 to:
function contrastColor({
bgColor = '#FFFFFF',
fgDarkColor = '#000000',
fgLightColor = '#FFFFFF',
defaultColor = '#000000',
threshold = 128,
customNamedColors = {},
} = {}) {
const namedColors = { ...NAMED_COLORS, ...customNamedColors }
const [
namedBgColor,
namedFgDarkColor,
namedFgLightColor,
namedDefaultColor,
] = [bgColor, fgDarkColor, fgLightColor, defaultColor].map(
(p) => namedColors[p],
)
(I'm just not calling this inside a function)
I am also seeing this error. @busterc can we expect a new version fixing this?
Hmm.. the tests don't fail and have 100% coverage. Can you attach a sample that is breaking?
https://stackblitz.com/edit/vitejs-vite-s2thdh is a pretty simple example that shows the failure.
What do you think about that sample @busterc
I have the same error when importing the function in a TypeScript Angular application. There is another workaround I would like to add for those facing the same problem:
contrastColor.call({}, { bgColor: '#ffffff' });
This effectively binds an empty object to the this scope before calling the function...
yah that works for me also @loedeman. It's a work around for now but I still hope @busterc can create a solution that doesn't change the calling api
Thanks for the insights, I will resolve this when I get the time to find a thorough fix. I believe this is actually an issue with Rollup (and perhaps other bundlers).
Thanks for the insights, I will resolve this when I get the time to find a thorough fix. I believe this is actually an issue with Rollup (and perhaps other bundlers).
Interesting thought. My repro is using esbuild and your build is using parcel. Where does rollup come into play?
@busterc Niche little library you got here! Thank you 😊 But this error is a problem so I ended up just copy/pasting your implementation..
To anyone who can do without the named colours:
const contrastColor = ({
bgColor = '#FFFFFF',
fgDarkColor = '#000000',
fgLightColor = '#FFFFFF',
defaultColor = '#000000',
threshold = 128,
} = {}) => {
const hexChars = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]
let bgColorArray = String(bgColor)
.toUpperCase()
.split('')
.filter(c => hexChars.includes(c))
switch (bgColorArray.length) {
case 3:
case 4:
bgColorArray = bgColorArray.slice(0, 3).map(c => `${c}${c}`)
break
case 6:
case 8:
bgColorArray = bgColorArray
.slice(0, 6)
.reduce((acc, curr, n, arr) => n % 2 ? [ ...acc, `${arr[n - 1]}${curr}` ] : acc, [])
break
default:
return defaultColor
}
const [ r, g, b ] = bgColorArray.map(h => parseInt(h, 16))
const yiq = (r * 299 + g * 587 + b * 114) / 1000
return yiq >= threshold ? fgDarkColor : fgLightColor
}
Same problem here, when using the library in a Vue component with TypeScript