chore: initial DSMMG v0.2 — refonte architecturale complète
Release / Release / open changeset PR (push) Has been cancelled
CI / Build, typecheck, test, a11y (push) Has been cancelled

Mise en place du Design System ManageMate Group v0.2 — refonte du
système de tokens (préfixe --mmg-color-*), 9 presets accent
user-themable validés WCAG AA, overlays Radix UI + Floating UI,
Storybook 8 + Vitest + axe-core en CI, doc Astro Starlight,
DESIGN.md (format google-labs-code) et exports tokens DTCG/CSS/
TS/Figma/Tailwind v3 et v4.

- 4 packages monorepo pnpm : @managemate/{tokens,css,react,icons}
- 62 composants React headless-first (Sheet, HoverCard, ContextMenu,
  Slider, ToggleGroup, AvatarGroup, UserCard, ProfileHeader,
  MetricCard, PricingCard, FeatureCard, Text/Display/Eyebrow/Lead…)
- Lint contraste WCAG : 37/37 paires AA, branché CI
- Toast pile Sonner-style avec ResizeObserver
- Theming user (9 presets) sans casser sémantique fixe
- Identité Synapse (rose #D12B6A) préservée

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dinawo
2026-05-04 22:07:57 +02:00
parent 5e019857fc
commit 62317f2ad7
172 changed files with 31397 additions and 1 deletions
+196
View File
@@ -0,0 +1,196 @@
#!/usr/bin/env node
/**
* @managemate/tokens — build pipeline
*
* Source de vérité unique : src/tokens.json (format W3C DTCG).
* Génère :
* - dist/tokens.css : CSS custom properties --mmg-color-*
* - dist/tokens.js / .d.ts: objet JS/TS pour consommation programmatique
* - dist/tokens.cjs : CommonJS
* - dist/figma-tokens.json: format Tokens Studio pour sync Figma
*/
import StyleDictionary from "style-dictionary";
import { mkdir, writeFile, readFile } from "node:fs/promises";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { existsSync } from "node:fs";
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = __dirname;
const DIST = join(ROOT, "dist");
const SOURCE = join(ROOT, "src", "tokens.json");
if (!existsSync(DIST)) await mkdir(DIST, { recursive: true });
// — Style Dictionary config ————————————————————————————————————
const sd = new StyleDictionary({
source: [SOURCE],
log: { warnings: "warn", verbosity: "default" },
platforms: {
css: {
transformGroup: "css",
buildPath: "dist/",
files: [
{
destination: "tokens.css",
format: "css/variables",
options: {
outputReferences: false,
selector: ":root",
},
},
],
prefix: "mmg",
},
js: {
transformGroup: "js",
buildPath: "dist/",
files: [
{
destination: "tokens.js",
format: "javascript/esm",
},
{
destination: "tokens.cjs",
format: "javascript/module",
},
{
destination: "tokens.d.ts",
format: "typescript/es6-declarations",
},
],
prefix: "mmg",
},
},
});
await sd.cleanAllPlatforms();
await sd.buildAllPlatforms();
// — Figma Tokens Studio export ————————————————————————————————————
// Plugin Tokens Studio attend un format proche de DTCG mais avec une
// structure aplatie : { "color/neutral/50": { "value": "...", "type": "color" } }
const dtcg = JSON.parse(await readFile(SOURCE, "utf8"));
function flatten(obj, prefix = "") {
const out = {};
for (const [k, v] of Object.entries(obj)) {
if (k.startsWith("$")) continue;
const path = prefix ? `${prefix}/${k}` : k;
if (v && typeof v === "object" && "$value" in v) {
out[path] = { value: v.$value, type: v.$type };
} else if (v && typeof v === "object") {
Object.assign(out, flatten(v, path));
}
}
return out;
}
const figmaTokens = {
global: flatten(dtcg),
$themes: [],
$metadata: {
tokenSetOrder: ["global"],
generatedAt: new Date().toISOString(),
generatedBy: "@managemate/tokens build.mjs",
},
};
await writeFile(join(DIST, "figma-tokens.json"), JSON.stringify(figmaTokens, null, 2));
// — Tailwind v3 export (theme.extend JSON) ————————————————————————
function buildTailwindV3() {
const colors = {};
for (const [name, ramp] of Object.entries(dtcg.color ?? {})) {
if (!ramp || typeof ramp !== "object") continue;
const shades = {};
for (const [shade, val] of Object.entries(ramp)) {
if (val && typeof val === "object" && "$value" in val) {
shades[shade] = val.$value;
}
}
if (Object.keys(shades).length > 0) colors[name] = shades;
}
const spacing = {};
for (const [k, v] of Object.entries(dtcg.spacing ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
spacing[`mmg-${k}`] = v.$value;
}
}
const radius = {};
for (const [k, v] of Object.entries(dtcg.radius ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
radius[`mmg-${k}`] = v.$value;
}
}
const fontSize = {};
for (const [k, v] of Object.entries(dtcg.fontSize ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
fontSize[`mmg-${k}`] = v.$value;
}
}
return {
theme: {
extend: {
colors: { mmg: colors },
spacing,
borderRadius: radius,
fontSize,
},
},
};
}
await writeFile(
join(DIST, "tailwind.config.json"),
JSON.stringify(buildTailwindV3(), null, 2),
);
// — Tailwind v4 export (@theme CSS block) ————————————————————————
function buildTailwindV4() {
const lines = ["/* DSMMG tokens — Tailwind v4 @theme block. */", "@theme {"];
// Colors
for (const [name, ramp] of Object.entries(dtcg.color ?? {})) {
if (!ramp || typeof ramp !== "object") continue;
for (const [shade, val] of Object.entries(ramp)) {
if (val && typeof val === "object" && "$value" in val) {
lines.push(` --color-mmg-${name}-${shade}: ${val.$value};`);
}
}
}
// Spacing
for (const [k, v] of Object.entries(dtcg.spacing ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
lines.push(` --spacing-mmg-${k}: ${v.$value};`);
}
}
// Radius
for (const [k, v] of Object.entries(dtcg.radius ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
lines.push(` --radius-mmg-${k}: ${v.$value};`);
}
}
// Font sizes
for (const [k, v] of Object.entries(dtcg.fontSize ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
lines.push(` --text-mmg-${k}: ${v.$value};`);
}
}
// Durations
for (const [k, v] of Object.entries(dtcg.duration ?? {})) {
if (v && typeof v === "object" && "$value" in v) {
lines.push(` --animate-duration-mmg-${k}: ${v.$value};`);
}
}
lines.push("}");
return lines.join("\n") + "\n";
}
await writeFile(join(DIST, "tailwind.css"), buildTailwindV4());
console.log(`✓ Tokens built → ${DIST}`);
console.log(` - tokens.css (CSS custom properties)`);
console.log(` - tokens.{js,cjs,d.ts} (ESM / CJS / TypeScript)`);
console.log(` - figma-tokens.json (Tokens Studio for Figma sync)`);
console.log(` - tailwind.config.json (Tailwind v3 theme.extend)`);
console.log(` - tailwind.css (Tailwind v4 @theme block)`);