@rojaostudio/ds-core 1.1.0-next.10 → 1.1.0-next.11
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.
- package/dist/{chunk-LP6UA4EW.js → chunk-D6HJEVJK.js} +143 -43
- package/dist/generate.d.ts +12 -2
- package/dist/generate.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/themes.js +1 -1
- package/package.json +1 -1
|
@@ -874,6 +874,16 @@ function stateFills(scale, fill, text, preferred) {
|
|
|
874
874
|
return (_a = ok[i]) != null ? _a : p;
|
|
875
875
|
});
|
|
876
876
|
}
|
|
877
|
+
var carry = (scale, fill, text, value) => contrastRatio(text, value) >= AA ? value : stateFills(scale, fill, text, [value])[0];
|
|
878
|
+
function over(top, below) {
|
|
879
|
+
const ch = (h, i) => parseInt(h.slice(1 + 2 * i, 3 + 2 * i), 16);
|
|
880
|
+
const a = top.length === 9 ? ch(top, 3) / 255 : 1;
|
|
881
|
+
return `#${[0, 1, 2].map((i) => Math.round(ch(top, i) * a + ch(below, i) * (1 - a)).toString(16).padStart(2, "0")).join("")}`;
|
|
882
|
+
}
|
|
883
|
+
var PLATE_MIN = 6;
|
|
884
|
+
function distinct(a, b) {
|
|
885
|
+
return contrastRatio(a, b) >= 1.5 || Math.abs(hexToHsl(a)[1] - hexToHsl(b)[1]) >= 40;
|
|
886
|
+
}
|
|
877
887
|
var defaultWarn = (m) => {
|
|
878
888
|
var _a;
|
|
879
889
|
return (_a = globalThis.console) == null ? void 0 : _a.warn(m);
|
|
@@ -989,7 +999,7 @@ var TINT_DEFAULT = 200;
|
|
|
989
999
|
var lighterStep = (s) => s - 100 ;
|
|
990
1000
|
var roleVar = (role) => `--${role.replaceAll("/", "-")}`;
|
|
991
1001
|
function generateRdsTheme(def, opts = {}) {
|
|
992
|
-
var _a, _b;
|
|
1002
|
+
var _a, _b, _c, _d;
|
|
993
1003
|
const warn = (_a = opts.warn) != null ? _a : defaultWarn;
|
|
994
1004
|
const where = `generateRdsTheme(${preview(def == null ? void 0 : def.name)})`;
|
|
995
1005
|
if (!(def == null ? void 0 : def.brand) || typeof def.brand !== "object") throw new Error(`${where}: brand is missing`);
|
|
@@ -1003,13 +1013,13 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1003
1013
|
const L = palette("blue");
|
|
1004
1014
|
const red = palette("red"), green = palette("green"), orange = palette("orange");
|
|
1005
1015
|
const teal = palette("teal"), purple = palette("purple");
|
|
1006
|
-
const lightBgs = [WHITE, N[100]];
|
|
1016
|
+
const lightBgs = [WHITE, N[100], N[200], A.scale[200]];
|
|
1007
1017
|
let heading;
|
|
1008
1018
|
if (b.heading) {
|
|
1009
1019
|
heading = ramp(b.heading, own).base;
|
|
1010
1020
|
if (!readsOn(heading, lightBgs)) {
|
|
1011
1021
|
const worst = Math.min(...lightBgs.map((bg) => contrastRatio(heading, bg)));
|
|
1012
|
-
warn(`generateRdsTheme(${def.name}): heading ${heading} is ${worst.toFixed(2)}:1 on surface/card
|
|
1022
|
+
warn(`generateRdsTheme(${def.name}): heading ${heading} is ${worst.toFixed(2)}:1 on surface/card, surface/page, surface/muted-strong or colors/accent/highlight (AA asks 4.5:1). Kept as given.`);
|
|
1013
1023
|
}
|
|
1014
1024
|
} else heading = readableFrom(P.base, P.scale, lightBgs, "darker", BLACK);
|
|
1015
1025
|
const invert = b.invert ? ramp(b.invert, own).base : WHITE;
|
|
@@ -1101,6 +1111,16 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1101
1111
|
"logo/inverse-signature": WHITE,
|
|
1102
1112
|
"social/ink": BLACK
|
|
1103
1113
|
};
|
|
1114
|
+
const single = !b.secondary;
|
|
1115
|
+
const K = single ? N : P.scale;
|
|
1116
|
+
if (single) {
|
|
1117
|
+
const steps = [900, 800, 700, 600, 500];
|
|
1118
|
+
const k = Math.max(0, steps.findIndex((s) => distinct(N[s], l["colors/secondary/default"])));
|
|
1119
|
+
l["colors/primary/default"] = N[steps[Math.min(k, 2)]];
|
|
1120
|
+
l["colors/primary/dark"] = N[steps[Math.min(k, 2) + 1]];
|
|
1121
|
+
l["colors/primary/active"] = N[steps[Math.min(k, 2) + 2]];
|
|
1122
|
+
l["colors/primary/light"] = N[500];
|
|
1123
|
+
}
|
|
1104
1124
|
for (const [fill, text] of [
|
|
1105
1125
|
["colors/primary/default", "text/on/primary"],
|
|
1106
1126
|
["colors/secondary/default", "text/on/secondary"],
|
|
@@ -1113,10 +1133,12 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1113
1133
|
["colors/state/neutral", "text/on/neutral"],
|
|
1114
1134
|
["surface/cover", "text/on/cover"],
|
|
1115
1135
|
["surface/lift/action", "text/on/lift-action"],
|
|
1116
|
-
["colors/primary/
|
|
1136
|
+
["colors/primary/default", "text/on/primary-strong"],
|
|
1117
1137
|
["surface/tint/default", "text/on/tint"]
|
|
1118
1138
|
]) l[text] = on(l[fill]);
|
|
1119
|
-
|
|
1139
|
+
for (const role of ["colors/primary/dark", "colors/primary/light"])
|
|
1140
|
+
l[role] = carry(K, l["colors/primary/default"], l["text/on/primary-strong"], l[role]);
|
|
1141
|
+
[l["colors/primary/active"]] = stateFills(K, l["colors/primary/default"], l["text/on/primary"], [l["colors/primary/active"]]);
|
|
1120
1142
|
[l["colors/secondary/hover"], l["colors/secondary/active"]] = stateFills(
|
|
1121
1143
|
S.scale,
|
|
1122
1144
|
l["colors/secondary/default"],
|
|
@@ -1125,9 +1147,9 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1125
1147
|
);
|
|
1126
1148
|
[l["colors/accent/hover"]] = stateFills(A.scale, l["colors/accent/default"], l["text/on/accent"], [l["colors/accent/hover"]]);
|
|
1127
1149
|
l["border/error"] = readableFrom(l["colors/state/error"], red, [l["surface/card"]], awayFrom(l["surface/card"]), BLACK, NON_TEXT);
|
|
1128
|
-
l["chart/series/1"] = readableFrom(P.scale[600], P.scale, [l["surface/card"]], awayFrom(l["surface/card"]), BLACK, NON_TEXT);
|
|
1129
|
-
l["logo/primary"] = l["
|
|
1130
|
-
l["logo/signature"] = l["
|
|
1150
|
+
l["chart/series/1"] = readableFrom(P.scale[600], P.scale, [l["surface/card"], l["surface/page"]], awayFrom(l["surface/card"]), BLACK, NON_TEXT);
|
|
1151
|
+
l["logo/primary"] = readableFrom(P.base, P.scale, [l["surface/card"], l["surface/page"], l["surface/panel"]], "darker", BLACK, NON_TEXT);
|
|
1152
|
+
l["logo/signature"] = l["logo/primary"];
|
|
1131
1153
|
l["logo/accent"] = l["colors/accent/logo"];
|
|
1132
1154
|
l["logo/accent-2"] = l["colors/secondary/default"];
|
|
1133
1155
|
l["logo/accent-3"] = l["colors/accent/default"];
|
|
@@ -1203,16 +1225,29 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1203
1225
|
"colors/state/neutral-strong": N[400],
|
|
1204
1226
|
"text/on/primary-subtle": black(30)
|
|
1205
1227
|
};
|
|
1228
|
+
if (single) {
|
|
1229
|
+
const steps = [200, 300, 100, 400];
|
|
1230
|
+
const s = (_b = steps.find((st) => distinct(N[st], d["colors/secondary/default"]))) != null ? _b : 200;
|
|
1231
|
+
d["colors/primary/default"] = N[s];
|
|
1232
|
+
d["colors/primary/dark"] = N[s === 100 ? 50 : s - 100];
|
|
1233
|
+
d["colors/primary/active"] = N[s + 100];
|
|
1234
|
+
d["colors/primary/light"] = N[s + 200];
|
|
1235
|
+
}
|
|
1236
|
+
d["surface/tint/default"] = readableFrom(d["surface/tint/default"], A.scale, [d["text/body"], d["text/muted"], d["colors/primary/default"]], "darker", N[900]);
|
|
1237
|
+
d["surface/tint/subtle"] = d["surface/tint/default"];
|
|
1238
|
+
d["colors/accent/highlight"] = readableFrom(d["colors/accent/highlight"], A.scale, [d["text/heading"]], "darker", N[900]);
|
|
1206
1239
|
for (const [fill, text] of [
|
|
1207
1240
|
["colors/primary/default", "text/on/primary"],
|
|
1208
1241
|
["colors/secondary/default", "text/on/secondary"],
|
|
1209
1242
|
["colors/accent/default", "text/on/accent"],
|
|
1210
1243
|
["colors/accent/mark", "text/on/accent-mark"],
|
|
1211
|
-
["colors/primary/
|
|
1244
|
+
["colors/primary/default", "text/on/primary-strong"],
|
|
1212
1245
|
["surface/tint/default", "text/on/tint"],
|
|
1213
1246
|
["surface/lift/action", "text/on/lift-action"]
|
|
1214
1247
|
]) d[text] = on(d[fill]);
|
|
1215
|
-
|
|
1248
|
+
for (const role of ["colors/primary/dark", "colors/primary/light"])
|
|
1249
|
+
d[role] = carry(K, d["colors/primary/default"], d["text/on/primary-strong"], d[role]);
|
|
1250
|
+
[d["colors/primary/active"]] = stateFills(K, d["colors/primary/default"], d["text/on/primary"], [d["colors/primary/active"]]);
|
|
1216
1251
|
[d["colors/secondary/hover"], d["colors/secondary/active"]] = stateFills(
|
|
1217
1252
|
S.scale,
|
|
1218
1253
|
d["colors/secondary/default"],
|
|
@@ -1220,16 +1255,26 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1220
1255
|
[d["colors/secondary/hover"], d["colors/secondary/active"]]
|
|
1221
1256
|
);
|
|
1222
1257
|
[d["colors/accent/hover"]] = stateFills(A.scale, d["colors/accent/default"], d["text/on/accent"], [d["colors/accent/hover"]]);
|
|
1223
|
-
d["border/error"] = readableFrom(
|
|
1258
|
+
d["border/error"] = readableFrom(red[400], red, [d["surface/card"]], awayFrom(d["surface/card"]), WHITE, NON_TEXT);
|
|
1224
1259
|
d["chart/series/1"] = readableFrom(P.scale[400], P.scale, [d["surface/card"]], awayFrom(d["surface/card"]), WHITE, NON_TEXT);
|
|
1225
|
-
|
|
1260
|
+
d["colors/state/error-strong"] = carry(red, l["colors/state/error"], l["text/on/error"], d["colors/state/error-strong"]);
|
|
1261
|
+
const ink0 = on(P.base);
|
|
1262
|
+
const plate = contrastRatio(ink0, P.base) >= PLATE_MIN ? P.base : readableFrom(P.base, P.scale, [ink0], ink0 === WHITE ? "darker" : "lighter", ink0 === WHITE ? BLACK : WHITE, PLATE_MIN);
|
|
1226
1263
|
const ink = on(plate);
|
|
1227
1264
|
const inkA = ink === WHITE ? white : black;
|
|
1228
1265
|
const antiInk = ink === WHITE ? black : white;
|
|
1229
1266
|
const lp = relativeLuminance(plate);
|
|
1230
1267
|
const isPlate = (c) => c.toLowerCase() === plate.toLowerCase();
|
|
1231
|
-
const plateCard = P.scale[800] && !isPlate(P.scale[800]) && contrastRatio(ink, P.scale[800]) >=
|
|
1232
|
-
const
|
|
1268
|
+
const plateCard = P.scale[800] && !isPlate(P.scale[800]) && contrastRatio(ink, P.scale[800]) >= PLATE_MIN ? P.scale[800] : (_c = SCALE_STEPS.map((st) => P.scale[st]).filter((c) => !!c && isHex(c) && !isPlate(c)).sort((a, b2) => Math.abs(relativeLuminance(a) - lp) - Math.abs(relativeLuminance(b2) - lp)).find((c) => contrastRatio(ink, c) >= PLATE_MIN)) != null ? _c : plate;
|
|
1269
|
+
const plateBgs = [plate, plateCard];
|
|
1270
|
+
const ov = plateBgs.every((bg) => contrastRatio(ink, over(inkA(20), bg)) >= AA) ? inkA : ink === WHITE ? black : white;
|
|
1271
|
+
const under = [...plateBgs, ...plateBgs.map((bg) => over(ov(10), bg))];
|
|
1272
|
+
const quiet = (pct, min = AA, bgs = under) => {
|
|
1273
|
+
for (let p = pct; p < 100; p += 5) if (bgs.every((bg) => contrastRatio(over(inkA(p), bg), bg) >= min)) return inkA(p);
|
|
1274
|
+
return ink;
|
|
1275
|
+
};
|
|
1276
|
+
const fieldBorder = quiet(60, NON_TEXT, plateBgs);
|
|
1277
|
+
const fieldAlpha = fieldBorder.length === 9 ? Math.round(parseInt(fieldBorder.slice(7), 16) / 255 * 100) : 100;
|
|
1233
1278
|
const br = {
|
|
1234
1279
|
"colors/primary/light": P.scale[300],
|
|
1235
1280
|
"colors/primary/default": ink,
|
|
@@ -1246,33 +1291,37 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1246
1291
|
"surface/card": plateCard,
|
|
1247
1292
|
"surface/panel": plate,
|
|
1248
1293
|
"border/default": inkA(20),
|
|
1249
|
-
"surface/tint/default":
|
|
1250
|
-
"surface/tint/strong":
|
|
1251
|
-
"surface/tint/subtle":
|
|
1294
|
+
"surface/tint/default": ov(10),
|
|
1295
|
+
"surface/tint/strong": ov(20),
|
|
1296
|
+
"surface/tint/subtle": ov(5),
|
|
1252
1297
|
"text/on/action-tonal": ink,
|
|
1253
1298
|
"text/on/primary": plate,
|
|
1254
1299
|
"text/on/secondary": plate,
|
|
1255
1300
|
"text/on/tint": ink,
|
|
1256
|
-
"surface/action/default":
|
|
1257
|
-
"surface/action/strong":
|
|
1301
|
+
"surface/action/default": ov(10),
|
|
1302
|
+
"surface/action/strong": ov(20),
|
|
1258
1303
|
"focus/ring": ink,
|
|
1259
1304
|
"focus/ring-inset": plate,
|
|
1260
1305
|
"surface/disabled": inkA(10),
|
|
1261
1306
|
"text/disabled": inkA(40),
|
|
1262
|
-
"text/muted":
|
|
1307
|
+
"text/muted": quiet(70),
|
|
1263
1308
|
"text/disabled-invert": antiInk(40),
|
|
1264
1309
|
"text/action": ink,
|
|
1265
|
-
"surface/lift/action":
|
|
1310
|
+
"surface/lift/action": ov(10),
|
|
1266
1311
|
"text/on/lift-action": ink,
|
|
1267
|
-
"surface/lift/action-strong":
|
|
1268
|
-
|
|
1269
|
-
"text/
|
|
1270
|
-
"
|
|
1271
|
-
"surface/muted
|
|
1272
|
-
"
|
|
1273
|
-
"border/strong
|
|
1312
|
+
"surface/lift/action-strong": ov(20),
|
|
1313
|
+
// The label of the neutral Button on the plate, whose fill is the ink: the plate colour.
|
|
1314
|
+
"text/on/primary-strong": plate,
|
|
1315
|
+
"text/subtle": quiet(60),
|
|
1316
|
+
"surface/muted": ov(10),
|
|
1317
|
+
"surface/muted-strong": ov(20),
|
|
1318
|
+
"border/strong": fieldBorder,
|
|
1319
|
+
"border/strong-hover": fieldAlpha + 20 < 100 ? inkA(fieldAlpha + 20) : ink,
|
|
1274
1320
|
"text/on/primary-subtle": inkA(30)
|
|
1275
1321
|
};
|
|
1322
|
+
for (const role of ["colors/primary/dark", "colors/primary/light"])
|
|
1323
|
+
br[role] = carry(P.scale, br["colors/primary/default"], br["text/on/primary-strong"], br[role]);
|
|
1324
|
+
br["colors/primary/dark"] = readableFrom(br["colors/primary/dark"], P.scale, [plateCard], awayFrom(plateCard), ink, NON_TEXT);
|
|
1276
1325
|
[br["colors/primary/active"]] = stateFills(P.scale, br["colors/primary/default"], br["text/on/primary"], [br["colors/primary/active"]]);
|
|
1277
1326
|
[br["colors/secondary/hover"], br["colors/secondary/active"]] = stateFills(
|
|
1278
1327
|
S.scale,
|
|
@@ -1280,7 +1329,18 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1280
1329
|
br["text/on/secondary"],
|
|
1281
1330
|
[br["colors/secondary/hover"], br["colors/secondary/active"]]
|
|
1282
1331
|
);
|
|
1283
|
-
const brandError = readableFrom(red[300], red,
|
|
1332
|
+
const brandError = readableFrom(red[300], red, plateBgs.slice().reverse(), awayFrom(plateCard), ink, NON_TEXT);
|
|
1333
|
+
const lightPlate = ink === BLACK;
|
|
1334
|
+
const plateOwn = {};
|
|
1335
|
+
for (const [st, rampOf] of [["error", red], ["success", green], ["info", L], ["warning", orange], ["neutral", N]]) {
|
|
1336
|
+
const from = lightPlate ? l : d;
|
|
1337
|
+
const soft = [`surface/${st}`, ...st === "error" ? ["surface/error-strong"] : []];
|
|
1338
|
+
for (const s of soft) plateOwn[s] = from[s];
|
|
1339
|
+
plateOwn[`text/${st}`] = readableFrom(from[`text/${st}`], rampOf, [...under, ...soft.map((s) => from[s])], awayFrom(plate), ink);
|
|
1340
|
+
}
|
|
1341
|
+
plateOwn["colors/accent/highlight"] = (_d = [d["colors/accent/highlight"], l["colors/accent/highlight"]].find((c) => contrastRatio(ink, c) >= AA)) != null ? _d : readableFrom(l["colors/accent/highlight"], A.scale, [ink], lightPlate ? "lighter" : "darker", ink === WHITE ? BLACK : WHITE);
|
|
1342
|
+
plateOwn["chart/series/1"] = readableFrom(d["chart/series/1"], P.scale, plateBgs, awayFrom(plate), ink, NON_TEXT);
|
|
1343
|
+
for (const logo of ["logo/primary", "logo/signature", "logo/accent", "logo/mono", "social/ink"]) plateOwn[logo] = ink;
|
|
1284
1344
|
const out = { light: {}, dark: {}, brand: {} };
|
|
1285
1345
|
const pick = (src, role) => {
|
|
1286
1346
|
var _a2;
|
|
@@ -1295,6 +1355,7 @@ function generateRdsTheme(def, opts = {}) {
|
|
|
1295
1355
|
out.brand[roleVar(role)] = pick(brandSrc, role);
|
|
1296
1356
|
}
|
|
1297
1357
|
out.brand[roleVar("border/error")] = brandError;
|
|
1358
|
+
for (const [role, v] of Object.entries(plateOwn)) out.brand[roleVar(role)] = v;
|
|
1298
1359
|
assertSafeTheme(out, where);
|
|
1299
1360
|
return out;
|
|
1300
1361
|
}
|
|
@@ -1385,15 +1446,54 @@ var RDS_CONTRAST_PAIRS = [
|
|
|
1385
1446
|
["text/on/info", "colors/state/info"],
|
|
1386
1447
|
["text/on/warning", "colors/state/warning"],
|
|
1387
1448
|
["text/on/neutral", "colors/state/neutral"],
|
|
1388
|
-
["text/error", "surface/error"]
|
|
1449
|
+
["text/error", "surface/error"],
|
|
1450
|
+
// The pairs the components join (packages/ds, styles/rds/components.css): the label of the neutral Button and
|
|
1451
|
+
// Badge on its fill and hovers, the inverse label (colors/primary/default) on the card, the pressed outline Button,
|
|
1452
|
+
// the Badge highlight, the selected entry, quiet text and state text where they are placed.
|
|
1453
|
+
["text/on/primary-strong", "colors/primary/default"],
|
|
1454
|
+
["text/on/primary-strong", "colors/primary/light"],
|
|
1455
|
+
["text/on/primary-strong", "colors/primary/active"],
|
|
1456
|
+
["colors/primary/default", "surface/card"],
|
|
1457
|
+
["colors/primary/default", "surface/tint/default"],
|
|
1458
|
+
["text/heading", "surface/muted-strong"],
|
|
1459
|
+
["text/heading", "colors/accent/highlight"],
|
|
1460
|
+
["text/body", "surface/tint/default"],
|
|
1461
|
+
["text/muted", "surface/tint/default"],
|
|
1462
|
+
["text/on/tint", "surface/tint/subtle"],
|
|
1463
|
+
["text/action", "surface/action/strong"],
|
|
1464
|
+
["text/muted", "surface/page"],
|
|
1465
|
+
["text/muted", "surface/panel"],
|
|
1466
|
+
["text/subtle", "surface/card"],
|
|
1467
|
+
["text/subtle", "surface/panel"],
|
|
1468
|
+
["text/error", "surface/card"],
|
|
1469
|
+
["text/error", "surface/page"],
|
|
1470
|
+
["text/error", "surface/error-strong"],
|
|
1471
|
+
["text/success", "surface/success"],
|
|
1472
|
+
["text/success", "surface/card"],
|
|
1473
|
+
["text/info", "surface/info"],
|
|
1474
|
+
["text/warning", "surface/warning"],
|
|
1475
|
+
["text/neutral", "surface/neutral"]
|
|
1476
|
+
];
|
|
1477
|
+
var RDS_NON_TEXT_PAIRS = [
|
|
1478
|
+
["border/strong", "surface/card"],
|
|
1479
|
+
["border/strong", "surface/page"],
|
|
1480
|
+
["border/error", "surface/card"],
|
|
1481
|
+
["focus/ring", "surface/page"],
|
|
1482
|
+
["focus/ring", "surface/card"],
|
|
1483
|
+
["logo/primary", "surface/card"],
|
|
1484
|
+
["logo/primary", "surface/page"],
|
|
1485
|
+
["logo/primary", "surface/panel"],
|
|
1486
|
+
["chart/series/1", "surface/card"],
|
|
1487
|
+
["chart/series/1", "surface/page"]
|
|
1389
1488
|
];
|
|
1390
1489
|
function rdsContrastReport(theme) {
|
|
1391
1490
|
const out = [];
|
|
1392
1491
|
for (const mode of ["light", "dark", "brand"])
|
|
1393
|
-
for (const [
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1492
|
+
for (const [pairs, min] of [[RDS_CONTRAST_PAIRS, AA], [RDS_NON_TEXT_PAIRS, NON_TEXT]])
|
|
1493
|
+
for (const [fg, bg] of pairs) {
|
|
1494
|
+
const ratio = rdsContrast(theme, mode, fg, bg);
|
|
1495
|
+
if (ratio !== null && ratio < min) out.push({ mode, fg, bg, ratio: Math.round(ratio * 100) / 100, min });
|
|
1496
|
+
}
|
|
1397
1497
|
return out;
|
|
1398
1498
|
}
|
|
1399
1499
|
var isColourRef = (v) => /^[a-z][a-z0-9-]*\/[a-z]?\d+$/i.test(v);
|
|
@@ -1470,8 +1570,8 @@ function rdsThemeFromTable(table, opts = {}) {
|
|
|
1470
1570
|
const fails = rdsContrastReport(out);
|
|
1471
1571
|
if (fails.length)
|
|
1472
1572
|
warn(
|
|
1473
|
-
`${where}: ${fails.length}
|
|
1474
|
-
` + fails.map((f) => `${f.mode}: ${f.fg} on ${f.bg} ${f.ratio}:1`).join("\n ")
|
|
1573
|
+
`${where}: ${fails.length} pair(s) below WCAG (4.5:1 text, 3:1 non-text)
|
|
1574
|
+
` + fails.map((f) => `${f.mode}: ${f.fg} on ${f.bg} ${f.ratio}:1 (min ${f.min}:1)`).join("\n ")
|
|
1475
1575
|
);
|
|
1476
1576
|
return out;
|
|
1477
1577
|
}
|
|
@@ -1553,10 +1653,10 @@ var CSS_FILE = /^[a-z0-9_@./-]+\.css$/i;
|
|
|
1553
1653
|
var CSS_URL = /^https?:\/\/[^\s"'`<>()\\]+$/i;
|
|
1554
1654
|
var INSTALL = /^(?:pnpm add|yarn add|bun add|npm install|npm i) @rojaostudio\/ds(?:@[a-z0-9][a-z0-9.+-]*)?$/;
|
|
1555
1655
|
var ROLE_DOCS = [
|
|
1556
|
-
{ role: "colors/primary/default", use: "
|
|
1557
|
-
{ role: "text/on/primary", use: "text/icon on the
|
|
1558
|
-
{ role: "colors/primary/active", use: "pressed
|
|
1559
|
-
{ role: "colors/secondary/default", use: "
|
|
1656
|
+
{ role: "colors/primary/default", use: "neutral ink fill: neutral Button and Badge, bars, Tooltip" },
|
|
1657
|
+
{ role: "text/on/primary", use: "text/icon on the neutral ink fill" },
|
|
1658
|
+
{ role: "colors/primary/active", use: "pressed neutral ink fill" },
|
|
1659
|
+
{ role: "colors/secondary/default", use: "action fill: the default Button, checkbox, switch (with `--text-on-secondary`)" },
|
|
1560
1660
|
{ role: "colors/accent/default", use: "highlight \u2014 sparingly (with `--text-on-accent`)" },
|
|
1561
1661
|
{ role: "surface/page", use: "page background" },
|
|
1562
1662
|
{ role: "surface/card", use: "cards" },
|
|
@@ -1665,7 +1765,7 @@ ${themeImport}
|
|
|
1665
1765
|
- ${opts.cssUrl ? `The theme is served from \`${opts.cssUrl}\`.` : `\`${cssFile}\` is the brand theme, generated \u2014 a file **you own**; commit it. Regenerate it
|
|
1666
1766
|
with \`npx rojao-ds init\` instead of editing it by hand.`}
|
|
1667
1767
|
- Dark mode: \`class="dark"\` on \`<html>\` (or any element). Light AND dark are first-class.
|
|
1668
|
-
- Brand plate: \`class="ds-plate"\` on a section paints it with the
|
|
1768
|
+
- Brand plate: \`class="ds-plate"\` on a section paints it with the brand color; the roles inside
|
|
1669
1769
|
flip so text and components stay legible.
|
|
1670
1770
|
|
|
1671
1771
|
## Components first
|
|
@@ -1700,7 +1800,7 @@ Brand's own variables (same value in every mode): ${own.map((v) => `\`${v}\``).j
|
|
|
1700
1800
|
- **Font:** \`font-family: var(${f.font})\` \u2014 never substitute.
|
|
1701
1801
|
|
|
1702
1802
|
## Rules (do / don't)
|
|
1703
|
-
- \u2705 Primary action = \`Button\` (
|
|
1803
|
+
- \u2705 Primary action = \`Button\` (tone action paints \`--colors-secondary-default\` + \`--text-on-secondary\`).
|
|
1704
1804
|
- \u2705 Page uses \`--surface-page\`; cards \`--surface-card\`; body text \`--text-body\`.
|
|
1705
1805
|
- \u2705 \`--colors-accent-default\` is the highlight \u2014 use it sparingly.
|
|
1706
1806
|
- \u2705 Spacing, radius and type come ONLY from the foundation tokens above.
|
|
@@ -1718,4 +1818,4 @@ Brand's own variables (same value in every mode): ${own.map((v) => `\`${v}\``).j
|
|
|
1718
1818
|
return text;
|
|
1719
1819
|
}
|
|
1720
1820
|
|
|
1721
|
-
export { RDS_CONTRAST_PAIRS, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, ROLES, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar };
|
|
1821
|
+
export { RDS_CONTRAST_PAIRS, RDS_NON_TEXT_PAIRS, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, ROLES, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar };
|
package/dist/generate.d.ts
CHANGED
|
@@ -62,13 +62,23 @@ declare function rdsContrast(theme: RdsTheme, mode: RdsMode, fg: string, bg: str
|
|
|
62
62
|
* alpha colour is skipped (its contrast depends on what is below).
|
|
63
63
|
*/
|
|
64
64
|
declare const RDS_CONTRAST_PAIRS: ReadonlyArray<readonly [string, string]>;
|
|
65
|
+
/**
|
|
66
|
+
* What is not text but has to be seen (WCAG 1.4.11, 3:1): the border of a field and of a field in error, the focus
|
|
67
|
+
* ring, the brand's logo and its chart series, on the surfaces they are placed on.
|
|
68
|
+
*/
|
|
69
|
+
declare const RDS_NON_TEXT_PAIRS: ReadonlyArray<readonly [string, string]>;
|
|
70
|
+
/** A pair below its minimum: 4.5:1 for text (RDS_CONTRAST_PAIRS), 3:1 for the rest (RDS_NON_TEXT_PAIRS). */
|
|
65
71
|
type RdsContrastFailure = {
|
|
66
72
|
mode: RdsMode;
|
|
67
73
|
fg: string;
|
|
68
74
|
bg: string;
|
|
69
75
|
ratio: number;
|
|
76
|
+
min: number;
|
|
70
77
|
};
|
|
71
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* The pairs of RDS_CONTRAST_PAIRS below WCAG AA (4.5:1) and of RDS_NON_TEXT_PAIRS below 3:1, mode by mode. Empty
|
|
80
|
+
* means every pair passes. A pair with an alpha colour is skipped (rdsContrast).
|
|
81
|
+
*/
|
|
72
82
|
declare function rdsContrastReport(theme: RdsTheme): RdsContrastFailure[];
|
|
73
83
|
/**
|
|
74
84
|
* A brand as drawn in the [RDS] Base Tokens file: for each theme mode, every role points to a primitive of the
|
|
@@ -218,4 +228,4 @@ declare function isNeutralBrand(def: {
|
|
|
218
228
|
palettes?: PaletteDefs;
|
|
219
229
|
}): boolean;
|
|
220
230
|
|
|
221
|
-
export { BrandDef, type ClaudeMdOptions, type ClaudeMdTarget, RDS_CONTRAST_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, type RdsBrandTable, type RdsContrastFailure, type RdsCssOptions, type RdsMode, type RdsTheme, type RdsThemeOptions, RdsValidationError, SCALE_STEPS, type Scale, type ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, roleVar };
|
|
231
|
+
export { BrandDef, type ClaudeMdOptions, type ClaudeMdTarget, RDS_CONTRAST_PAIRS, RDS_NON_TEXT_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, type RdsBrandTable, type RdsContrastFailure, type RdsCssOptions, type RdsMode, type RdsTheme, type RdsThemeOptions, RdsValidationError, SCALE_STEPS, type Scale, type ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, roleVar };
|
package/dist/generate.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { RDS_CONTRAST_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-
|
|
1
|
+
export { RDS_CONTRAST_PAIRS, RDS_NON_TEXT_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-D6HJEVJK.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_CONTRAST_PAIRS, RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsBrandTable, RdsContrastFailure, RdsCssOptions, RdsMode, RdsTheme, RdsThemeOptions, RdsValidationError, SCALE_STEPS, Scale, ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, roleVar } from './generate.js';
|
|
2
|
+
export { ClaudeMdOptions, ClaudeMdTarget, RDS_CONTRAST_PAIRS, RDS_NON_TEXT_PAIRS, RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsBrandTable, RdsContrastFailure, RdsCssOptions, RdsMode, RdsTheme, RdsThemeOptions, RdsValidationError, SCALE_STEPS, Scale, ScaleStep, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, 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-PV6GFEAM.js';
|
|
2
|
-
export { RDS_CONTRAST_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-
|
|
2
|
+
export { RDS_CONTRAST_PAIRS, RDS_NON_TEXT_PAIRS, ROLES as RDS_ROLES, RDS_SCOPE_SELECTORS, RDS_TOKEN_SCOPE, RdsValidationError, SCALE_STEPS, brandTones, buildScale, contrastRatio, emitClaudeMd, emitCss, emitRdsCss, generateRdsTheme, generateTheme, hexToHsl, hslToHex, isHex, isNeutralBrand, isSafeColor, isSafeFont, isSafeVarName, onColor, rdsContrast, rdsContrastReport, rdsThemeFromTable, refToHex, relativeLuminance, resolveTheme, roleVar } from './chunk-D6HJEVJK.js';
|
|
3
3
|
export { primitives, tokens } from './chunk-FRWRLCYM.js';
|
|
4
4
|
import './chunk-ORMEWXMH.js';
|
package/dist/themes.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rojaostudio/ds-core",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.11",
|
|
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)",
|