rafters 0.0.64 → 0.0.65
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/index.js +295 -346
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18394,94 +18394,6 @@ function generateHarmony(baseColor) {
|
|
|
18394
18394
|
monochromatic
|
|
18395
18395
|
};
|
|
18396
18396
|
}
|
|
18397
|
-
function generateSemanticColorSuggestions(baseColor) {
|
|
18398
|
-
const danger = [
|
|
18399
|
-
roundOKLCH({
|
|
18400
|
-
l: Math.max(0.55, Math.min(0.7, baseColor.l + 0.1)),
|
|
18401
|
-
c: Math.min(0.25, baseColor.c * 1.2),
|
|
18402
|
-
h: 15,
|
|
18403
|
-
alpha: 1
|
|
18404
|
-
}),
|
|
18405
|
-
roundOKLCH({
|
|
18406
|
-
l: Math.max(0.6, Math.min(0.75, baseColor.l + 0.15)),
|
|
18407
|
-
c: Math.min(0.22, baseColor.c * 1.1),
|
|
18408
|
-
h: 25,
|
|
18409
|
-
alpha: 1
|
|
18410
|
-
}),
|
|
18411
|
-
roundOKLCH({
|
|
18412
|
-
l: Math.max(0.5, Math.min(0.65, baseColor.l + 0.05)),
|
|
18413
|
-
c: Math.min(0.23, baseColor.c * 1.15),
|
|
18414
|
-
h: 5,
|
|
18415
|
-
alpha: 1
|
|
18416
|
-
})
|
|
18417
|
-
];
|
|
18418
|
-
const success2 = [
|
|
18419
|
-
roundOKLCH({
|
|
18420
|
-
l: Math.max(0.6, Math.min(0.75, baseColor.l + 0.15)),
|
|
18421
|
-
c: Math.min(0.2, baseColor.c * 0.9),
|
|
18422
|
-
h: 135,
|
|
18423
|
-
alpha: 1
|
|
18424
|
-
}),
|
|
18425
|
-
roundOKLCH({
|
|
18426
|
-
l: Math.max(0.55, Math.min(0.7, baseColor.l + 0.1)),
|
|
18427
|
-
c: Math.min(0.22, baseColor.c * 1),
|
|
18428
|
-
h: 145,
|
|
18429
|
-
alpha: 1
|
|
18430
|
-
}),
|
|
18431
|
-
roundOKLCH({
|
|
18432
|
-
l: Math.max(0.65, Math.min(0.8, baseColor.l + 0.2)),
|
|
18433
|
-
c: Math.min(0.24, baseColor.c * 1.1),
|
|
18434
|
-
h: 125,
|
|
18435
|
-
alpha: 1
|
|
18436
|
-
})
|
|
18437
|
-
];
|
|
18438
|
-
const warning = [
|
|
18439
|
-
roundOKLCH({
|
|
18440
|
-
l: Math.max(0.7, Math.min(0.8, baseColor.l + 0.15)),
|
|
18441
|
-
c: Math.min(0.2, baseColor.c * 0.95),
|
|
18442
|
-
h: 45,
|
|
18443
|
-
alpha: 1
|
|
18444
|
-
}),
|
|
18445
|
-
roundOKLCH({
|
|
18446
|
-
l: Math.max(0.75, Math.min(0.85, baseColor.l + 0.2)),
|
|
18447
|
-
c: Math.min(0.18, baseColor.c * 0.9),
|
|
18448
|
-
h: 55,
|
|
18449
|
-
alpha: 1
|
|
18450
|
-
}),
|
|
18451
|
-
roundOKLCH({
|
|
18452
|
-
l: Math.max(0.72, Math.min(0.82, baseColor.l + 0.17)),
|
|
18453
|
-
c: Math.min(0.19, baseColor.c * 0.92),
|
|
18454
|
-
h: 35,
|
|
18455
|
-
alpha: 1
|
|
18456
|
-
})
|
|
18457
|
-
];
|
|
18458
|
-
const info = [
|
|
18459
|
-
roundOKLCH({
|
|
18460
|
-
l: Math.max(0.6, Math.min(0.75, baseColor.l + 0.1)),
|
|
18461
|
-
c: Math.min(0.2, baseColor.c * 0.9),
|
|
18462
|
-
h: 220,
|
|
18463
|
-
alpha: 1
|
|
18464
|
-
}),
|
|
18465
|
-
roundOKLCH({
|
|
18466
|
-
l: Math.max(0.55, Math.min(0.7, baseColor.l + 0.05)),
|
|
18467
|
-
c: Math.min(0.22, baseColor.c * 1),
|
|
18468
|
-
h: 230,
|
|
18469
|
-
alpha: 1
|
|
18470
|
-
}),
|
|
18471
|
-
roundOKLCH({
|
|
18472
|
-
l: Math.max(0.5, Math.min(0.65, baseColor.l)),
|
|
18473
|
-
c: Math.min(0.25, baseColor.c * 1.1),
|
|
18474
|
-
h: 240,
|
|
18475
|
-
alpha: 1
|
|
18476
|
-
})
|
|
18477
|
-
];
|
|
18478
|
-
return {
|
|
18479
|
-
danger: danger.map(clampColor),
|
|
18480
|
-
success: success2.map(clampColor),
|
|
18481
|
-
warning: warning.map(clampColor),
|
|
18482
|
-
info: info.map(clampColor)
|
|
18483
|
-
};
|
|
18484
|
-
}
|
|
18485
18397
|
function validateScaleGeneration(baseColor) {
|
|
18486
18398
|
const l = baseColor.l;
|
|
18487
18399
|
if (l > 0.85) {
|
|
@@ -21213,44 +21125,255 @@ var POSITION_TO_INDEX = SCALE_POSITIONS.reduce(
|
|
|
21213
21125
|
},
|
|
21214
21126
|
{}
|
|
21215
21127
|
);
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
|
|
21128
|
+
|
|
21129
|
+
// ../color-utils/src/semantic.ts
|
|
21130
|
+
var SemanticSelectionError = class extends Error {
|
|
21131
|
+
constructor(familyName, message) {
|
|
21132
|
+
super(`semantic selection: family "${familyName}" ${message}`);
|
|
21133
|
+
this.familyName = familyName;
|
|
21134
|
+
this.name = "SemanticSelectionError";
|
|
21135
|
+
}
|
|
21136
|
+
};
|
|
21137
|
+
var STATE_USES = ["hover", "active", "focus", "disabled"];
|
|
21138
|
+
var STATE_RANK_STEP = {
|
|
21139
|
+
hover: (rank) => rank + 1,
|
|
21140
|
+
active: (rank) => rank + 2,
|
|
21141
|
+
focus: (rank) => rank + 1,
|
|
21142
|
+
disabled: (_rank, ladder) => closestRankTo(ladder, 5)
|
|
21143
|
+
};
|
|
21144
|
+
function partnerForBase(pairs, base) {
|
|
21145
|
+
if (!pairs) return void 0;
|
|
21146
|
+
for (const [p1, p2] of pairs) {
|
|
21147
|
+
if (p1 === base) return p2;
|
|
21148
|
+
if (p2 === base) return p1;
|
|
21149
|
+
}
|
|
21150
|
+
return void 0;
|
|
21151
|
+
}
|
|
21152
|
+
function nearestPartner(pairs, base) {
|
|
21153
|
+
if (!pairs || pairs.length === 0) return void 0;
|
|
21154
|
+
const anchors = /* @__PURE__ */ new Set();
|
|
21220
21155
|
for (const pair of pairs) {
|
|
21221
|
-
|
|
21222
|
-
|
|
21223
|
-
|
|
21224
|
-
|
|
21225
|
-
|
|
21226
|
-
|
|
21227
|
-
|
|
21228
|
-
if (wantHigher && partner <= sourceIndex) continue;
|
|
21229
|
-
if (!wantHigher && partner >= sourceIndex) continue;
|
|
21230
|
-
const distance2 = Math.abs(partner - sourceIndex);
|
|
21231
|
-
if (distance2 > bestDistance) {
|
|
21156
|
+
for (const position of pair) anchors.add(position);
|
|
21157
|
+
}
|
|
21158
|
+
let nearest = -1;
|
|
21159
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
21160
|
+
for (const anchor of anchors) {
|
|
21161
|
+
const distance2 = Math.abs(anchor - base);
|
|
21162
|
+
if (distance2 < bestDistance) {
|
|
21232
21163
|
bestDistance = distance2;
|
|
21233
|
-
|
|
21164
|
+
nearest = anchor;
|
|
21234
21165
|
}
|
|
21235
21166
|
}
|
|
21236
|
-
return
|
|
21167
|
+
return nearest === -1 ? void 0 : partnerForBase(pairs, nearest);
|
|
21237
21168
|
}
|
|
21238
|
-
function
|
|
21239
|
-
const
|
|
21240
|
-
const
|
|
21241
|
-
|
|
21242
|
-
throw new Error(
|
|
21243
|
-
`No WCAG accessibility data available for dark mode counterpart of index ${lightIndex}. ColorValue must include accessibility.wcagAAA or wcagAA pair matrices.`
|
|
21244
|
-
);
|
|
21169
|
+
function collectLadder(pairs) {
|
|
21170
|
+
const positions = /* @__PURE__ */ new Set();
|
|
21171
|
+
for (const pair of pairs) {
|
|
21172
|
+
for (const position of pair) positions.add(position);
|
|
21245
21173
|
}
|
|
21246
|
-
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
|
|
21250
|
-
|
|
21174
|
+
return Array.from(positions).sort((a2, b2) => a2 - b2);
|
|
21175
|
+
}
|
|
21176
|
+
function closestRankTo(ladder, target) {
|
|
21177
|
+
let bestRank = 0;
|
|
21178
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
21179
|
+
for (let rank = 0; rank < ladder.length; rank++) {
|
|
21180
|
+
const position = ladder[rank];
|
|
21181
|
+
if (position === void 0) continue;
|
|
21182
|
+
const distance2 = Math.abs(position - target);
|
|
21183
|
+
if (distance2 < bestDistance) {
|
|
21184
|
+
bestDistance = distance2;
|
|
21185
|
+
bestRank = rank;
|
|
21251
21186
|
}
|
|
21252
21187
|
}
|
|
21253
|
-
return
|
|
21188
|
+
return bestRank;
|
|
21189
|
+
}
|
|
21190
|
+
function requirePosition(index, familyName) {
|
|
21191
|
+
const position = SCALE_POSITIONS[index];
|
|
21192
|
+
if (!position) {
|
|
21193
|
+
throw new SemanticSelectionError(familyName, `produced invalid scale index ${index}`);
|
|
21194
|
+
}
|
|
21195
|
+
return position;
|
|
21196
|
+
}
|
|
21197
|
+
function requireIndex(position, familyName) {
|
|
21198
|
+
const index = POSITION_TO_INDEX[position];
|
|
21199
|
+
if (index === void 0) {
|
|
21200
|
+
throw new SemanticSelectionError(familyName, `has no scale position "${position}"`);
|
|
21201
|
+
}
|
|
21202
|
+
return index;
|
|
21203
|
+
}
|
|
21204
|
+
var STATUS_ROLE_ANCHORS = {
|
|
21205
|
+
// band is the recognizability range a variant may never leave;
|
|
21206
|
+
// [min > max] means the band wraps through 0 (destructive: 330..360..30).
|
|
21207
|
+
destructive: { hue: 25, l: 0.55, cCap: 0.2, cScale: 1, band: [330, 30] },
|
|
21208
|
+
success: { hue: 145, l: 0.55, cCap: 0.18, cScale: 0.9, band: [120, 160] },
|
|
21209
|
+
warning: { hue: 85, l: 0.75, cCap: 0.18, cScale: 0.9, band: [60, 110] },
|
|
21210
|
+
info: { hue: 230, l: 0.58, cCap: 0.15, cScale: 0.85, band: [200, 250] }
|
|
21211
|
+
};
|
|
21212
|
+
function statusAnchor(role, seed) {
|
|
21213
|
+
const spec = STATUS_ROLE_ANCHORS[role];
|
|
21214
|
+
return roundOKLCH({
|
|
21215
|
+
l: spec.l,
|
|
21216
|
+
c: Math.min(spec.cCap, seed.c * spec.cScale),
|
|
21217
|
+
h: spec.hue,
|
|
21218
|
+
alpha: seed.alpha ?? 1
|
|
21219
|
+
});
|
|
21220
|
+
}
|
|
21221
|
+
function clampHueToBand(hue, band) {
|
|
21222
|
+
const h = (hue % 360 + 360) % 360;
|
|
21223
|
+
const [min, max2] = band;
|
|
21224
|
+
if (min <= max2) return Math.max(min, Math.min(max2, h));
|
|
21225
|
+
if (h >= min || h <= max2) return h;
|
|
21226
|
+
const toMin = Math.abs(h - min);
|
|
21227
|
+
const toMax = Math.abs(h - max2);
|
|
21228
|
+
return toMin < toMax ? min : max2;
|
|
21229
|
+
}
|
|
21230
|
+
var VARIANT_OFFSETS = [
|
|
21231
|
+
{ dh: 0, dl: 0 },
|
|
21232
|
+
{ dh: 10, dl: 0.05 },
|
|
21233
|
+
{ dh: -10, dl: -0.05 }
|
|
21234
|
+
];
|
|
21235
|
+
function generateSemanticColorSuggestions(baseColor) {
|
|
21236
|
+
const roles = {};
|
|
21237
|
+
for (const role of Object.keys(STATUS_ROLE_ANCHORS)) {
|
|
21238
|
+
const anchor = statusAnchor(role, baseColor);
|
|
21239
|
+
const { band } = STATUS_ROLE_ANCHORS[role];
|
|
21240
|
+
roles[role] = VARIANT_OFFSETS.map(({ dh, dl }) => {
|
|
21241
|
+
const raw = roundOKLCH({
|
|
21242
|
+
l: Math.max(0, Math.min(1, anchor.l + dl)),
|
|
21243
|
+
c: anchor.c,
|
|
21244
|
+
h: clampHueToBand(anchor.h + dh, band),
|
|
21245
|
+
alpha: anchor.alpha ?? 1
|
|
21246
|
+
});
|
|
21247
|
+
return roundOKLCH(toNearestGamut(raw).color);
|
|
21248
|
+
});
|
|
21249
|
+
}
|
|
21250
|
+
return { ...roles, danger: roles.destructive };
|
|
21251
|
+
}
|
|
21252
|
+
function semanticFor(family, options) {
|
|
21253
|
+
const familyName = options?.name ?? family.name;
|
|
21254
|
+
const refs = family;
|
|
21255
|
+
const aaaPairs = family.accessibility?.wcagAAA?.normal;
|
|
21256
|
+
const aaPairs = family.accessibility?.wcagAA?.normal;
|
|
21257
|
+
function foregroundPair(from, level) {
|
|
21258
|
+
const auto = refs.foregroundReferences?.auto;
|
|
21259
|
+
if (auto) {
|
|
21260
|
+
return {
|
|
21261
|
+
from: { family: familyName, position: from },
|
|
21262
|
+
to: { family: auto.family, position: auto.position },
|
|
21263
|
+
standard: level,
|
|
21264
|
+
tier: "reference"
|
|
21265
|
+
};
|
|
21266
|
+
}
|
|
21267
|
+
const base = requireIndex(from, familyName);
|
|
21268
|
+
const exactAAA = partnerForBase(aaaPairs, base);
|
|
21269
|
+
const aaa = exactAAA ?? nearestPartner(aaaPairs, base);
|
|
21270
|
+
const exactAA = partnerForBase(aaPairs, base);
|
|
21271
|
+
const aa = exactAA ?? nearestPartner(aaPairs, base);
|
|
21272
|
+
const partner = level === "AAA" ? aaa ?? aa : aa;
|
|
21273
|
+
if (partner === void 0) {
|
|
21274
|
+
throw new SemanticSelectionError(
|
|
21275
|
+
familyName,
|
|
21276
|
+
`has no WCAG pair partner for position ${from} (accessibility metadata required)`
|
|
21277
|
+
);
|
|
21278
|
+
}
|
|
21279
|
+
const fromAAA = level === "AAA" && aaa !== void 0;
|
|
21280
|
+
return {
|
|
21281
|
+
from: { family: familyName, position: from },
|
|
21282
|
+
to: { family: familyName, position: requirePosition(partner, familyName) },
|
|
21283
|
+
standard: fromAAA ? "AAA" : "AA",
|
|
21284
|
+
tier: (fromAAA ? exactAAA : exactAA) !== void 0 ? "pair-exact" : "pair-nearest"
|
|
21285
|
+
};
|
|
21286
|
+
}
|
|
21287
|
+
function statePair(use, from) {
|
|
21288
|
+
const precomputed = refs.stateReferences?.[use];
|
|
21289
|
+
if (precomputed) {
|
|
21290
|
+
return {
|
|
21291
|
+
from: { family: familyName, position: from },
|
|
21292
|
+
to: { family: precomputed.family, position: String(precomputed.position) },
|
|
21293
|
+
standard: "AAA",
|
|
21294
|
+
tier: "reference"
|
|
21295
|
+
};
|
|
21296
|
+
}
|
|
21297
|
+
if (!aaaPairs || aaaPairs.length === 0) {
|
|
21298
|
+
throw new SemanticSelectionError(
|
|
21299
|
+
familyName,
|
|
21300
|
+
"has no accessibility.wcagAAA.normal ladder (color generator must emit accessibility metadata)"
|
|
21301
|
+
);
|
|
21302
|
+
}
|
|
21303
|
+
const base = requireIndex(from, familyName);
|
|
21304
|
+
const ladder = collectLadder(aaaPairs);
|
|
21305
|
+
const baseRank = closestRankTo(ladder, base);
|
|
21306
|
+
const targetRank = STATE_RANK_STEP[use](baseRank, ladder);
|
|
21307
|
+
const clampedRank = Math.max(0, Math.min(ladder.length - 1, targetRank));
|
|
21308
|
+
const targetIndex = ladder[clampedRank];
|
|
21309
|
+
if (targetIndex === void 0) {
|
|
21310
|
+
throw new SemanticSelectionError(familyName, `ladder lookup failed at rank ${clampedRank}`);
|
|
21311
|
+
}
|
|
21312
|
+
return {
|
|
21313
|
+
from: { family: familyName, position: from },
|
|
21314
|
+
to: { family: familyName, position: requirePosition(targetIndex, familyName) },
|
|
21315
|
+
standard: "AAA",
|
|
21316
|
+
tier: "ladder"
|
|
21317
|
+
};
|
|
21318
|
+
}
|
|
21319
|
+
function invert(pair) {
|
|
21320
|
+
if (pair.to.family !== familyName && pair.tier !== "reference") {
|
|
21321
|
+
throw new SemanticSelectionError(
|
|
21322
|
+
familyName,
|
|
21323
|
+
`cannot invert a pair whose legs belong to "${pair.from.family}"/"${pair.to.family}"`
|
|
21324
|
+
);
|
|
21325
|
+
}
|
|
21326
|
+
const fromTarget = 10 - requireIndex(pair.from.position, familyName);
|
|
21327
|
+
const toIndex = POSITION_TO_INDEX[pair.to.position];
|
|
21328
|
+
const toTarget = toIndex === void 0 ? void 0 : 10 - toIndex;
|
|
21329
|
+
for (const [pairs, standard] of [
|
|
21330
|
+
[aaaPairs, "AAA"],
|
|
21331
|
+
[aaPairs, "AA"]
|
|
21332
|
+
]) {
|
|
21333
|
+
if (!pairs || pairs.length === 0) continue;
|
|
21334
|
+
let best = null;
|
|
21335
|
+
for (const [p1, p2] of pairs) {
|
|
21336
|
+
if (p1 === void 0 || p2 === void 0) continue;
|
|
21337
|
+
for (const [a2, b2] of [
|
|
21338
|
+
[p1, p2],
|
|
21339
|
+
[p2, p1]
|
|
21340
|
+
]) {
|
|
21341
|
+
const fromDist = Math.abs(a2 - fromTarget);
|
|
21342
|
+
const toDist = toTarget === void 0 ? 0 : Math.abs(b2 - toTarget);
|
|
21343
|
+
const better = best === null || fromDist < best.fromDist || fromDist === best.fromDist && toDist < best.toDist || fromDist === best.fromDist && toDist === best.toDist && a2 < best.from;
|
|
21344
|
+
if (better) best = { from: a2, to: b2, fromDist, toDist };
|
|
21345
|
+
}
|
|
21346
|
+
}
|
|
21347
|
+
if (best) {
|
|
21348
|
+
return {
|
|
21349
|
+
from: { family: familyName, position: requirePosition(best.from, familyName) },
|
|
21350
|
+
to: { family: familyName, position: requirePosition(best.to, familyName) },
|
|
21351
|
+
standard,
|
|
21352
|
+
tier: best.fromDist === 0 && best.toDist === 0 ? "pair-exact" : "pair-nearest"
|
|
21353
|
+
};
|
|
21354
|
+
}
|
|
21355
|
+
}
|
|
21356
|
+
const toFallback = toTarget === void 0 ? fromTarget : toTarget;
|
|
21357
|
+
return {
|
|
21358
|
+
from: { family: familyName, position: requirePosition(fromTarget, familyName) },
|
|
21359
|
+
to: { family: familyName, position: requirePosition(toFallback, familyName) },
|
|
21360
|
+
standard: "none",
|
|
21361
|
+
tier: "inversion"
|
|
21362
|
+
};
|
|
21363
|
+
}
|
|
21364
|
+
return {
|
|
21365
|
+
pair(request) {
|
|
21366
|
+
const level = request.level ?? "AAA";
|
|
21367
|
+
if (request.use === "foreground") return foregroundPair(request.from, level);
|
|
21368
|
+
return statePair(request.use, request.from);
|
|
21369
|
+
},
|
|
21370
|
+
states(from) {
|
|
21371
|
+
const out = {};
|
|
21372
|
+
for (const use of STATE_USES) out[use] = statePair(use, from);
|
|
21373
|
+
return out;
|
|
21374
|
+
},
|
|
21375
|
+
invert
|
|
21376
|
+
};
|
|
21254
21377
|
}
|
|
21255
21378
|
|
|
21256
21379
|
// ../color-utils/src/builder.ts
|
|
@@ -21603,12 +21726,22 @@ var PerceptualWeightSchema = external_exports.object({
|
|
|
21603
21726
|
density: external_exports.enum(["light", "medium", "heavy"]),
|
|
21604
21727
|
balancingRecommendation: external_exports.string()
|
|
21605
21728
|
});
|
|
21606
|
-
var SemanticColorSuggestionsSchema = external_exports.
|
|
21607
|
-
|
|
21608
|
-
|
|
21609
|
-
|
|
21610
|
-
|
|
21611
|
-
|
|
21729
|
+
var SemanticColorSuggestionsSchema = external_exports.preprocess(
|
|
21730
|
+
(raw) => {
|
|
21731
|
+
if (raw && typeof raw === "object" && !("destructive" in raw) && "danger" in raw) {
|
|
21732
|
+
return { ...raw, destructive: raw.danger };
|
|
21733
|
+
}
|
|
21734
|
+
return raw;
|
|
21735
|
+
},
|
|
21736
|
+
external_exports.object({
|
|
21737
|
+
destructive: external_exports.array(OKLCHSchema),
|
|
21738
|
+
success: external_exports.array(OKLCHSchema),
|
|
21739
|
+
warning: external_exports.array(OKLCHSchema),
|
|
21740
|
+
info: external_exports.array(OKLCHSchema),
|
|
21741
|
+
/** @deprecated mirror of `destructive`; dies when apps/api leaves the repo */
|
|
21742
|
+
danger: external_exports.array(OKLCHSchema).optional()
|
|
21743
|
+
})
|
|
21744
|
+
);
|
|
21612
21745
|
var ColorValueSchema = external_exports.object({
|
|
21613
21746
|
name: external_exports.string(),
|
|
21614
21747
|
// the fancy name from color-utils, IE ocean-blue
|
|
@@ -27376,12 +27509,12 @@ function derivationParent(derivation, suffix = "") {
|
|
|
27376
27509
|
return `${derivation.against}${suffix}`;
|
|
27377
27510
|
}
|
|
27378
27511
|
}
|
|
27379
|
-
function deriveDarkBinding(derivation) {
|
|
27512
|
+
function deriveDarkBinding(derivation, parentName) {
|
|
27380
27513
|
switch (derivation.kind) {
|
|
27381
27514
|
case "scale":
|
|
27382
27515
|
return {
|
|
27383
27516
|
plugin: "invert",
|
|
27384
|
-
input: {
|
|
27517
|
+
input: { fromToken: parentName }
|
|
27385
27518
|
};
|
|
27386
27519
|
case "state":
|
|
27387
27520
|
return {
|
|
@@ -27406,7 +27539,7 @@ function generateSemanticTokens(_config) {
|
|
|
27406
27539
|
const binding = derivationToBinding(derivation);
|
|
27407
27540
|
const parent = derivationParent(derivation);
|
|
27408
27541
|
const darkName = `${name}--dark`;
|
|
27409
|
-
const darkBinding = deriveDarkBinding(derivation);
|
|
27542
|
+
const darkBinding = deriveDarkBinding(derivation, name);
|
|
27410
27543
|
const darkParent = derivationParent(derivation, "--dark");
|
|
27411
27544
|
const dependsOn = [parent, darkName];
|
|
27412
27545
|
tokens.push({
|
|
@@ -28883,14 +29016,30 @@ function readEnvelopes(dir) {
|
|
|
28883
29016
|
// ../design-tokens/src/plugin.ts
|
|
28884
29017
|
function resolveFamily(familyName, get3) {
|
|
28885
29018
|
let resolved = get3(familyName);
|
|
28886
|
-
let
|
|
29019
|
+
let name = familyName;
|
|
28887
29020
|
if (resolved && typeof resolved === "object" && "family" in resolved && "position" in resolved) {
|
|
28888
|
-
|
|
28889
|
-
resolved = get3(
|
|
29021
|
+
name = resolved.family;
|
|
29022
|
+
resolved = get3(name);
|
|
28890
29023
|
}
|
|
28891
|
-
|
|
28892
|
-
|
|
28893
|
-
|
|
29024
|
+
if (!resolved || typeof resolved !== "object" || !("scale" in resolved)) return null;
|
|
29025
|
+
return { family: resolved, familyName: name };
|
|
29026
|
+
}
|
|
29027
|
+
function resolveParent(tokenName, get3) {
|
|
29028
|
+
const raw = get3(tokenName);
|
|
29029
|
+
if (!raw || typeof raw !== "object" || !("family" in raw) || !("position" in raw)) return null;
|
|
29030
|
+
const ref = raw;
|
|
29031
|
+
const positionIndex = POSITION_TO_INDEX[ref.position];
|
|
29032
|
+
if (positionIndex === void 0) return null;
|
|
29033
|
+
const result = resolveFamily(ref.family, get3);
|
|
29034
|
+
if (!result) return null;
|
|
29035
|
+
return { ref, positionIndex, ...result };
|
|
29036
|
+
}
|
|
29037
|
+
function requireSemanticParent(tokenName, get3, pluginName) {
|
|
29038
|
+
const resolved = resolveParent(tokenName, get3);
|
|
29039
|
+
if (!resolved) {
|
|
29040
|
+
throw new Error(`${pluginName} plugin: "${tokenName}" could not resolve`);
|
|
29041
|
+
}
|
|
29042
|
+
return { sem: semanticFor(resolved.family, { name: resolved.familyName }), resolved };
|
|
28894
29043
|
}
|
|
28895
29044
|
function definePlugin(spec) {
|
|
28896
29045
|
return {
|
|
@@ -28944,132 +29093,32 @@ var ContrastInputSchema = external_exports.object({
|
|
|
28944
29093
|
against: external_exports.string(),
|
|
28945
29094
|
level: external_exports.enum(["AA", "AAA"]).default("AAA")
|
|
28946
29095
|
});
|
|
28947
|
-
function partnerForBase(pairs, basePosition) {
|
|
28948
|
-
if (!pairs) return void 0;
|
|
28949
|
-
for (const [p1, p2] of pairs) {
|
|
28950
|
-
if (p1 === basePosition) return p2;
|
|
28951
|
-
if (p2 === basePosition) return p1;
|
|
28952
|
-
}
|
|
28953
|
-
return void 0;
|
|
28954
|
-
}
|
|
28955
|
-
function nearestPartner(pairs, basePosition) {
|
|
28956
|
-
if (!pairs || pairs.length === 0) return void 0;
|
|
28957
|
-
const anchors = /* @__PURE__ */ new Set();
|
|
28958
|
-
for (const pair of pairs) {
|
|
28959
|
-
for (const position of pair) anchors.add(position);
|
|
28960
|
-
}
|
|
28961
|
-
if (anchors.size === 0) return void 0;
|
|
28962
|
-
let nearest = -1;
|
|
28963
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
28964
|
-
for (const anchor of anchors) {
|
|
28965
|
-
const distance2 = Math.abs(anchor - basePosition);
|
|
28966
|
-
if (distance2 < bestDistance) {
|
|
28967
|
-
bestDistance = distance2;
|
|
28968
|
-
nearest = anchor;
|
|
28969
|
-
}
|
|
28970
|
-
}
|
|
28971
|
-
if (nearest === -1) return void 0;
|
|
28972
|
-
return partnerForBase(pairs, nearest);
|
|
28973
|
-
}
|
|
28974
|
-
function requireScalePosition(index, label) {
|
|
28975
|
-
const position = SCALE_POSITIONS[index];
|
|
28976
|
-
if (!position) {
|
|
28977
|
-
throw new Error(`contrast plugin: invalid scale index ${index} (${label})`);
|
|
28978
|
-
}
|
|
28979
|
-
return position;
|
|
28980
|
-
}
|
|
28981
|
-
function isPositionString(value) {
|
|
28982
|
-
return typeof value === "string";
|
|
28983
|
-
}
|
|
28984
|
-
function resolveBasePosition(position) {
|
|
28985
|
-
const map2 = {
|
|
28986
|
-
"50": 0,
|
|
28987
|
-
"100": 1,
|
|
28988
|
-
"200": 2,
|
|
28989
|
-
"300": 3,
|
|
28990
|
-
"400": 4,
|
|
28991
|
-
"500": 5,
|
|
28992
|
-
"600": 6,
|
|
28993
|
-
"700": 7,
|
|
28994
|
-
"800": 8,
|
|
28995
|
-
"900": 9,
|
|
28996
|
-
"950": 10
|
|
28997
|
-
};
|
|
28998
|
-
const index = map2[position];
|
|
28999
|
-
if (index === void 0) {
|
|
29000
|
-
throw new Error(`contrast plugin: unknown scale position "${position}"`);
|
|
29001
|
-
}
|
|
29002
|
-
return index;
|
|
29003
|
-
}
|
|
29004
29096
|
var contrastPlugin = definePlugin({
|
|
29005
29097
|
name: "contrast",
|
|
29006
29098
|
inputSchema: ContrastInputSchema,
|
|
29007
29099
|
outputSchema: ColorReferenceSchema,
|
|
29008
29100
|
dependsOn: (input2) => [input2.against],
|
|
29009
29101
|
transform: (input2, get3) => {
|
|
29010
|
-
const
|
|
29011
|
-
|
|
29012
|
-
|
|
29013
|
-
`contrast plugin: parent token "${input2.against}" did not resolve to a ColorReference`
|
|
29014
|
-
);
|
|
29015
|
-
}
|
|
29016
|
-
const parentRef = parent;
|
|
29017
|
-
if (!isPositionString(parentRef.position)) {
|
|
29018
|
-
throw new Error(
|
|
29019
|
-
`contrast plugin: parent token "${input2.against}" position is not a scale string`
|
|
29020
|
-
);
|
|
29021
|
-
}
|
|
29022
|
-
const basePosition = resolveBasePosition(parentRef.position);
|
|
29023
|
-
const family = get3(parentRef.family);
|
|
29024
|
-
if (!family) {
|
|
29025
|
-
throw new Error(
|
|
29026
|
-
`contrast plugin: family "${parentRef.family}" (from "${input2.against}") not in registry`
|
|
29027
|
-
);
|
|
29028
|
-
}
|
|
29029
|
-
if (family.foregroundReferences?.auto) {
|
|
29030
|
-
const ref = family.foregroundReferences.auto;
|
|
29031
|
-
return { family: ref.family, position: ref.position };
|
|
29032
|
-
}
|
|
29033
|
-
if (family.accessibility) {
|
|
29034
|
-
const aaaPartner = partnerForBase(family.accessibility.wcagAAA?.normal, basePosition) ?? nearestPartner(family.accessibility.wcagAAA?.normal, basePosition);
|
|
29035
|
-
const aaPartner = partnerForBase(family.accessibility.wcagAA?.normal, basePosition) ?? nearestPartner(family.accessibility.wcagAA?.normal, basePosition);
|
|
29036
|
-
const partner = input2.level === "AAA" ? aaaPartner ?? aaPartner : aaPartner;
|
|
29037
|
-
if (partner !== void 0) {
|
|
29038
|
-
return {
|
|
29039
|
-
family: parentRef.family,
|
|
29040
|
-
position: requireScalePosition(partner, `${parentRef.family} pair`)
|
|
29041
|
-
};
|
|
29042
|
-
}
|
|
29043
|
-
}
|
|
29044
|
-
throw new Error(
|
|
29045
|
-
`contrast plugin: family "${parentRef.family}" has no foregroundReferences and no accessibility WCAG pair partner for position ${parentRef.position} (against ${input2.against})`
|
|
29046
|
-
);
|
|
29102
|
+
const { sem, resolved } = requireSemanticParent(input2.against, get3, "contrast");
|
|
29103
|
+
const pair = sem.pair({ use: "foreground", from: resolved.ref.position, level: input2.level });
|
|
29104
|
+
return { family: pair.to.family, position: pair.to.position };
|
|
29047
29105
|
}
|
|
29048
29106
|
});
|
|
29049
29107
|
|
|
29050
29108
|
// ../design-tokens/src/plugins/invert.ts
|
|
29051
29109
|
var InvertInputSchema = external_exports.object({
|
|
29052
|
-
|
|
29053
|
-
basePosition: external_exports.number().int().min(0).max(10)
|
|
29110
|
+
fromToken: external_exports.string()
|
|
29054
29111
|
});
|
|
29055
29112
|
var invertPlugin = definePlugin({
|
|
29056
29113
|
name: "invert",
|
|
29057
29114
|
inputSchema: InvertInputSchema,
|
|
29058
29115
|
outputSchema: ColorReferenceSchema,
|
|
29059
|
-
dependsOn: (input2) => [input2.
|
|
29116
|
+
dependsOn: (input2) => [input2.fromToken],
|
|
29060
29117
|
transform: (input2, get3) => {
|
|
29061
|
-
const
|
|
29062
|
-
|
|
29063
|
-
|
|
29064
|
-
}
|
|
29065
|
-
const darkIndex = findDarkCounterpartIndex(input2.basePosition, result.family);
|
|
29066
|
-
const darkPosition = SCALE_POSITIONS[darkIndex];
|
|
29067
|
-
if (!darkPosition) {
|
|
29068
|
-
throw new Error(
|
|
29069
|
-
`invert plugin: invalid dark index ${darkIndex} for base position ${input2.basePosition}`
|
|
29070
|
-
);
|
|
29071
|
-
}
|
|
29072
|
-
return { family: result.resolvedName, position: darkPosition };
|
|
29118
|
+
const { sem, resolved } = requireSemanticParent(input2.fromToken, get3, "invert");
|
|
29119
|
+
const lightPair = sem.pair({ use: "foreground", from: resolved.ref.position });
|
|
29120
|
+
const darkPair = sem.invert(lightPair);
|
|
29121
|
+
return { family: resolved.familyName, position: darkPair.from.position };
|
|
29073
29122
|
}
|
|
29074
29123
|
});
|
|
29075
29124
|
|
|
@@ -29092,7 +29141,7 @@ var scalePlugin = definePlugin({
|
|
|
29092
29141
|
if (position === void 0) {
|
|
29093
29142
|
throw new Error(`scale plugin: invalid position index ${input2.scalePosition}`);
|
|
29094
29143
|
}
|
|
29095
|
-
return { family: result.
|
|
29144
|
+
return { family: result.familyName, position };
|
|
29096
29145
|
}
|
|
29097
29146
|
});
|
|
29098
29147
|
|
|
@@ -29102,115 +29151,15 @@ var StateInputSchema = external_exports.object({
|
|
|
29102
29151
|
from: external_exports.string(),
|
|
29103
29152
|
stateType: StateTypeSchema
|
|
29104
29153
|
});
|
|
29105
|
-
var POSITION_TO_INDEX3 = {
|
|
29106
|
-
"50": 0,
|
|
29107
|
-
"100": 1,
|
|
29108
|
-
"200": 2,
|
|
29109
|
-
"300": 3,
|
|
29110
|
-
"400": 4,
|
|
29111
|
-
"500": 5,
|
|
29112
|
-
"600": 6,
|
|
29113
|
-
"700": 7,
|
|
29114
|
-
"800": 8,
|
|
29115
|
-
"900": 9,
|
|
29116
|
-
"950": 10
|
|
29117
|
-
};
|
|
29118
|
-
var STEP_BY_STATE = {
|
|
29119
|
-
hover: (rank) => rank + 1,
|
|
29120
|
-
active: (rank) => rank + 2,
|
|
29121
|
-
focus: (rank) => rank + 1,
|
|
29122
|
-
disabled: (_rank, ladder) => closestRankToMidpoint(ladder)
|
|
29123
|
-
};
|
|
29124
|
-
function closestRankToMidpoint(ladder) {
|
|
29125
|
-
let bestRank = 0;
|
|
29126
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
29127
|
-
for (let r = 0; r < ladder.length; r++) {
|
|
29128
|
-
const position = ladder[r];
|
|
29129
|
-
if (position === void 0) continue;
|
|
29130
|
-
const distance2 = Math.abs(position - 5);
|
|
29131
|
-
if (distance2 < bestDistance) {
|
|
29132
|
-
bestDistance = distance2;
|
|
29133
|
-
bestRank = r;
|
|
29134
|
-
}
|
|
29135
|
-
}
|
|
29136
|
-
return bestRank;
|
|
29137
|
-
}
|
|
29138
|
-
function nearestRankOnLadder(ladder, position) {
|
|
29139
|
-
let bestRank = 0;
|
|
29140
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
29141
|
-
for (let r = 0; r < ladder.length; r++) {
|
|
29142
|
-
const candidate = ladder[r];
|
|
29143
|
-
if (candidate === void 0) continue;
|
|
29144
|
-
const distance2 = Math.abs(candidate - position);
|
|
29145
|
-
if (distance2 < bestDistance) {
|
|
29146
|
-
bestDistance = distance2;
|
|
29147
|
-
bestRank = r;
|
|
29148
|
-
}
|
|
29149
|
-
}
|
|
29150
|
-
return bestRank;
|
|
29151
|
-
}
|
|
29152
|
-
function collectLadder(pairs) {
|
|
29153
|
-
const positions = /* @__PURE__ */ new Set();
|
|
29154
|
-
for (const pair of pairs) {
|
|
29155
|
-
for (const position of pair) positions.add(position);
|
|
29156
|
-
}
|
|
29157
|
-
return Array.from(positions).sort((a2, b2) => a2 - b2);
|
|
29158
|
-
}
|
|
29159
29154
|
var statePlugin = definePlugin({
|
|
29160
29155
|
name: "state",
|
|
29161
29156
|
inputSchema: StateInputSchema,
|
|
29162
29157
|
outputSchema: ColorReferenceSchema,
|
|
29163
29158
|
dependsOn: (input2) => [input2.from],
|
|
29164
29159
|
transform: (input2, get3) => {
|
|
29165
|
-
const
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
`state plugin: parent token "${input2.from}" did not resolve to a ColorReference`
|
|
29169
|
-
);
|
|
29170
|
-
}
|
|
29171
|
-
const parentRef = parent;
|
|
29172
|
-
if (typeof parentRef.position !== "string") {
|
|
29173
|
-
throw new Error(`state plugin: parent token "${input2.from}" position is not a scale string`);
|
|
29174
|
-
}
|
|
29175
|
-
const basePosition = POSITION_TO_INDEX3[parentRef.position];
|
|
29176
|
-
if (basePosition === void 0) {
|
|
29177
|
-
throw new Error(
|
|
29178
|
-
`state plugin: parent token "${input2.from}" position "${parentRef.position}" is not a known scale step`
|
|
29179
|
-
);
|
|
29180
|
-
}
|
|
29181
|
-
const family = get3(parentRef.family);
|
|
29182
|
-
if (!family) {
|
|
29183
|
-
throw new Error(
|
|
29184
|
-
`state plugin: family "${parentRef.family}" (from "${input2.from}") not in registry`
|
|
29185
|
-
);
|
|
29186
|
-
}
|
|
29187
|
-
const precomputed = family.stateReferences?.[input2.stateType];
|
|
29188
|
-
if (precomputed) {
|
|
29189
|
-
return { family: precomputed.family, position: String(precomputed.position) };
|
|
29190
|
-
}
|
|
29191
|
-
const pairs = family.accessibility?.wcagAAA?.normal;
|
|
29192
|
-
if (!pairs || pairs.length === 0) {
|
|
29193
|
-
throw new Error(
|
|
29194
|
-
`state plugin: family "${parentRef.family}" has no accessibility.wcagAAA.normal ladder (color generator must emit accessibility metadata)`
|
|
29195
|
-
);
|
|
29196
|
-
}
|
|
29197
|
-
const ladder = collectLadder(pairs);
|
|
29198
|
-
const baseRank = nearestRankOnLadder(ladder, basePosition);
|
|
29199
|
-
const targetRank = STEP_BY_STATE[input2.stateType](baseRank, ladder);
|
|
29200
|
-
const clampedRank = Math.max(0, Math.min(ladder.length - 1, targetRank));
|
|
29201
|
-
const targetIndex = ladder[clampedRank];
|
|
29202
|
-
if (targetIndex === void 0) {
|
|
29203
|
-
throw new Error(
|
|
29204
|
-
`state plugin: ladder lookup failed for rank ${clampedRank} on family "${parentRef.family}"`
|
|
29205
|
-
);
|
|
29206
|
-
}
|
|
29207
|
-
const position = SCALE_POSITIONS[targetIndex];
|
|
29208
|
-
if (!position) {
|
|
29209
|
-
throw new Error(
|
|
29210
|
-
`state plugin: invalid scale index ${targetIndex} for family "${parentRef.family}"`
|
|
29211
|
-
);
|
|
29212
|
-
}
|
|
29213
|
-
return { family: parentRef.family, position };
|
|
29160
|
+
const { sem, resolved } = requireSemanticParent(input2.from, get3, "state");
|
|
29161
|
+
const pair = sem.pair({ use: input2.stateType, from: resolved.ref.position });
|
|
29162
|
+
return { family: pair.to.family, position: pair.to.position };
|
|
29214
29163
|
}
|
|
29215
29164
|
});
|
|
29216
29165
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rafters",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.65",
|
|
4
4
|
"description": "Design Intelligence CLI. Scaffold tokens, import existing shadcn/Tailwind v4 sources, add components, and serve an MCP server so AI agents read decisions instead of guessing.",
|
|
5
5
|
"homepage": "https://rafters.studio",
|
|
6
6
|
"license": "MIT",
|