@rojaostudio/ds-core 1.1.0-next.1 → 1.1.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1102,6 +1102,31 @@ function rdsContrast(theme, mode, fg, bg) {
1102
1102
  if (!/^#[0-9a-f]{6}$/i.test(a) || !/^#[0-9a-f]{6}$/i.test(c)) return null;
1103
1103
  return contrastRatio(a, c);
1104
1104
  }
1105
+ var isColourRef = (v) => /^[a-z][a-z0-9-]*\/[a-z]?\d+$/i.test(v);
1106
+ function rdsThemeFromTable(table) {
1107
+ var _a;
1108
+ const out = { light: {}, dark: {}, brand: {} };
1109
+ const problems = [];
1110
+ for (const mode of ["light", "dark", "brand"]) {
1111
+ const roles = (_a = table.modes) == null ? void 0 : _a[mode];
1112
+ if (!roles) {
1113
+ problems.push(`mode "${mode}" is missing`);
1114
+ continue;
1115
+ }
1116
+ for (const [role] of ROLES) {
1117
+ const ref2 = roles[role];
1118
+ if (ref2 === void 0) problems.push(`${mode}: role "${role}" is missing`);
1119
+ else if (isColourRef(ref2)) {
1120
+ const value = table.primitives[ref2];
1121
+ if (value === void 0) problems.push(`${mode}: "${role}" points to unknown primitive "${ref2}"`);
1122
+ else out[mode][roleVar(role)] = value.toLowerCase();
1123
+ } else out[mode][roleVar(role)] = ref2;
1124
+ }
1125
+ }
1126
+ if (problems.length) throw new Error(`rdsThemeFromTable(${table.name}):
1127
+ ${problems.join("\n ")}`);
1128
+ return out;
1129
+ }
1105
1130
 
1106
1131
  // generate/emitCss.ts
1107
1132
  var SECTIONS = [
@@ -1323,4 +1348,4 @@ neutral 50 ${neutral[50]} \xB7 500 ${neutral[500]} \xB7 900 ${neutral[900]}
1323
1348
  `;
1324
1349
  }
1325
1350
 
1326
- export { ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, refToHex, relativeLuminance, resolveTheme, roleVar };
1351
+ export { ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar };
@@ -28,6 +28,19 @@ type RdsCssOptions = {
28
28
  declare function emitRdsCss(theme: RdsTheme, opts?: RdsCssOptions): string;
29
29
  /** Contrast of a role pair in one mode (alpha colours are not measured: they depend on what is below). */
30
30
  declare function rdsContrast(theme: RdsTheme, mode: RdsMode, fg: string, bg: string): number | null;
31
+ /**
32
+ * A brand as drawn in the [RDS] Base Tokens file: for each theme mode, every role points to a primitive of the
33
+ * [RDS] Primitives library by name ("accyan/400"), and `primitives` holds the colour Figma resolves for each.
34
+ * Exported by `figma/export-brand.js`. The theme comes out one to one with the Figma brand mode.
35
+ */
36
+ type RdsBrandTable = {
37
+ $schema?: "rds-brand-table/1";
38
+ name: string;
39
+ primitives: Record<string, string>;
40
+ modes: Record<RdsMode, Record<string, string>>;
41
+ };
42
+ /** The theme of a brand table. Fails on a missing role or an unknown primitive, listing them all. */
43
+ declare function rdsThemeFromTable(table: RdsBrandTable): RdsTheme;
31
44
 
32
45
  /**
33
46
  * emitCss.ts — formata o output do generateTheme num theme.css legível.
@@ -110,4 +123,4 @@ declare function isNeutralBrand(def: {
110
123
  palettes?: PaletteDefs;
111
124
  }): boolean;
112
125
 
113
- export { BrandDef, type ClaudeMdOptions, type ClaudeMdTarget, ROLES as RDS_ROLES, type RdsCssOptions, type RdsMode, type RdsTheme, SCALE_STEPS, type Scale, type ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, refToHex, relativeLuminance, roleVar };
126
+ export { BrandDef, type ClaudeMdOptions, type ClaudeMdTarget, ROLES as RDS_ROLES, type RdsBrandTable, type RdsCssOptions, type RdsMode, type RdsTheme, SCALE_STEPS, type Scale, type ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, rdsThemeFromTable, refToHex, relativeLuminance, roleVar };
package/dist/generate.js CHANGED
@@ -1,3 +1,3 @@
1
- export { ROLES as RDS_ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-CFOS2RAD.js';
1
+ export { ROLES as RDS_ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-DZAJKHNW.js';
2
2
  import './chunk-FRWRLCYM.js';
3
3
  import './chunk-ORMEWXMH.js';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { G as GenResult, R as ResolvedTheme, T as TokenMap, g as generateTheme, r as resolveTheme } from './generateTheme-CUfNpsKs.js';
2
- export { ClaudeMdOptions, ClaudeMdTarget, RDS_ROLES, RdsCssOptions, RdsMode, RdsTheme, SCALE_STEPS, Scale, ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, refToHex, relativeLuminance, roleVar } from './generate.js';
2
+ export { ClaudeMdOptions, ClaudeMdTarget, RDS_ROLES, RdsBrandTable, RdsCssOptions, RdsMode, RdsTheme, SCALE_STEPS, Scale, ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, rdsThemeFromTable, refToHex, relativeLuminance, roleVar } from './generate.js';
3
3
  export { A as Archetype, B as BrandColors, a as BrandDef, C as ColorRef, D as DarkStrategy, F as FontDef, P as PaletteRef, S as ScaleToken, T as TextStyle, b as TextStyleName, c as TypeScale } from './recipe.schema-Cq7e82nx.js';
4
4
  export { primitives, tokens } from './tokens.js';
5
5
  export { RecipeName, recipes } from './recipes.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { recipes } from './chunk-3QTDO2HW.js';
2
- export { ROLES as RDS_ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-CFOS2RAD.js';
2
+ export { ROLES as RDS_ROLES, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, onColor, rdsContrast, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-DZAJKHNW.js';
3
3
  export { primitives, tokens } from './chunk-FRWRLCYM.js';
4
4
  import './chunk-ORMEWXMH.js';
package/dist/themes.js CHANGED
@@ -1,4 +1,4 @@
1
- import { generateTheme } from './chunk-CFOS2RAD.js';
1
+ import { generateTheme } from './chunk-DZAJKHNW.js';
2
2
  import './chunk-FRWRLCYM.js';
3
3
  import { __spreadValues, __objRest } from './chunk-ORMEWXMH.js';
4
4
 
@@ -0,0 +1,51 @@
1
+ /* global figma */
2
+ // Exports one brand of the [RDS] Base Tokens file as a brand table for rdsThemeFromTable().
3
+ // Run inside the Base Tokens file with the Figma Plugin API (a plugin console or an agent with use_figma),
4
+ // after setting BRAND to the mode name of the `base` collection. The return value is the JSON to save.
5
+ //
6
+ // Each theme role is followed through the aliases of the `base` collection (in the brand's mode) down to a
7
+ // primitive of the [RDS] Primitives library, kept by name ("accyan/400") with the colour Figma resolves.
8
+ const BRAND = "rojao";
9
+
10
+ const cols = await figma.variables.getLocalVariableCollectionsAsync();
11
+ const base = cols.find((c) => c.name === "base");
12
+ const theme = cols.find((c) => c.name === "theme");
13
+ if (!base || !theme) throw new Error("open the [RDS] Base Tokens file");
14
+ const brandMode = base.modes.find((m) => m.name === BRAND);
15
+ if (!brandMode) throw new Error(`no brand "${BRAND}" in base: ${base.modes.map((m) => m.name).join(", ")}`);
16
+ const local = new Set(cols.map((c) => c.id));
17
+
18
+ const hex = (c) =>
19
+ "#" +
20
+ [c.r, c.g, c.b].map((x) => Math.round(x * 255).toString(16).padStart(2, "0")).join("") +
21
+ (c.a !== undefined && c.a < 1 ? Math.round(c.a * 255).toString(16).padStart(2, "0") : "");
22
+ const literal = (v, val) => (v.resolvedType === "COLOR" ? hex(val) : String(val));
23
+ const isAlias = (val) => val && typeof val === "object" && val.type === "VARIABLE_ALIAS";
24
+
25
+ const primitives = {};
26
+ async function resolve(v, themeMode) {
27
+ if (!local.has(v.variableCollectionId)) {
28
+ // A Primitives library variable: keep its name, record what it resolves to.
29
+ const val = Object.values(v.valuesByMode)[0];
30
+ if (isAlias(val)) return resolve(await figma.variables.getVariableByIdAsync(val.id), themeMode);
31
+ primitives[v.name] = literal(v, val);
32
+ return v.name;
33
+ }
34
+ const modeId = v.variableCollectionId === base.id ? brandMode.modeId
35
+ : v.variableCollectionId === theme.id ? themeMode : Object.keys(v.valuesByMode)[0];
36
+ const val = v.valuesByMode[modeId] ?? Object.values(v.valuesByMode)[0];
37
+ if (isAlias(val)) return resolve(await figma.variables.getVariableByIdAsync(val.id), themeMode);
38
+ return literal(v, val);
39
+ }
40
+
41
+ const modes = {};
42
+ for (const m of theme.modes) {
43
+ const roles = {};
44
+ for (const id of theme.variableIds) {
45
+ const v = await figma.variables.getVariableByIdAsync(id);
46
+ roles[v.name] = await resolve(v, m.modeId);
47
+ }
48
+ modes[m.name] = roles;
49
+ }
50
+ const sorted = Object.fromEntries(Object.entries(primitives).sort(([a], [b]) => a.localeCompare(b)));
51
+ return { $schema: "rds-brand-table/1", name: BRAND, primitives: sorted, modes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rojaostudio/ds-core",
3
- "version": "1.1.0-next.1",
3
+ "version": "1.1.0-next.2",
4
4
  "description": "O motor do Rojão DS — tokens, derivação de tema e emissores. Sem React, sem Tailwind, sem CSS.",
5
5
  "license": "MIT",
6
6
  "author": "Rojão Studio (https://rojao.studio)",
@@ -54,7 +54,8 @@
54
54
  "files": [
55
55
  "LICENSE",
56
56
  "README.md",
57
- "dist"
57
+ "dist",
58
+ "figma/export-brand.js"
58
59
  ],
59
60
  "devDependencies": {
60
61
  "eslint": "^9.18.0",