122 lines
3.9 KiB
JavaScript
122 lines
3.9 KiB
JavaScript
|
|
/**
|
||
|
|
* SUMI Design System — Style Dictionary configuration
|
||
|
|
*
|
||
|
|
* Source : tokens/primitive/*.json + tokens/semantic/*.json (W3C tokens spec)
|
||
|
|
* Outputs :
|
||
|
|
* - dist/tokens.css (concat of primitive + dark + light themes)
|
||
|
|
* - dist/tokens-primitive.css
|
||
|
|
* - dist/tokens-dark.css (selector :root, [data-theme="dark"])
|
||
|
|
* - dist/tokens-light.css (selector [data-theme="light"])
|
||
|
|
* - dist/tokens.ts (TS exports — values resolved against dark theme)
|
||
|
|
*
|
||
|
|
* SOURCE OF TRUTH = tokens/*.json
|
||
|
|
* Do NOT edit dist/* manually — they are generated. Edit tokens/* and run `npm run build:tokens`.
|
||
|
|
*
|
||
|
|
* Charte : ../../../Documents/TG__Talas_Group/05_EXPERIENCE_UTILISATEUR/CHARTE_GRAPHIQUE_TALAS.md
|
||
|
|
*/
|
||
|
|
|
||
|
|
import StyleDictionary from 'style-dictionary';
|
||
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
||
|
|
|
||
|
|
const PRIMITIVE_GLOB = 'tokens/primitive/**/*.json';
|
||
|
|
const SEMANTIC_DARK = 'tokens/semantic/dark.json';
|
||
|
|
const SEMANTIC_LIGHT = 'tokens/semantic/light.json';
|
||
|
|
|
||
|
|
/** Filter that keeps only tokens whose path starts with one of `prefixes`. */
|
||
|
|
const filterByPathPrefix = (prefixes) => (token) => prefixes.includes(token.path[0]);
|
||
|
|
|
||
|
|
/** Build primitive tokens — :root only (raw values shared by all themes). */
|
||
|
|
const buildPrimitive = async () => {
|
||
|
|
const sd = new StyleDictionary({
|
||
|
|
source: [PRIMITIVE_GLOB],
|
||
|
|
platforms: {
|
||
|
|
css: {
|
||
|
|
transformGroup: 'css',
|
||
|
|
buildPath: 'dist/',
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
destination: 'tokens-primitive.css',
|
||
|
|
format: 'css/variables',
|
||
|
|
options: { selector: ':root', outputReferences: false },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
await sd.buildAllPlatforms();
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Build a theme — semantic tokens with theme selector. */
|
||
|
|
const buildTheme = async (themeName, semanticFile, selector) => {
|
||
|
|
const sd = new StyleDictionary({
|
||
|
|
source: [PRIMITIVE_GLOB, semanticFile],
|
||
|
|
platforms: {
|
||
|
|
css: {
|
||
|
|
transformGroup: 'css',
|
||
|
|
buildPath: 'dist/',
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
destination: `tokens-${themeName}.css`,
|
||
|
|
format: 'css/variables',
|
||
|
|
filter: filterByPathPrefix(['sumi']),
|
||
|
|
options: { selector, outputReferences: true },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
await sd.buildAllPlatforms();
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Build TS exports — values resolved against dark theme (default). */
|
||
|
|
const buildTypeScript = async () => {
|
||
|
|
const sd = new StyleDictionary({
|
||
|
|
source: [PRIMITIVE_GLOB, SEMANTIC_DARK],
|
||
|
|
platforms: {
|
||
|
|
ts: {
|
||
|
|
transformGroup: 'js',
|
||
|
|
buildPath: 'dist/',
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
destination: 'tokens.ts',
|
||
|
|
format: 'javascript/es6',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
destination: 'tokens.d.ts',
|
||
|
|
format: 'typescript/es6-declarations',
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
await sd.buildAllPlatforms();
|
||
|
|
};
|
||
|
|
|
||
|
|
await buildPrimitive();
|
||
|
|
await buildTheme('dark', SEMANTIC_DARK, ':root, [data-theme="dark"]');
|
||
|
|
await buildTheme('light', SEMANTIC_LIGHT, '[data-theme="light"]');
|
||
|
|
await buildTypeScript();
|
||
|
|
|
||
|
|
// Concatenate the three CSS files into a single tokens.css
|
||
|
|
const header = `/**
|
||
|
|
* SUMI tokens — generated by style-dictionary.config.mjs
|
||
|
|
* Source: packages/design-system/tokens/
|
||
|
|
* Do NOT edit this file. Edit tokens/*.json and run \`npm run build:tokens\`.
|
||
|
|
*/
|
||
|
|
|
||
|
|
`;
|
||
|
|
const primitive = readFileSync('dist/tokens-primitive.css', 'utf8');
|
||
|
|
const dark = readFileSync('dist/tokens-dark.css', 'utf8');
|
||
|
|
const light = readFileSync('dist/tokens-light.css', 'utf8');
|
||
|
|
const stripGenerated = (s) => s.replace(/^\/\*\*\n \* Do not edit directly[\s\S]*?\*\/\n\n?/m, '');
|
||
|
|
writeFileSync(
|
||
|
|
'dist/tokens.css',
|
||
|
|
header + stripGenerated(primitive) + '\n' + stripGenerated(dark) + '\n' + stripGenerated(light),
|
||
|
|
);
|
||
|
|
|
||
|
|
console.log('\n✓ Style Dictionary build complete.');
|
||
|
|
console.log(' Output: packages/design-system/dist/');
|
||
|
|
console.log(' - tokens.css (unified)');
|
||
|
|
console.log(' - tokens-primitive.css, tokens-dark.css, tokens-light.css');
|
||
|
|
console.log(' - tokens.ts, tokens.d.ts');
|