Vanilla Components do not currently support this option out of the box, but there are solutions available with a little development on your side. One option is to cache color on the browser side. Here’s an example of code that does this:
import { COLORS } from '../constants';
const CACHE_KEY = 'color-cache';
export function getComponentId(...identifiers: unknown[]): string {
const ids: string[] = [];
for (const identifier of identifiers) {
// ignore undefined, null, function
switch (typeof identifier) {
case 'string':
ids.push(identifier);
break;
case 'number':
case 'boolean':
case 'bigint':
case 'symbol':
ids.push(String(identifier));
break;
case 'object':
ids.push(JSON.stringify(identifier));
break;
default:
console.warn(`${typeof identifier} not supported as part of componentId`);
}
}
return ids.join(':');
}
export function getCachedColorForLabel(componentId: string, label: string, index: number): string {
const key = `${CACHE_KEY}:${componentId}`;
const colorsJson = window.localStorage.getItem(key) ;
// If no colors have been chosen for this component yet initialize the cache and give the Nth color.
if (!colorsJson) {
const color = COLORS[index % COLORS.length];
window.localStorage.setItem(key, JSON.stringify({ [label]: color }));
return color;
}
const colors = JSON.parse(colorsJson);
// If a color has already been used for this component and this label use it again.
if (label in colors) {
return colors[label];
}
// Once we get to this point the cache has been instantiated but we have not seen this label before.
// Sequentially go over the colors and check if it's been used before.
// Once we find a suitable color store it in the cache and return it.
const usedColors = Object.values(colors);
for (const color of COLORS) {
if (!usedColors.includes(color)) {
window.localStorage.setItem(key, JSON.stringify({ [label]: color, ...colors }));
return color;
}
}
// If we get to this point all colors have been used. Just re-use a color based on the index.
const color = COLORS[index % COLORS.length];
window.localStorage.setItem(key, JSON.stringify({ [label]: color, ...colors }));
return color;
}