master-co / css

The CSS Language and Framework
https://css.master.co
MIT License
1.75k stars 42 forks source link

✨ Figma (Experimental) #362

Open 1aron opened 2 weeks ago

1aron commented 2 weeks ago

Description

Screenshot 2024-06-17 at 12 25 52 AM

You can paste the following code in Figma’s Console to obtain Master CSS variables with different modes.

collections = {};

localCollections = await figma.variables.getLocalVariableCollectionsAsync();

async function getEqualValue(obj) {
    let firstValue = null;
    if(Object.keys(obj).length > 1)
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (firstValue === null) {
                    firstValue = obj[key];
                } else if (obj[key] !== firstValue) {
                    return;
                }
            }
        }
    return firstValue;
}

function rgbaToHex(rgba) {
  const r = Math.floor(rgba.r * 255).toString(16).padStart(2, '0');
  const g = Math.floor(rgba.g * 255).toString(16).padStart(2, '0');
  const b = Math.floor(rgba.b * 255).toString(16).padStart(2, '0');
  const a = rgba.a === 1 ? '' : Math.round(rgba.a * 255).toString(16).padStart(2, '0');
  return `#${r}${g}${b}${a}`;
}

for (const eachLocalCollection of localCollections) {
    const modeNameById = eachLocalCollection.modes.reduce((a, b) => {
        a[b.modeId] = b.name;
        return a;
    }, {});
    const modeLength = eachLocalCollection.modes.length
    const eachCollectionColors = {}
    for (const eachVariableId of eachLocalCollection.variableIds) {
        const variable = await figma.variables.getVariableByIdAsync(eachVariableId);
        if (variable && variable.resolvedType === 'COLOR') {
            const [colorName, level] = variable.name.split('/');
            const currentColors = Object.prototype.hasOwnProperty.call(eachCollectionColors, colorName)
                ? eachCollectionColors[colorName]
                : (eachCollectionColors[colorName] = {});
            let eachThemeColors = {}
            for(const eachModeId in variable.valuesByMode) {
                const modeName = modeNameById[eachModeId].toLowerCase()
                const suffix = (modeName !== 'default' && modeLength > 1) ? ('@' + modeName) : '';
                const values = variable.valuesByMode[eachModeId];
                let resolvedValue;
                if (values.type === 'VARIABLE_ALIAS') {
                    const aliasVariable = await figma.variables.getVariableByIdAsync(values.id);
                    resolvedValue = `$(${aliasVariable?.name.replace('/', '-')})`;
                } else {
                    resolvedValue = rgbaToHex(values);
                }
                modeLength > 1
                    ? eachThemeColors[suffix] = resolvedValue
                    : eachThemeColors = resolvedValue
            }
            const equalValue = await getEqualValue(eachThemeColors);
            if (equalValue) {
                eachThemeColors = equalValue;
            }
            currentColors[level || ''] = eachThemeColors;
            if (!level && Object.keys(currentColors).length === 1) {
                eachCollectionColors[colorName] = eachThemeColors;
            }
        }
    }
    collections[eachLocalCollection.name] = eachCollectionColors;
}

collections;

Mode Names:

Currently only color is supported. If you have a better version, please provide it. In the future, we will release Master CSS Figma as an official plugin.