rafters 0.0.71 → 0.0.73
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 +556 -151
- package/dist/registry/types.d.ts +9 -1
- package/dist/registry/types.js +3 -2
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -437,7 +437,7 @@ function generateThemeInlineBlock(semanticTokens) {
|
|
|
437
437
|
function generateRootBlock(semanticTokens, darkMode = "class") {
|
|
438
438
|
const semanticMappings = getSemanticMappingsFromTokens(semanticTokens);
|
|
439
439
|
const lines = [];
|
|
440
|
-
lines.push(":root {");
|
|
440
|
+
lines.push(":root, :host {");
|
|
441
441
|
for (const [name, mapping] of Object.entries(semanticMappings)) {
|
|
442
442
|
lines.push(` --rafters-${name}: var(--color-${mapping.light});`);
|
|
443
443
|
}
|
|
@@ -750,6 +750,37 @@ function generateTypographyCompositeUtilities(compositeTokens) {
|
|
|
750
750
|
}
|
|
751
751
|
return lines.join("\n");
|
|
752
752
|
}
|
|
753
|
+
function generateMotionUtilities(motionTokens) {
|
|
754
|
+
const semanticTokens = motionTokens.filter((t) => t.name.startsWith("motion-semantic-"));
|
|
755
|
+
if (semanticTokens.length === 0) {
|
|
756
|
+
return "";
|
|
757
|
+
}
|
|
758
|
+
const lines = ["/* Semantic motion utilities -- transition longhand per token */"];
|
|
759
|
+
for (const token of semanticTokens) {
|
|
760
|
+
if (typeof token.value !== "string") continue;
|
|
761
|
+
let spec;
|
|
762
|
+
try {
|
|
763
|
+
spec = JSON.parse(token.value);
|
|
764
|
+
} catch {
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
const className = token.name.replace("motion-semantic-", "motion-");
|
|
768
|
+
lines.push(`@utility ${className} {`);
|
|
769
|
+
lines.push(` transition-property: ${spec.properties.join(", ")};`);
|
|
770
|
+
lines.push(` transition-duration: var(--duration-${spec.durationTier});`);
|
|
771
|
+
lines.push(` transition-timing-function: var(--ease-${spec.curve});`);
|
|
772
|
+
if (spec.reducedMotion) {
|
|
773
|
+
lines.push(" @media (prefers-reduced-motion: reduce) {");
|
|
774
|
+
lines.push(` transition-property: ${spec.reducedMotion.properties.join(", ")};`);
|
|
775
|
+
if (typeof spec.reducedMotion.ms === "number") {
|
|
776
|
+
lines.push(` transition-duration: ${spec.reducedMotion.ms}ms;`);
|
|
777
|
+
}
|
|
778
|
+
lines.push(" }");
|
|
779
|
+
}
|
|
780
|
+
lines.push("}");
|
|
781
|
+
}
|
|
782
|
+
return lines.join("\n");
|
|
783
|
+
}
|
|
753
784
|
function overridePropertyToUtility(property, value) {
|
|
754
785
|
switch (property) {
|
|
755
786
|
case "fontFamily":
|
|
@@ -825,6 +856,11 @@ function tokensToTailwind(tokens, options = {}, typographyOverrides = []) {
|
|
|
825
856
|
sections.push("");
|
|
826
857
|
sections.push(depthUtilities);
|
|
827
858
|
}
|
|
859
|
+
const motionUtilities = generateMotionUtilities(groups.motion);
|
|
860
|
+
if (motionUtilities) {
|
|
861
|
+
sections.push("");
|
|
862
|
+
sections.push(motionUtilities);
|
|
863
|
+
}
|
|
828
864
|
const overrideCSS = generateTypographyOverrideCSS(typographyOverrides);
|
|
829
865
|
if (overrideCSS) {
|
|
830
866
|
sections.push("");
|
|
@@ -876,6 +912,147 @@ ${themeBody}`;
|
|
|
876
912
|
rmSync(tempDir, { recursive: true, force: true });
|
|
877
913
|
}
|
|
878
914
|
}
|
|
915
|
+
var COLOR_UTILITIES = [
|
|
916
|
+
"bg",
|
|
917
|
+
"text",
|
|
918
|
+
"border",
|
|
919
|
+
"ring",
|
|
920
|
+
"outline",
|
|
921
|
+
"fill",
|
|
922
|
+
"stroke",
|
|
923
|
+
"accent",
|
|
924
|
+
"caret",
|
|
925
|
+
"decoration",
|
|
926
|
+
"divide",
|
|
927
|
+
"shadow",
|
|
928
|
+
"placeholder"
|
|
929
|
+
];
|
|
930
|
+
var SPACING_UTILITIES = [
|
|
931
|
+
"p",
|
|
932
|
+
"px",
|
|
933
|
+
"py",
|
|
934
|
+
"pt",
|
|
935
|
+
"pr",
|
|
936
|
+
"pb",
|
|
937
|
+
"pl",
|
|
938
|
+
"m",
|
|
939
|
+
"mx",
|
|
940
|
+
"my",
|
|
941
|
+
"mt",
|
|
942
|
+
"mr",
|
|
943
|
+
"mb",
|
|
944
|
+
"ml",
|
|
945
|
+
"gap",
|
|
946
|
+
"gap-x",
|
|
947
|
+
"gap-y",
|
|
948
|
+
"w",
|
|
949
|
+
"h",
|
|
950
|
+
"size",
|
|
951
|
+
"inset",
|
|
952
|
+
"top",
|
|
953
|
+
"right",
|
|
954
|
+
"bottom",
|
|
955
|
+
"left",
|
|
956
|
+
"space-x",
|
|
957
|
+
"space-y"
|
|
958
|
+
];
|
|
959
|
+
var RADIUS_UTILITIES = [
|
|
960
|
+
"rounded",
|
|
961
|
+
"rounded-t",
|
|
962
|
+
"rounded-r",
|
|
963
|
+
"rounded-b",
|
|
964
|
+
"rounded-l",
|
|
965
|
+
"rounded-tl",
|
|
966
|
+
"rounded-tr",
|
|
967
|
+
"rounded-br",
|
|
968
|
+
"rounded-bl"
|
|
969
|
+
];
|
|
970
|
+
var STATE_VARIANTS = ["hover", "focus-visible", "focus", "active", "dark"];
|
|
971
|
+
function deriveCandidates(themeCSS) {
|
|
972
|
+
const themeVarNames = [];
|
|
973
|
+
const themeBlockRe = /@theme\s*(?:inline\s*)?\{([^}]*)\}/gs;
|
|
974
|
+
let blockMatch;
|
|
975
|
+
while ((blockMatch = themeBlockRe.exec(themeCSS)) !== null) {
|
|
976
|
+
const block = blockMatch[1] ?? "";
|
|
977
|
+
const varRe = /--([a-z][a-z0-9-]*)\s*:/g;
|
|
978
|
+
let varMatch;
|
|
979
|
+
while ((varMatch = varRe.exec(block)) !== null) {
|
|
980
|
+
if (varMatch[1]) themeVarNames.push(varMatch[1]);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
984
|
+
for (const name of themeVarNames) {
|
|
985
|
+
if (name.startsWith("color-")) {
|
|
986
|
+
const slug = name.slice(6);
|
|
987
|
+
for (const p2 of COLOR_UTILITIES) candidates.add(`${p2}-${slug}`);
|
|
988
|
+
} else if (name.startsWith("spacing-")) {
|
|
989
|
+
const slug = name.slice(8);
|
|
990
|
+
for (const p2 of SPACING_UTILITIES) candidates.add(`${p2}-${slug}`);
|
|
991
|
+
} else if (name.startsWith("radius-")) {
|
|
992
|
+
const slug = name.slice(7);
|
|
993
|
+
for (const p2 of RADIUS_UTILITIES) candidates.add(`${p2}-${slug}`);
|
|
994
|
+
} else if (name.startsWith("shadow-") && !/-(blur|spread|offset|color|inset)/.test(name)) {
|
|
995
|
+
candidates.add(`shadow-${name.slice(7)}`);
|
|
996
|
+
} else if (name.startsWith("font-size-")) {
|
|
997
|
+
candidates.add(`text-${name.slice(10)}`);
|
|
998
|
+
} else if (name.startsWith("font-weight-")) {
|
|
999
|
+
candidates.add(`font-${name.slice(12)}`);
|
|
1000
|
+
} else if (name.startsWith("ease-")) {
|
|
1001
|
+
candidates.add(name);
|
|
1002
|
+
} else if (name.startsWith("animate-")) {
|
|
1003
|
+
candidates.add(name);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
const base = [...candidates];
|
|
1007
|
+
for (const variant of STATE_VARIANTS) {
|
|
1008
|
+
for (const c4 of base) {
|
|
1009
|
+
candidates.add(`${variant}:${c4}`);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return [...candidates];
|
|
1013
|
+
}
|
|
1014
|
+
async function registryToDocumentation(registry2, options = {}) {
|
|
1015
|
+
const { minify = true } = options;
|
|
1016
|
+
const themeBody = registryToTailwind(registry2, { includeImport: false });
|
|
1017
|
+
const candidates = deriveCandidates(themeBody);
|
|
1018
|
+
const { mkdtempSync, writeFileSync: writeFileSync2, rmSync } = await import("fs");
|
|
1019
|
+
const { join: join15, dirname: dirname4 } = await import("path");
|
|
1020
|
+
const { createRequire: createRequire2 } = await import("module");
|
|
1021
|
+
const require2 = createRequire2(import.meta.url);
|
|
1022
|
+
let pkgDir;
|
|
1023
|
+
try {
|
|
1024
|
+
const pkgJsonPath = require2.resolve("@tailwindcss/cli/package.json");
|
|
1025
|
+
pkgDir = dirname4(pkgJsonPath);
|
|
1026
|
+
} catch {
|
|
1027
|
+
throw new Error(
|
|
1028
|
+
"Failed to resolve @tailwindcss/cli -- install it to generate documentation CSS"
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
const tempDir = mkdtempSync(join15(pkgDir, ".tmp-doc-compile-"));
|
|
1032
|
+
const candidateFile = join15(tempDir, "candidates.txt");
|
|
1033
|
+
writeFileSync2(candidateFile, candidates.join("\n"));
|
|
1034
|
+
const sourceDirective = `@source "${candidateFile}";`;
|
|
1035
|
+
const input = `@import "tailwindcss" source(none);
|
|
1036
|
+
${sourceDirective}
|
|
1037
|
+
${themeBody}`;
|
|
1038
|
+
const tempInput = join15(tempDir, "input.css");
|
|
1039
|
+
const tempOutput = join15(tempDir, "output.css");
|
|
1040
|
+
try {
|
|
1041
|
+
writeFileSync2(tempInput, input);
|
|
1042
|
+
const { execFileSync } = await import("child_process");
|
|
1043
|
+
const binPath = join15(pkgDir, "dist", "index.mjs");
|
|
1044
|
+
const args = [binPath, "-i", tempInput, "-o", tempOutput];
|
|
1045
|
+
if (minify) args.push("--minify");
|
|
1046
|
+
execFileSync("node", args, { stdio: "pipe", timeout: 6e4, cwd: pkgDir });
|
|
1047
|
+
const { readFileSync: readFileSync3 } = await import("fs");
|
|
1048
|
+
return readFileSync3(tempOutput, "utf-8");
|
|
1049
|
+
} catch (error47) {
|
|
1050
|
+
const message = error47 instanceof Error ? error47.message : String(error47);
|
|
1051
|
+
throw new Error(`Failed to compile documentation CSS: ${message}`);
|
|
1052
|
+
} finally {
|
|
1053
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
879
1056
|
|
|
880
1057
|
// ../design-tokens/src/exporters/typescript.ts
|
|
881
1058
|
function tokenValueToTS(token) {
|
|
@@ -910,6 +1087,13 @@ function escapeStringValue(value) {
|
|
|
910
1087
|
}
|
|
911
1088
|
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
912
1089
|
}
|
|
1090
|
+
var VALID_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
1091
|
+
function namespaceKey(namespace) {
|
|
1092
|
+
return VALID_IDENTIFIER.test(namespace) ? namespace : `'${namespace}'`;
|
|
1093
|
+
}
|
|
1094
|
+
function namespaceAccess(namespace) {
|
|
1095
|
+
return VALID_IDENTIFIER.test(namespace) ? `tokens.${namespace}` : `tokens['${namespace}']`;
|
|
1096
|
+
}
|
|
913
1097
|
function namespaceToTypeName(namespace) {
|
|
914
1098
|
return namespace.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
915
1099
|
}
|
|
@@ -930,7 +1114,7 @@ function generateTokensObject(tokensByNamespace, includeJSDoc) {
|
|
|
930
1114
|
const namespaces = Array.from(tokensByNamespace.keys()).sort();
|
|
931
1115
|
for (const namespace of namespaces) {
|
|
932
1116
|
const tokens = tokensByNamespace.get(namespace) || [];
|
|
933
|
-
lines.push(` ${namespace}: {`);
|
|
1117
|
+
lines.push(` ${namespaceKey(namespace)}: {`);
|
|
934
1118
|
for (const token of tokens) {
|
|
935
1119
|
const value = tokenValueToTS(token);
|
|
936
1120
|
if (includeJSDoc && token.semanticMeaning) {
|
|
@@ -949,7 +1133,7 @@ function generateTypeAliases(namespaces) {
|
|
|
949
1133
|
lines.push("");
|
|
950
1134
|
for (const namespace of namespaces) {
|
|
951
1135
|
const typeName = `${namespaceToTypeName(namespace)}Token`;
|
|
952
|
-
lines.push(`export type ${typeName} = keyof typeof
|
|
1136
|
+
lines.push(`export type ${typeName} = keyof (typeof ${namespaceAccess(namespace)});`);
|
|
953
1137
|
}
|
|
954
1138
|
if (namespaces.length > 0) {
|
|
955
1139
|
lines.push("");
|
|
@@ -1124,15 +1308,21 @@ var DEPTH_LEVELS = [
|
|
|
1124
1308
|
"tooltip",
|
|
1125
1309
|
"overlay"
|
|
1126
1310
|
];
|
|
1127
|
-
var MOTION_DURATION_SCALE = [
|
|
1311
|
+
var MOTION_DURATION_SCALE = [
|
|
1312
|
+
"instant",
|
|
1313
|
+
"micro",
|
|
1314
|
+
"fast",
|
|
1315
|
+
"moderate",
|
|
1316
|
+
"normal",
|
|
1317
|
+
"slow"
|
|
1318
|
+
];
|
|
1128
1319
|
var EASING_CURVES = [
|
|
1320
|
+
"standard",
|
|
1321
|
+
"enter",
|
|
1322
|
+
"exit",
|
|
1129
1323
|
"linear",
|
|
1130
|
-
"
|
|
1131
|
-
"
|
|
1132
|
-
"ease-in-out",
|
|
1133
|
-
"productive",
|
|
1134
|
-
"expressive",
|
|
1135
|
-
"spring"
|
|
1324
|
+
"spring-smooth",
|
|
1325
|
+
"spring-snappy"
|
|
1136
1326
|
];
|
|
1137
1327
|
var BREAKPOINT_SCALE = ["sm", "md", "lg", "xl", "2xl"];
|
|
1138
1328
|
|
|
@@ -21442,6 +21632,13 @@ var ExampleSchema = external_exports.object({
|
|
|
21442
21632
|
description: external_exports.string().optional()
|
|
21443
21633
|
});
|
|
21444
21634
|
var ColorIntelligenceSchema = external_exports.object({
|
|
21635
|
+
// Designer-facing evocative handle ("Aged Terracotta", "Solar Citrine") from
|
|
21636
|
+
// the intelligence generator. Language, not identity: the deterministic
|
|
21637
|
+
// `name` on ColorValue is the stable, parseable address; `label` is the
|
|
21638
|
+
// voice. Optional because pre-label intelligence persists in Vectorize and
|
|
21639
|
+
// token files. Backported from platform's generateColorIntelligence, which
|
|
21640
|
+
// requires it on generation.
|
|
21641
|
+
label: external_exports.string().optional(),
|
|
21445
21642
|
reasoning: external_exports.string(),
|
|
21446
21643
|
emotionalImpact: external_exports.string(),
|
|
21447
21644
|
culturalContext: external_exports.string(),
|
|
@@ -21684,7 +21881,7 @@ var TokenSchema = external_exports.object({
|
|
|
21684
21881
|
motionIntent: external_exports.enum(["enter", "exit", "emphasis", "transition"]).optional(),
|
|
21685
21882
|
easingCurve: external_exports.tuple([external_exports.number(), external_exports.number(), external_exports.number(), external_exports.number()]).optional(),
|
|
21686
21883
|
// cubicBezier [x1, y1, x2, y2]
|
|
21687
|
-
easingName: external_exports.enum(["
|
|
21884
|
+
easingName: external_exports.enum(["standard", "enter", "exit", "linear", "spring-smooth", "spring-snappy"]).optional(),
|
|
21688
21885
|
delayMs: external_exports.number().optional(),
|
|
21689
21886
|
// Delay before animation starts
|
|
21690
21887
|
// Keyframe tokens (CSS @keyframes content / animation step definitions)
|
|
@@ -22301,78 +22498,216 @@ var DEFAULT_SHADOW_DEFINITIONS = {
|
|
|
22301
22498
|
};
|
|
22302
22499
|
var DEFAULT_DURATION_DEFINITIONS = {
|
|
22303
22500
|
instant: {
|
|
22304
|
-
|
|
22305
|
-
|
|
22306
|
-
|
|
22501
|
+
ms: 0,
|
|
22502
|
+
band: "",
|
|
22503
|
+
meaning: "No perceptible transition. Cursor changes, text selection, badge counts. Below all perception -- there is nothing to track, so nothing is communicated.",
|
|
22504
|
+
contexts: ["disabled-motion", "prefers-reduced-motion", "cursor", "badge-count"],
|
|
22505
|
+
motionIntent: "transition"
|
|
22506
|
+
},
|
|
22507
|
+
micro: {
|
|
22508
|
+
ms: 100,
|
|
22509
|
+
band: "at the instantaneous threshold (Nielsen 0.1s)",
|
|
22510
|
+
meaning: "Immediate but visible. Focus rings and press feedback. At the instantaneous threshold -- acknowledgment that input landed, not communication of a change.",
|
|
22511
|
+
contexts: ["focus", "press", "micro-feedback"],
|
|
22307
22512
|
motionIntent: "transition"
|
|
22308
22513
|
},
|
|
22309
22514
|
fast: {
|
|
22310
|
-
|
|
22311
|
-
|
|
22312
|
-
|
|
22515
|
+
ms: 150,
|
|
22516
|
+
band: "below the communicative window",
|
|
22517
|
+
meaning: "Hover states. The cursor is already there, so the response must match its speed. Below the communicative window -- acknowledgment, not communication.",
|
|
22518
|
+
contexts: ["hover", "micro-feedback"],
|
|
22313
22519
|
motionIntent: "transition"
|
|
22314
22520
|
},
|
|
22315
|
-
|
|
22316
|
-
|
|
22317
|
-
|
|
22318
|
-
|
|
22521
|
+
moderate: {
|
|
22522
|
+
ms: 250,
|
|
22523
|
+
band: "communicative (~200-300ms)",
|
|
22524
|
+
meaning: "Dropdowns, tab switches, small reveals. The communicative window: fast enough to feel responsive, slow enough for the eye to track a trajectory and build a spatial model.",
|
|
22525
|
+
contexts: ["dropdowns", "tab-switches", "small-reveals"],
|
|
22319
22526
|
motionIntent: "transition"
|
|
22320
22527
|
},
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
|
|
22324
|
-
|
|
22528
|
+
normal: {
|
|
22529
|
+
ms: 350,
|
|
22530
|
+
band: "communicative, larger movement",
|
|
22531
|
+
meaning: "The workhorse -- modal entrances, toggles, standard state transitions. The communicative window for larger movement.",
|
|
22532
|
+
contexts: ["modals", "toggles", "state-changes"],
|
|
22325
22533
|
motionIntent: "enter"
|
|
22326
22534
|
},
|
|
22327
|
-
|
|
22328
|
-
|
|
22329
|
-
|
|
22330
|
-
|
|
22331
|
-
|
|
22535
|
+
slow: {
|
|
22536
|
+
ms: 500,
|
|
22537
|
+
band: "at the sluggish boundary",
|
|
22538
|
+
meaning: "Sheets, page transitions, large spatial movement where the user needs orientation. At the sluggish boundary -- the ceiling for anything but full-screen spatial transitions.",
|
|
22539
|
+
contexts: ["sheets", "page-transitions", "large-spatial-movement"],
|
|
22540
|
+
motionIntent: "enter"
|
|
22332
22541
|
}
|
|
22333
22542
|
};
|
|
22334
22543
|
var DEFAULT_EASING_DEFINITIONS = {
|
|
22544
|
+
standard: {
|
|
22545
|
+
curve: [0.25, 0.1, 0.25, 1],
|
|
22546
|
+
meaning: "Precision -- arrives exactly where it should, engineered rather than thrown. Decelerates into its final position. General-purpose state transitions and hover.",
|
|
22547
|
+
contexts: ["state-changes", "hover", "general-purpose"],
|
|
22548
|
+
css: "cubic-bezier(0.25, 0.1, 0.25, 1)"
|
|
22549
|
+
},
|
|
22550
|
+
enter: {
|
|
22551
|
+
curve: [0, 0, 0.2, 1],
|
|
22552
|
+
meaning: "Arrival, welcome, settling into place. The fast start communicates responsiveness; the slow finish communicates care. Anything entering the viewport. Paired with `exit` as a deliberately asymmetric couple. (Dragicevic 2011: slow-in/slow-out outperforms constant speed for tracking.)",
|
|
22553
|
+
contexts: ["enter-animations", "elements-appearing"],
|
|
22554
|
+
css: "cubic-bezier(0, 0, 0.2, 1)"
|
|
22555
|
+
},
|
|
22556
|
+
exit: {
|
|
22557
|
+
curve: [0.4, 0, 1, 1],
|
|
22558
|
+
meaning: "Withdrawal, giving space. The brief hesitation acknowledges the user; the fast departure avoids lingering. Anything leaving the viewport. Paired with `enter` as a deliberately asymmetric couple -- exits are faster than entrances by design.",
|
|
22559
|
+
contexts: ["exit-animations", "elements-leaving"],
|
|
22560
|
+
css: "cubic-bezier(0.4, 0, 1, 1)"
|
|
22561
|
+
},
|
|
22335
22562
|
linear: {
|
|
22336
22563
|
curve: [0, 0, 1, 1],
|
|
22337
|
-
meaning: "
|
|
22338
|
-
contexts: ["progress-bars", "loading-spinners", "opacity-fades"],
|
|
22564
|
+
meaning: "Mechanical, procedural, without personality -- a process, not a gesture. Progress and loading, where the system is working rather than interacting. Never for interactive spatial transitions.",
|
|
22565
|
+
contexts: ["progress-bars", "loading-spinners", "opacity-fades", "focus-ring-fade"],
|
|
22339
22566
|
css: "linear"
|
|
22340
22567
|
},
|
|
22341
|
-
"
|
|
22342
|
-
curve: [0.
|
|
22343
|
-
meaning: "
|
|
22344
|
-
contexts: ["
|
|
22345
|
-
css: "cubic-bezier(0.
|
|
22568
|
+
"spring-smooth": {
|
|
22569
|
+
curve: [0.2, 0.9, 0.3, 1],
|
|
22570
|
+
meaning: "Alive, coming physically to rest -- a critically-damped spring with no overshoot. Page transitions, sheets, large tracked spatial movement. (Johansson 1973 / Pratt 2010: animate motion is perceived as alive and captures attention.)",
|
|
22571
|
+
contexts: ["page-transitions", "sheets", "large-spatial-movement"],
|
|
22572
|
+
css: "cubic-bezier(0.2, 0.9, 0.3, 1)"
|
|
22346
22573
|
},
|
|
22347
|
-
"
|
|
22348
|
-
curve: [0, 0, 0.
|
|
22349
|
-
meaning: "
|
|
22350
|
-
contexts: ["
|
|
22351
|
-
css: "cubic-bezier(0, 0, 0.
|
|
22352
|
-
}
|
|
22353
|
-
|
|
22354
|
-
|
|
22355
|
-
|
|
22356
|
-
|
|
22357
|
-
|
|
22358
|
-
|
|
22359
|
-
|
|
22360
|
-
|
|
22361
|
-
|
|
22362
|
-
|
|
22363
|
-
|
|
22364
|
-
},
|
|
22365
|
-
|
|
22366
|
-
|
|
22367
|
-
|
|
22368
|
-
|
|
22369
|
-
|
|
22370
|
-
|
|
22371
|
-
|
|
22372
|
-
|
|
22373
|
-
|
|
22374
|
-
|
|
22375
|
-
|
|
22574
|
+
"spring-snappy": {
|
|
22575
|
+
curve: [0.2, 0.8, 0.2, 1],
|
|
22576
|
+
meaning: "Alive, tight, following input closely -- a tighter spring with less settle and no overshoot. Toggles, presses, interactions that track input.",
|
|
22577
|
+
contexts: ["toggles", "presses", "input-tracking"],
|
|
22578
|
+
css: "cubic-bezier(0.2, 0.8, 0.2, 1)"
|
|
22579
|
+
}
|
|
22580
|
+
};
|
|
22581
|
+
var DEFAULT_MOTION_SEMANTIC_MAPPINGS = {
|
|
22582
|
+
hover: {
|
|
22583
|
+
properties: ["color", "background-color", "border-color"],
|
|
22584
|
+
durationTier: "fast",
|
|
22585
|
+
curve: "standard",
|
|
22586
|
+
reducedMotion: null,
|
|
22587
|
+
category: "interaction",
|
|
22588
|
+
sizeReasoning: "Colour only, no movement -- the cursor is already on target, so the response matches its speed at the fast tier.",
|
|
22589
|
+
meaning: "Hover-state colour transition. Acknowledges pointer presence.",
|
|
22590
|
+
contexts: ["hover", "links", "interactive-surfaces"]
|
|
22591
|
+
},
|
|
22592
|
+
focus: {
|
|
22593
|
+
properties: ["box-shadow", "outline-color"],
|
|
22594
|
+
durationTier: "micro",
|
|
22595
|
+
curve: "linear",
|
|
22596
|
+
reducedMotion: null,
|
|
22597
|
+
category: "interaction",
|
|
22598
|
+
sizeReasoning: "A ring appearing, not moving -- micro tier at linear velocity reads as the system marking focus, not a gesture. (Tailwind ring is box-shadow.)",
|
|
22599
|
+
meaning: "Focus-ring transition. Marks the focused element.",
|
|
22600
|
+
contexts: ["focus-visible", "keyboard-navigation"]
|
|
22601
|
+
},
|
|
22602
|
+
press: {
|
|
22603
|
+
properties: ["transform", "color", "background-color"],
|
|
22604
|
+
durationTier: "micro",
|
|
22605
|
+
curve: "spring-snappy",
|
|
22606
|
+
reducedMotion: { properties: ["color", "background-color"] },
|
|
22607
|
+
category: "interaction",
|
|
22608
|
+
sizeReasoning: "The fastest, tightest feedback -- micro tier with a snappy spring follows the finger. Under reduced motion the transform drops; the colour change survives.",
|
|
22609
|
+
meaning: "Press/active feedback. Confirms the input was received.",
|
|
22610
|
+
contexts: ["press", "active", "buttons"]
|
|
22611
|
+
},
|
|
22612
|
+
toggle: {
|
|
22613
|
+
properties: ["color", "background-color", "transform"],
|
|
22614
|
+
durationTier: "moderate",
|
|
22615
|
+
curve: "spring-snappy",
|
|
22616
|
+
reducedMotion: { properties: ["color", "background-color"] },
|
|
22617
|
+
category: "interaction",
|
|
22618
|
+
sizeReasoning: "A thumb travelling a track is a small, tracked movement -- moderate tier, snappy spring. Reduced motion drops the transform to a colour cross-fade.",
|
|
22619
|
+
meaning: "Toggle/switch state change. Shows the new state.",
|
|
22620
|
+
contexts: ["switch", "toggle", "checkbox"]
|
|
22621
|
+
},
|
|
22622
|
+
"dropdown-in": {
|
|
22623
|
+
properties: ["opacity", "transform"],
|
|
22624
|
+
durationTier: "moderate",
|
|
22625
|
+
curve: "enter",
|
|
22626
|
+
reducedMotion: { properties: ["opacity"], ms: 100 },
|
|
22627
|
+
category: "enter",
|
|
22628
|
+
sizeReasoning: "A dropdown is small and travels a short distance -- moderate tier, one step below the modal, with the arrival curve.",
|
|
22629
|
+
meaning: "Dropdown/menu entrance.",
|
|
22630
|
+
contexts: ["dropdown", "menu", "select", "popover"]
|
|
22631
|
+
},
|
|
22632
|
+
"dropdown-out": {
|
|
22633
|
+
properties: ["opacity", "transform"],
|
|
22634
|
+
durationTier: "fast",
|
|
22635
|
+
curve: "exit",
|
|
22636
|
+
reducedMotion: { properties: ["opacity"], ms: 100 },
|
|
22637
|
+
category: "exit",
|
|
22638
|
+
sizeReasoning: "The exit of a small element -- fast tier (shorter than its moderate entrance) with the departure curve. The user already chose to dismiss it.",
|
|
22639
|
+
meaning: "Dropdown/menu exit.",
|
|
22640
|
+
contexts: ["dropdown", "menu", "select", "popover"]
|
|
22641
|
+
},
|
|
22642
|
+
"modal-in": {
|
|
22643
|
+
properties: ["opacity", "transform"],
|
|
22644
|
+
durationTier: "normal",
|
|
22645
|
+
curve: "enter",
|
|
22646
|
+
reducedMotion: { properties: ["opacity"], ms: 150 },
|
|
22647
|
+
category: "enter",
|
|
22648
|
+
sizeReasoning: "A modal is larger and travels farther than a dropdown -- normal tier, one step up, with the arrival curve. Size and distance produce the longer duration.",
|
|
22649
|
+
meaning: "Modal/dialog entrance.",
|
|
22650
|
+
contexts: ["modal", "dialog", "alert-dialog"]
|
|
22651
|
+
},
|
|
22652
|
+
"modal-out": {
|
|
22653
|
+
properties: ["opacity", "transform"],
|
|
22654
|
+
durationTier: "moderate",
|
|
22655
|
+
curve: "exit",
|
|
22656
|
+
reducedMotion: { properties: ["opacity"], ms: 150 },
|
|
22657
|
+
category: "exit",
|
|
22658
|
+
sizeReasoning: "The modal exit -- moderate tier (shorter than its normal entrance) with the departure curve.",
|
|
22659
|
+
meaning: "Modal/dialog exit.",
|
|
22660
|
+
contexts: ["modal", "dialog", "alert-dialog"]
|
|
22661
|
+
},
|
|
22662
|
+
"sheet-in": {
|
|
22663
|
+
properties: ["transform"],
|
|
22664
|
+
durationTier: "slow",
|
|
22665
|
+
curve: "spring-smooth",
|
|
22666
|
+
reducedMotion: { properties: ["opacity"], ms: 250 },
|
|
22667
|
+
category: "enter",
|
|
22668
|
+
sizeReasoning: "A sheet is the largest spatial movement -- slow tier with the physical settle of a smooth spring, because the user must track it into place. Reduced motion becomes a cross-fade.",
|
|
22669
|
+
meaning: "Sheet/drawer entrance.",
|
|
22670
|
+
contexts: ["sheet", "drawer", "side-panel"]
|
|
22671
|
+
},
|
|
22672
|
+
"sheet-out": {
|
|
22673
|
+
properties: ["transform"],
|
|
22674
|
+
durationTier: "normal",
|
|
22675
|
+
curve: "exit",
|
|
22676
|
+
reducedMotion: { properties: ["opacity"], ms: 250 },
|
|
22677
|
+
category: "exit",
|
|
22678
|
+
sizeReasoning: "The sheet exit -- normal tier (shorter than its slow entrance) with the departure curve.",
|
|
22679
|
+
meaning: "Sheet/drawer exit.",
|
|
22680
|
+
contexts: ["sheet", "drawer", "side-panel"]
|
|
22681
|
+
},
|
|
22682
|
+
expand: {
|
|
22683
|
+
properties: ["grid-template-rows", "opacity"],
|
|
22684
|
+
durationTier: "normal",
|
|
22685
|
+
curve: "enter",
|
|
22686
|
+
reducedMotion: { properties: ["opacity"] },
|
|
22687
|
+
category: "enter",
|
|
22688
|
+
sizeReasoning: "Content unfolding to its natural height -- normal tier with the arrival curve. Transitions grid-template-rows (0fr->1fr), the transitionable stand-in for height:auto. Reduced motion snaps the rows and fades opacity.",
|
|
22689
|
+
meaning: "Expand/reveal collapsible content (accordion, disclosure).",
|
|
22690
|
+
contexts: ["accordion", "collapsible", "disclosure"]
|
|
22691
|
+
},
|
|
22692
|
+
collapse: {
|
|
22693
|
+
properties: ["grid-template-rows", "opacity"],
|
|
22694
|
+
durationTier: "moderate",
|
|
22695
|
+
curve: "exit",
|
|
22696
|
+
reducedMotion: { properties: ["opacity"] },
|
|
22697
|
+
category: "exit",
|
|
22698
|
+
sizeReasoning: "Content folding away -- moderate tier (shorter than its normal expansion) with the departure curve. Reduced motion snaps the rows.",
|
|
22699
|
+
meaning: "Collapse/hide collapsible content (accordion, disclosure).",
|
|
22700
|
+
contexts: ["accordion", "collapsible", "disclosure"]
|
|
22701
|
+
},
|
|
22702
|
+
page: {
|
|
22703
|
+
properties: ["opacity", "transform"],
|
|
22704
|
+
durationTier: "slow",
|
|
22705
|
+
curve: "spring-smooth",
|
|
22706
|
+
reducedMotion: { properties: ["opacity"], ms: 200 },
|
|
22707
|
+
category: "enter",
|
|
22708
|
+
sizeReasoning: "A whole-view transition -- slow tier with the physical settle of a smooth spring, because the user reorients across the largest possible distance.",
|
|
22709
|
+
meaning: "Page/route transition.",
|
|
22710
|
+
contexts: ["page-transition", "route-change", "view-switch"]
|
|
22376
22711
|
}
|
|
22377
22712
|
};
|
|
22378
22713
|
var DEFAULT_DELAY_DEFINITIONS = {
|
|
@@ -24997,7 +25332,14 @@ function tryParseUnit(cssValue, registry2 = DEFAULT_UNITS) {
|
|
|
24997
25332
|
}
|
|
24998
25333
|
|
|
24999
25334
|
// ../design-tokens/src/generators/motion.ts
|
|
25000
|
-
|
|
25335
|
+
var LEGACY_EASING_REMAP = {
|
|
25336
|
+
linear: "linear",
|
|
25337
|
+
"ease-out": "enter",
|
|
25338
|
+
"ease-in": "exit",
|
|
25339
|
+
"ease-in-out": "standard",
|
|
25340
|
+
spring: "spring-snappy"
|
|
25341
|
+
};
|
|
25342
|
+
function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs, semanticMappings) {
|
|
25001
25343
|
const tokens = [];
|
|
25002
25344
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
25003
25345
|
const { baseTransitionDuration, progressionRatio } = config2;
|
|
@@ -25009,52 +25351,44 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25009
25351
|
value: `${baseTransitionDuration}ms`,
|
|
25010
25352
|
category: "motion",
|
|
25011
25353
|
namespace: "motion",
|
|
25012
|
-
semanticMeaning: "
|
|
25013
|
-
usageContext: ["calculation-reference"],
|
|
25354
|
+
semanticMeaning: "Legacy base transition duration. The perceptual duration scale (motion-duration-*) no longer derives from this; retained only as a reference value and delay-progression base.",
|
|
25355
|
+
usageContext: ["calculation-reference", "delay-base"],
|
|
25014
25356
|
progressionSystem: progressionRatio,
|
|
25015
|
-
description: `Base duration (${baseTransitionDuration}ms).
|
|
25357
|
+
description: `Base duration (${baseTransitionDuration}ms). Delay tokens use ${progressionRatio} progression (ratio ${ratioVal}); duration tiers are perceptually derived literals.`,
|
|
25016
25358
|
generatedAt: timestamp,
|
|
25017
25359
|
containerQueryAware: false,
|
|
25018
25360
|
reducedMotionAware: true,
|
|
25019
25361
|
userOverride: null,
|
|
25020
25362
|
usagePatterns: {
|
|
25021
|
-
do: ["Reference as the
|
|
25022
|
-
never: ["
|
|
25363
|
+
do: ["Reference as the delay-progression base"],
|
|
25364
|
+
never: ["Assume the perceptual duration tiers derive from this"]
|
|
25023
25365
|
}
|
|
25024
25366
|
});
|
|
25025
25367
|
for (const scale2 of MOTION_DURATION_SCALE) {
|
|
25026
25368
|
const def = durationDefs[scale2];
|
|
25027
25369
|
if (!def) continue;
|
|
25028
25370
|
const scaleIndex = MOTION_DURATION_SCALE.indexOf(scale2);
|
|
25029
|
-
|
|
25030
|
-
|
|
25031
|
-
if (def.step === "instant") {
|
|
25032
|
-
durationMs = 0;
|
|
25033
|
-
mathRelationship = "0";
|
|
25034
|
-
} else {
|
|
25035
|
-
durationMs = Math.round(computeStep(baseTransitionDuration, def.step));
|
|
25036
|
-
mathRelationship = def.step === 0 ? `${baseTransitionDuration}ms (base)` : `${baseTransitionDuration} \xD7 ${ratioVal}^${def.step}`;
|
|
25037
|
-
}
|
|
25371
|
+
const durationMs = def.ms;
|
|
25372
|
+
const bandNote = def.band ? ` Band: ${def.band}.` : "";
|
|
25038
25373
|
tokens.push({
|
|
25039
25374
|
name: `motion-duration-${scale2}`,
|
|
25040
|
-
value:
|
|
25375
|
+
value: `${durationMs}ms`,
|
|
25041
25376
|
category: "motion",
|
|
25042
25377
|
namespace: "motion",
|
|
25043
|
-
semanticMeaning: def.meaning
|
|
25378
|
+
semanticMeaning: `${def.meaning}${bandNote}`,
|
|
25044
25379
|
usageContext: def.contexts,
|
|
25045
25380
|
scalePosition: scaleIndex,
|
|
25046
|
-
progressionSystem: progressionRatio,
|
|
25047
25381
|
motionIntent: def.motionIntent,
|
|
25048
25382
|
motionDuration: durationMs,
|
|
25049
|
-
mathRelationship
|
|
25050
|
-
dependsOn:
|
|
25051
|
-
description: `Duration ${scale2}: ${durationMs}ms
|
|
25383
|
+
mathRelationship: def.band ? `${durationMs}ms (perceptual: ${def.band})` : `${durationMs}ms`,
|
|
25384
|
+
dependsOn: [],
|
|
25385
|
+
description: `Duration ${scale2}: ${durationMs}ms.${bandNote} ${def.meaning}`,
|
|
25052
25386
|
generatedAt: timestamp,
|
|
25053
25387
|
containerQueryAware: false,
|
|
25054
25388
|
reducedMotionAware: true,
|
|
25055
25389
|
userOverride: null,
|
|
25056
25390
|
usagePatterns: {
|
|
25057
|
-
do: scale2 === "instant" ? ["Use for prefers-reduced-motion", "Use for disabled animations"] : scale2 === "
|
|
25391
|
+
do: scale2 === "instant" ? ["Use for prefers-reduced-motion", "Use for disabled animations"] : scale2 === "micro" || scale2 === "fast" ? ["Use for acknowledgment feedback (hover, focus, press)"] : ["Use for communicative transitions where the user must track the change"],
|
|
25058
25392
|
never: ["Ignore prefers-reduced-motion", "Use slow animations for frequent actions"]
|
|
25059
25393
|
}
|
|
25060
25394
|
});
|
|
@@ -25077,10 +25411,10 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25077
25411
|
reducedMotionAware: true,
|
|
25078
25412
|
userOverride: null,
|
|
25079
25413
|
usagePatterns: {
|
|
25080
|
-
do: curve === "linear" ? ["Use for
|
|
25414
|
+
do: curve === "linear" ? ["Use for progress and loading, where the system is working not interacting"] : curve === "enter" ? ["Use for anything entering the viewport"] : curve === "exit" ? ["Use for anything leaving the viewport"] : ["Match the curve register to the interaction feel"],
|
|
25081
25415
|
never: [
|
|
25082
|
-
"Use
|
|
25083
|
-
"Use
|
|
25416
|
+
"Use exit for entering (arrives reluctantly)",
|
|
25417
|
+
"Use linear for interactive spatial transitions (reads as mechanical)"
|
|
25084
25418
|
]
|
|
25085
25419
|
}
|
|
25086
25420
|
});
|
|
@@ -25417,13 +25751,13 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25417
25751
|
} else {
|
|
25418
25752
|
const durationDef = durationDefs[anim.duration];
|
|
25419
25753
|
if (!durationDef) continue;
|
|
25420
|
-
|
|
25421
|
-
durationValue = `${durationMs}ms`;
|
|
25754
|
+
durationValue = `${durationDef.ms}ms`;
|
|
25422
25755
|
durationRef = `var(--motion-duration-${anim.duration})`;
|
|
25423
25756
|
}
|
|
25424
|
-
const
|
|
25757
|
+
const easingKey = LEGACY_EASING_REMAP[anim.easing] ?? anim.easing;
|
|
25758
|
+
const easingDef = easingDefs[easingKey];
|
|
25425
25759
|
if (!easingDef) continue;
|
|
25426
|
-
const easingRef = `var(--motion-easing-${
|
|
25760
|
+
const easingRef = `var(--motion-easing-${easingKey})`;
|
|
25427
25761
|
const iterations = anim.iterations || "";
|
|
25428
25762
|
const animValue = iterations ? `${anim.keyframe} ${durationRef} ${easingRef} ${iterations}` : `${anim.keyframe} ${durationRef} ${easingRef}`;
|
|
25429
25763
|
tokens.push({
|
|
@@ -25441,7 +25775,7 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25441
25775
|
dependsOn: [
|
|
25442
25776
|
`motion-keyframe-${anim.keyframe}`,
|
|
25443
25777
|
...anim.duration.endsWith("s") || anim.duration.endsWith("ms") ? [] : [`motion-duration-${anim.duration}`],
|
|
25444
|
-
`motion-easing-${
|
|
25778
|
+
`motion-easing-${easingKey}`
|
|
25445
25779
|
],
|
|
25446
25780
|
description: `Animation ${anim.name}: ${anim.meaning}`,
|
|
25447
25781
|
generatedAt: timestamp,
|
|
@@ -25489,14 +25823,10 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25489
25823
|
];
|
|
25490
25824
|
for (const comp of composites2) {
|
|
25491
25825
|
const durationDef = durationDefs[comp.duration];
|
|
25492
|
-
const
|
|
25826
|
+
const easingKey = LEGACY_EASING_REMAP[comp.easing] ?? comp.easing;
|
|
25827
|
+
const easingDef = easingDefs[easingKey];
|
|
25493
25828
|
if (!durationDef || !easingDef) continue;
|
|
25494
|
-
|
|
25495
|
-
if (durationDef.step === "instant") {
|
|
25496
|
-
durationMs = 0;
|
|
25497
|
-
} else {
|
|
25498
|
-
durationMs = Math.round(computeStep(baseTransitionDuration, durationDef.step));
|
|
25499
|
-
}
|
|
25829
|
+
const durationMs = durationDef.ms;
|
|
25500
25830
|
tokens.push({
|
|
25501
25831
|
name: comp.name,
|
|
25502
25832
|
value: `${durationMs}ms ${easingDef.css}`,
|
|
@@ -25506,27 +25836,54 @@ function generateMotionTokens(config2, durationDefs, easingDefs, delayDefs) {
|
|
|
25506
25836
|
usageContext: comp.contexts,
|
|
25507
25837
|
motionDuration: durationMs,
|
|
25508
25838
|
easingCurve: easingDef.curve,
|
|
25509
|
-
easingName:
|
|
25510
|
-
dependsOn: [`motion-duration-${comp.duration}`, `motion-easing-${
|
|
25511
|
-
description: `${comp.meaning}. Combines ${comp.duration} duration with ${
|
|
25839
|
+
easingName: easingKey,
|
|
25840
|
+
dependsOn: [`motion-duration-${comp.duration}`, `motion-easing-${easingKey}`],
|
|
25841
|
+
description: `${comp.meaning}. Combines ${comp.duration} duration with ${easingKey} easing.`,
|
|
25512
25842
|
generatedAt: timestamp,
|
|
25513
25843
|
containerQueryAware: false,
|
|
25514
25844
|
reducedMotionAware: true,
|
|
25515
25845
|
userOverride: null
|
|
25516
25846
|
});
|
|
25517
25847
|
}
|
|
25848
|
+
for (const [name, mapping] of Object.entries(semanticMappings)) {
|
|
25849
|
+
tokens.push({
|
|
25850
|
+
name: `motion-semantic-${name}`,
|
|
25851
|
+
value: JSON.stringify({
|
|
25852
|
+
properties: mapping.properties,
|
|
25853
|
+
durationTier: mapping.durationTier,
|
|
25854
|
+
curve: mapping.curve,
|
|
25855
|
+
reducedMotion: mapping.reducedMotion
|
|
25856
|
+
}),
|
|
25857
|
+
category: "motion",
|
|
25858
|
+
namespace: "motion",
|
|
25859
|
+
semanticMeaning: `${mapping.meaning} ${mapping.sizeReasoning}`,
|
|
25860
|
+
usageContext: mapping.contexts,
|
|
25861
|
+
motionIntent: mapping.category === "enter" ? "enter" : mapping.category === "exit" ? "exit" : "transition",
|
|
25862
|
+
generateUtilityClass: true,
|
|
25863
|
+
dependsOn: [`motion-duration-${mapping.durationTier}`, `motion-easing-${mapping.curve}`],
|
|
25864
|
+
description: `Semantic motion motion-${name}: ${mapping.properties.join(", ")} over ${mapping.durationTier} with ${mapping.curve}. ${mapping.sizeReasoning}`,
|
|
25865
|
+
generatedAt: timestamp,
|
|
25866
|
+
containerQueryAware: false,
|
|
25867
|
+
reducedMotionAware: true,
|
|
25868
|
+
userOverride: null,
|
|
25869
|
+
usagePatterns: {
|
|
25870
|
+
do: [`Apply class motion-${name} and let a state/presence change trigger the transition`],
|
|
25871
|
+
never: ["Hardcode a raw numeric duration in place of this token"]
|
|
25872
|
+
}
|
|
25873
|
+
});
|
|
25874
|
+
}
|
|
25518
25875
|
tokens.push({
|
|
25519
25876
|
name: "motion-progression",
|
|
25520
25877
|
value: JSON.stringify({
|
|
25521
25878
|
ratio: progressionRatio,
|
|
25522
25879
|
ratioValue: ratioVal,
|
|
25523
25880
|
baseDuration: baseTransitionDuration,
|
|
25524
|
-
note: "
|
|
25881
|
+
note: "Duration tiers are perceptually derived literals (docs/MOTION.md); delay tokens use the workspace progression ratio from the base duration."
|
|
25525
25882
|
}),
|
|
25526
25883
|
category: "motion",
|
|
25527
25884
|
namespace: "motion",
|
|
25528
|
-
semanticMeaning: "Metadata about the motion
|
|
25529
|
-
description: `
|
|
25885
|
+
semanticMeaning: "Metadata about the motion system",
|
|
25886
|
+
description: `Duration tiers are perceptual literals; delays use ${progressionRatio} progression from ${baseTransitionDuration}ms base.`,
|
|
25530
25887
|
generatedAt: timestamp,
|
|
25531
25888
|
containerQueryAware: false,
|
|
25532
25889
|
userOverride: null
|
|
@@ -26436,7 +26793,8 @@ function createGeneratorDefs(colorPaletteBases) {
|
|
|
26436
26793
|
config2,
|
|
26437
26794
|
DEFAULT_DURATION_DEFINITIONS,
|
|
26438
26795
|
DEFAULT_EASING_DEFINITIONS,
|
|
26439
|
-
DEFAULT_DELAY_DEFINITIONS
|
|
26796
|
+
DEFAULT_DELAY_DEFINITIONS,
|
|
26797
|
+
DEFAULT_MOTION_SEMANTIC_MAPPINGS
|
|
26440
26798
|
)
|
|
26441
26799
|
},
|
|
26442
26800
|
{
|
|
@@ -27085,6 +27443,11 @@ async function regenerateOutputs(registry2, input, hooks2 = {}) {
|
|
|
27085
27443
|
await writeFile(join2(outputDir2, "rafters.standalone.css"), compiled);
|
|
27086
27444
|
written.push("rafters.standalone.css");
|
|
27087
27445
|
}
|
|
27446
|
+
if (exports.documentation) {
|
|
27447
|
+
const doc = await registryToDocumentation(registry2);
|
|
27448
|
+
await writeFile(join2(outputDir2, "rafters.documentation.css"), doc);
|
|
27449
|
+
written.push("rafters.documentation.css");
|
|
27450
|
+
}
|
|
27088
27451
|
hooks2.notify?.();
|
|
27089
27452
|
return written;
|
|
27090
27453
|
}
|
|
@@ -27444,7 +27807,7 @@ var RegistryFileSchema = external_exports.object({
|
|
|
27444
27807
|
devDependencies: external_exports.array(external_exports.string()).default([])
|
|
27445
27808
|
// e.g., ["vitest"] - from @devDependencies JSDoc
|
|
27446
27809
|
});
|
|
27447
|
-
var RegistryItemTypeSchema = external_exports.enum(["ui", "primitive", "composite", "rule"]);
|
|
27810
|
+
var RegistryItemTypeSchema = external_exports.enum(["ui", "primitive", "composite", "rule", "substrate"]);
|
|
27448
27811
|
var RegistryItemIntelligenceSchema = external_exports.object({
|
|
27449
27812
|
cognitiveLoad: external_exports.number().optional(),
|
|
27450
27813
|
attentionEconomics: external_exports.string().optional(),
|
|
@@ -27472,7 +27835,8 @@ var RegistryIndexSchema = external_exports.object({
|
|
|
27472
27835
|
components: external_exports.array(external_exports.string()),
|
|
27473
27836
|
primitives: external_exports.array(external_exports.string()),
|
|
27474
27837
|
composites: external_exports.array(external_exports.string()).default([]),
|
|
27475
|
-
rules: external_exports.array(external_exports.string()).default([])
|
|
27838
|
+
rules: external_exports.array(external_exports.string()).default([]),
|
|
27839
|
+
substrate: external_exports.array(external_exports.string()).default([])
|
|
27476
27840
|
});
|
|
27477
27841
|
|
|
27478
27842
|
// src/registry/client.ts
|
|
@@ -27481,7 +27845,8 @@ var REGISTRY_SOURCE = {
|
|
|
27481
27845
|
ui: { folder: "components", label: "Component" },
|
|
27482
27846
|
primitive: { folder: "primitives", label: "Primitive" },
|
|
27483
27847
|
composite: { folder: "composites", label: "Composite" },
|
|
27484
|
-
rule: { folder: "rules", label: "Rule" }
|
|
27848
|
+
rule: { folder: "rules", label: "Rule" },
|
|
27849
|
+
substrate: { folder: "substrate", label: "Substrate" }
|
|
27485
27850
|
};
|
|
27486
27851
|
var FETCH_ORDER = Object.keys(REGISTRY_SOURCE);
|
|
27487
27852
|
var RegistryClient = class {
|
|
@@ -27517,7 +27882,8 @@ var RegistryClient = class {
|
|
|
27517
27882
|
ui: fetchFrom("ui"),
|
|
27518
27883
|
primitive: fetchFrom("primitive"),
|
|
27519
27884
|
composite: fetchFrom("composite"),
|
|
27520
|
-
rule: fetchFrom("rule")
|
|
27885
|
+
rule: fetchFrom("rule"),
|
|
27886
|
+
substrate: fetchFrom("substrate")
|
|
27521
27887
|
};
|
|
27522
27888
|
this.fetchComponent = this.fetchByType.ui;
|
|
27523
27889
|
this.fetchPrimitive = this.fetchByType.primitive;
|
|
@@ -27799,7 +28165,8 @@ var DEFAULT_EXPORTS = {
|
|
|
27799
28165
|
tailwind: true,
|
|
27800
28166
|
typescript: true,
|
|
27801
28167
|
dtcg: false,
|
|
27802
|
-
compiled: false
|
|
28168
|
+
compiled: false,
|
|
28169
|
+
documentation: false
|
|
27803
28170
|
};
|
|
27804
28171
|
var EXPORT_CHOICES = [
|
|
27805
28172
|
{
|
|
@@ -27821,6 +28188,11 @@ var EXPORT_CHOICES = [
|
|
|
27821
28188
|
name: "Standalone CSS (pre-built, no Tailwind required)",
|
|
27822
28189
|
value: "compiled",
|
|
27823
28190
|
checked: false
|
|
28191
|
+
},
|
|
28192
|
+
{
|
|
28193
|
+
name: "Documentation CSS (complete utility surface for docs/previews)",
|
|
28194
|
+
value: "documentation",
|
|
28195
|
+
checked: false
|
|
27824
28196
|
}
|
|
27825
28197
|
];
|
|
27826
28198
|
var FUTURE_EXPORTS = [
|
|
@@ -27844,7 +28216,8 @@ function selectionsToConfig(selections) {
|
|
|
27844
28216
|
tailwind: selections.includes("tailwind"),
|
|
27845
28217
|
typescript: selections.includes("typescript"),
|
|
27846
28218
|
dtcg: selections.includes("dtcg"),
|
|
27847
|
-
compiled: selections.includes("compiled")
|
|
28219
|
+
compiled: selections.includes("compiled"),
|
|
28220
|
+
documentation: selections.includes("documentation")
|
|
27848
28221
|
};
|
|
27849
28222
|
}
|
|
27850
28223
|
|
|
@@ -28488,6 +28861,7 @@ function isSharedFile(path) {
|
|
|
28488
28861
|
}
|
|
28489
28862
|
return false;
|
|
28490
28863
|
}
|
|
28864
|
+
var REACT_FALLBACK_TARGETS = /* @__PURE__ */ new Set(["astro", "vue", "svelte"]);
|
|
28491
28865
|
function selectFilesForFramework(files, target) {
|
|
28492
28866
|
const preferredExt = targetToExtension(target);
|
|
28493
28867
|
const shared = files.filter((f) => isSharedFile(f.path));
|
|
@@ -28495,12 +28869,15 @@ function selectFilesForFramework(files, target) {
|
|
|
28495
28869
|
if (matched.length > 0) {
|
|
28496
28870
|
return { files: [...matched, ...shared], fallback: false };
|
|
28497
28871
|
}
|
|
28498
|
-
if (target
|
|
28872
|
+
if (REACT_FALLBACK_TARGETS.has(target)) {
|
|
28499
28873
|
const fallbackFiles = files.filter((f) => f.path.endsWith(".tsx"));
|
|
28500
28874
|
if (fallbackFiles.length > 0) {
|
|
28501
28875
|
return { files: [...fallbackFiles, ...shared], fallback: true };
|
|
28502
28876
|
}
|
|
28503
28877
|
}
|
|
28878
|
+
if (target !== "react" && !REACT_FALLBACK_TARGETS.has(target)) {
|
|
28879
|
+
return { files: shared, fallback: false };
|
|
28880
|
+
}
|
|
28504
28881
|
return { files, fallback: false };
|
|
28505
28882
|
}
|
|
28506
28883
|
var TARGET_GATED_COMPOSITE_FILES = [
|
|
@@ -28515,12 +28892,13 @@ function selectCompositeFiles(files, target) {
|
|
|
28515
28892
|
var FOLDER_NAMES = /* @__PURE__ */ new Set(["composites"]);
|
|
28516
28893
|
function isAlreadyInstalled(config2, item) {
|
|
28517
28894
|
if (!config2?.installed) return false;
|
|
28518
|
-
const { components, primitives, composites: composites2, rules } = config2.installed;
|
|
28895
|
+
const { components, primitives, composites: composites2, rules, substrate } = config2.installed;
|
|
28519
28896
|
const bucketByType = {
|
|
28520
28897
|
ui: components,
|
|
28521
28898
|
primitive: primitives,
|
|
28522
28899
|
composite: composites2 ?? [],
|
|
28523
|
-
rule: rules ?? []
|
|
28900
|
+
rule: rules ?? [],
|
|
28901
|
+
substrate: substrate ?? []
|
|
28524
28902
|
};
|
|
28525
28903
|
return bucketByType[item.type].includes(item.name);
|
|
28526
28904
|
}
|
|
@@ -28539,11 +28917,13 @@ function trackInstalled(config2, items) {
|
|
|
28539
28917
|
const installed = config2.installed;
|
|
28540
28918
|
if (!installed.composites) installed.composites = [];
|
|
28541
28919
|
if (!installed.rules) installed.rules = [];
|
|
28920
|
+
if (!installed.substrate) installed.substrate = [];
|
|
28542
28921
|
const bucketByType = {
|
|
28543
28922
|
ui: installed.components,
|
|
28544
28923
|
primitive: installed.primitives,
|
|
28545
28924
|
composite: installed.composites,
|
|
28546
|
-
rule: installed.rules
|
|
28925
|
+
rule: installed.rules,
|
|
28926
|
+
substrate: installed.substrate
|
|
28547
28927
|
};
|
|
28548
28928
|
for (const item of items) {
|
|
28549
28929
|
const bucket = bucketByType[item.type];
|
|
@@ -28553,11 +28933,12 @@ function trackInstalled(config2, items) {
|
|
|
28553
28933
|
installed.primitives.sort();
|
|
28554
28934
|
installed.composites.sort();
|
|
28555
28935
|
installed.rules.sort();
|
|
28936
|
+
installed.substrate.sort();
|
|
28556
28937
|
}
|
|
28557
28938
|
function rootFor(field, cwd, fallback) {
|
|
28558
28939
|
return field === void 0 ? fallback : resolveRoot(field, cwd, fallback);
|
|
28559
28940
|
}
|
|
28560
|
-
function transformPath(registryPath, config2, cwd) {
|
|
28941
|
+
function transformPath(registryPath, config2, cwd = process.cwd()) {
|
|
28561
28942
|
if (!config2) return registryPath;
|
|
28562
28943
|
const replacements = [
|
|
28563
28944
|
["components/ui/", config2.componentsPath, "components/ui"],
|
|
@@ -28572,10 +28953,16 @@ function transformPath(registryPath, config2, cwd) {
|
|
|
28572
28953
|
}
|
|
28573
28954
|
return registryPath;
|
|
28574
28955
|
}
|
|
28956
|
+
function substrateProjectPath(registryPath, config2, cwd = process.cwd()) {
|
|
28957
|
+
const componentsResolved = rootFor(config2?.componentsPath, cwd, "components/ui");
|
|
28958
|
+
const sourceRoot = componentsResolved.replace(/\/?components\/ui$/, "");
|
|
28959
|
+
return sourceRoot ? join7(sourceRoot, registryPath) : registryPath;
|
|
28960
|
+
}
|
|
28575
28961
|
function fileExists(cwd, relativePath) {
|
|
28576
28962
|
return existsSync3(join7(cwd, relativePath));
|
|
28577
28963
|
}
|
|
28578
|
-
function transformFileContent(content, config2, fileType = "component", cwd = process.cwd()) {
|
|
28964
|
+
function transformFileContent(content, config2, fileType = "component", cwd = process.cwd(), opts = {}) {
|
|
28965
|
+
const { substrateKinds = [], installPath } = opts;
|
|
28579
28966
|
let transformed = content;
|
|
28580
28967
|
const componentsPath = rootFor(config2?.componentsPath, cwd, "components/ui");
|
|
28581
28968
|
const primitivesPath = rootFor(config2?.primitivesPath, cwd, "lib/primitives");
|
|
@@ -28590,26 +28977,23 @@ function transformFileContent(content, config2, fileType = "component", cwd = pr
|
|
|
28590
28977
|
/from\s+['"]\.\.\/primitives\/([^'"]+)['"]/g,
|
|
28591
28978
|
`from '@/${aliasPrimitives}/$1'`
|
|
28592
28979
|
);
|
|
28593
|
-
const
|
|
28980
|
+
const substrateOwnDir = fileType === "substrate" && installPath ? stripSourceRoot(dirname(installPath)) : null;
|
|
28981
|
+
const aliasSibling = fileType === "primitive" ? aliasPrimitives : substrateOwnDir ?? aliasComponents;
|
|
28594
28982
|
transformed = transformed.replace(/from\s+['"]\.\/([^'"]+)['"]/g, `from '@/${aliasSibling}/$1'`);
|
|
28595
|
-
|
|
28596
|
-
|
|
28597
|
-
|
|
28598
|
-
|
|
28599
|
-
|
|
28600
|
-
|
|
28601
|
-
|
|
28602
|
-
transformed = transformed.replace(
|
|
28603
|
-
/from\s+['"]\.\.\/hooks\/([^'"]+)['"]/g,
|
|
28604
|
-
`from '@/${aliasHooks}/$1'`
|
|
28605
|
-
);
|
|
28983
|
+
if (substrateKinds.length > 0) {
|
|
28984
|
+
const kindAlternation = substrateKinds.join("|");
|
|
28985
|
+
transformed = transformed.replace(
|
|
28986
|
+
new RegExp(`from\\s+['"](?:\\.\\./){1,2}(${kindAlternation})/([^'"]+)['"]`, "g"),
|
|
28987
|
+
"from '@/$1/$2'"
|
|
28988
|
+
);
|
|
28989
|
+
}
|
|
28606
28990
|
transformed = transformed.replace(
|
|
28607
|
-
/from\s+['"]\.\.\/(
|
|
28991
|
+
/from\s+['"]\.\.\/([^'"]+)['"]/g,
|
|
28608
28992
|
`from '@/${aliasComponents}/$1'`
|
|
28609
28993
|
);
|
|
28610
28994
|
return transformed;
|
|
28611
28995
|
}
|
|
28612
|
-
async function installItem(cwd, item, options, config2) {
|
|
28996
|
+
async function installItem(cwd, item, options, config2, substrateKinds = []) {
|
|
28613
28997
|
const installedFiles = [];
|
|
28614
28998
|
let skipped = false;
|
|
28615
28999
|
let filesToInstall = item.files;
|
|
@@ -28625,11 +29009,17 @@ async function installItem(cwd, item, options, config2) {
|
|
|
28625
29009
|
message: `No ${targetToExtension(target)} version available for ${item.name}. Installing React version.`
|
|
28626
29010
|
});
|
|
28627
29011
|
}
|
|
29012
|
+
const hasComponentFile = selection.files.some((f) => !isSharedFile(f.path));
|
|
29013
|
+
if (!hasComponentFile) {
|
|
29014
|
+
throw new Error(
|
|
29015
|
+
`No ${targetToExtension(target)} version available for "${item.name}" and no compatible fallback exists.`
|
|
29016
|
+
);
|
|
29017
|
+
}
|
|
28628
29018
|
} else if (item.type === "composite") {
|
|
28629
29019
|
filesToInstall = selectCompositeFiles(item.files, getComponentTarget(config2));
|
|
28630
29020
|
}
|
|
28631
29021
|
for (const file2 of filesToInstall) {
|
|
28632
|
-
const projectPath2 = transformPath(file2.path, config2, cwd);
|
|
29022
|
+
const projectPath2 = item.type === "substrate" ? substrateProjectPath(file2.path, config2, cwd) : transformPath(file2.path, config2, cwd);
|
|
28633
29023
|
const targetPath = join7(cwd, projectPath2);
|
|
28634
29024
|
if (fileExists(cwd, projectPath2)) {
|
|
28635
29025
|
if (!options.overwrite) {
|
|
@@ -28644,8 +29034,11 @@ async function installItem(cwd, item, options, config2) {
|
|
|
28644
29034
|
}
|
|
28645
29035
|
}
|
|
28646
29036
|
await mkdir2(dirname(targetPath), { recursive: true });
|
|
28647
|
-
const fileType = item.type === "primitive" ? "primitive" : "component";
|
|
28648
|
-
const transformedContent = transformFileContent(file2.content, config2, fileType, cwd
|
|
29037
|
+
const fileType = item.type === "primitive" ? "primitive" : item.type === "substrate" ? "substrate" : "component";
|
|
29038
|
+
const transformedContent = transformFileContent(file2.content, config2, fileType, cwd, {
|
|
29039
|
+
substrateKinds,
|
|
29040
|
+
installPath: file2.path
|
|
29041
|
+
});
|
|
28649
29042
|
await writeFile2(targetPath, transformedContent, "utf-8");
|
|
28650
29043
|
installedFiles.push(projectPath2);
|
|
28651
29044
|
}
|
|
@@ -28758,6 +29151,11 @@ async function add(componentArgs, options) {
|
|
|
28758
29151
|
return;
|
|
28759
29152
|
}
|
|
28760
29153
|
}
|
|
29154
|
+
const substrateKinds = [
|
|
29155
|
+
...new Set(
|
|
29156
|
+
allItems.filter((item) => item.type === "substrate").map((item) => item.files[0]?.path.split("/")[0]).filter((segment) => Boolean(segment))
|
|
29157
|
+
)
|
|
29158
|
+
];
|
|
28761
29159
|
const installed = [];
|
|
28762
29160
|
const skipped = [];
|
|
28763
29161
|
const installedItems = [];
|
|
@@ -28781,7 +29179,7 @@ async function add(componentArgs, options) {
|
|
|
28781
29179
|
});
|
|
28782
29180
|
}
|
|
28783
29181
|
try {
|
|
28784
|
-
const result = await installItem(cwd, item, options, config2);
|
|
29182
|
+
const result = await installItem(cwd, item, options, config2, substrateKinds);
|
|
28785
29183
|
if (result.installed) {
|
|
28786
29184
|
installed.push(item.name);
|
|
28787
29185
|
installedItems.push(item);
|
|
@@ -30931,9 +31329,10 @@ function studioApiPlugin() {
|
|
|
30931
31329
|
const config2 = await loadStudioConfig();
|
|
30932
31330
|
const exports = config2?.exports ?? {
|
|
30933
31331
|
tailwind: true,
|
|
30934
|
-
typescript:
|
|
31332
|
+
typescript: true,
|
|
30935
31333
|
dtcg: false,
|
|
30936
|
-
compiled: false
|
|
31334
|
+
compiled: false,
|
|
31335
|
+
documentation: false
|
|
30937
31336
|
};
|
|
30938
31337
|
await regenerateOutputs(
|
|
30939
31338
|
registry2,
|
|
@@ -30970,21 +31369,27 @@ function studioApiPlugin() {
|
|
|
30970
31369
|
}
|
|
30971
31370
|
};
|
|
30972
31371
|
{
|
|
30973
|
-
const
|
|
30974
|
-
const
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
30980
|
-
|
|
31372
|
+
const trackedClassDirs = /* @__PURE__ */ new Set();
|
|
31373
|
+
const syncWatchTargets = async () => {
|
|
31374
|
+
const watchConfig = await loadStudioConfig();
|
|
31375
|
+
const classDirs = watchConfig ? resolveContentSources(projectPath, watchConfig) : [];
|
|
31376
|
+
const newDirs = classDirs.filter((d2) => !trackedClassDirs.has(d2));
|
|
31377
|
+
if (newDirs.length > 0) {
|
|
31378
|
+
server.watcher.add(newDirs.map((dir) => join14(dir, "**/*.classes.ts")));
|
|
31379
|
+
for (const d2 of newDirs) trackedClassDirs.add(d2);
|
|
31380
|
+
}
|
|
31381
|
+
};
|
|
31382
|
+
server.watcher.add([join14(tokensDir, "*.rafters.json"), configPath]);
|
|
31383
|
+
await syncWatchTargets();
|
|
30981
31384
|
let debounce = null;
|
|
30982
31385
|
const onChange = (changed) => {
|
|
30983
31386
|
const watched = changed.endsWith(".classes.ts") || changed.endsWith(".rafters.json") || changed === configPath;
|
|
30984
31387
|
if (!watched) return;
|
|
30985
31388
|
if (debounce) clearTimeout(debounce);
|
|
30986
31389
|
debounce = setTimeout(() => {
|
|
30987
|
-
|
|
31390
|
+
const isConfigChange = changed === configPath;
|
|
31391
|
+
const run = isConfigChange ? syncWatchTargets().then(reloadAndRegenerate) : reloadAndRegenerate();
|
|
31392
|
+
void run;
|
|
30988
31393
|
}, 150);
|
|
30989
31394
|
};
|
|
30990
31395
|
server.watcher.on("change", onChange);
|
package/dist/registry/types.d.ts
CHANGED
|
@@ -19,13 +19,19 @@ declare const RegistryFileSchema: z.ZodObject<{
|
|
|
19
19
|
}, z.core.$strip>;
|
|
20
20
|
type RegistryFile = z.infer<typeof RegistryFileSchema>;
|
|
21
21
|
/**
|
|
22
|
-
* Item type in registry
|
|
22
|
+
* Item type in registry.
|
|
23
|
+
* `substrate` is the behavior-layer runtime (the score contract, compose
|
|
24
|
+
* slices, reactive hooks -- everything under ui/src outside components /
|
|
25
|
+
* primitives / composites). It is a copy-in shared dependency resolved like a
|
|
26
|
+
* primitive; the specific dir it installs into (`@/lib`, `@/hooks`, ...) is
|
|
27
|
+
* carried in the item's file path, so the type never grows per kind.
|
|
23
28
|
*/
|
|
24
29
|
declare const RegistryItemTypeSchema: z.ZodEnum<{
|
|
25
30
|
ui: "ui";
|
|
26
31
|
primitive: "primitive";
|
|
27
32
|
composite: "composite";
|
|
28
33
|
rule: "rule";
|
|
34
|
+
substrate: "substrate";
|
|
29
35
|
}>;
|
|
30
36
|
type RegistryItemType = z.infer<typeof RegistryItemTypeSchema>;
|
|
31
37
|
/**
|
|
@@ -59,6 +65,7 @@ declare const RegistryItemSchema: z.ZodObject<{
|
|
|
59
65
|
primitive: "primitive";
|
|
60
66
|
composite: "composite";
|
|
61
67
|
rule: "rule";
|
|
68
|
+
substrate: "substrate";
|
|
62
69
|
}>;
|
|
63
70
|
description: z.ZodOptional<z.ZodString>;
|
|
64
71
|
primitives: z.ZodArray<z.ZodString>;
|
|
@@ -93,6 +100,7 @@ declare const RegistryIndexSchema: z.ZodObject<{
|
|
|
93
100
|
primitives: z.ZodArray<z.ZodString>;
|
|
94
101
|
composites: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
95
102
|
rules: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
103
|
+
substrate: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
96
104
|
}, z.core.$strip>;
|
|
97
105
|
type RegistryIndex = z.infer<typeof RegistryIndexSchema>;
|
|
98
106
|
|
package/dist/registry/types.js
CHANGED
|
@@ -8,7 +8,7 @@ var RegistryFileSchema = z.object({
|
|
|
8
8
|
devDependencies: z.array(z.string()).default([])
|
|
9
9
|
// e.g., ["vitest"] - from @devDependencies JSDoc
|
|
10
10
|
});
|
|
11
|
-
var RegistryItemTypeSchema = z.enum(["ui", "primitive", "composite", "rule"]);
|
|
11
|
+
var RegistryItemTypeSchema = z.enum(["ui", "primitive", "composite", "rule", "substrate"]);
|
|
12
12
|
var RegistryItemIntelligenceSchema = z.object({
|
|
13
13
|
cognitiveLoad: z.number().optional(),
|
|
14
14
|
attentionEconomics: z.string().optional(),
|
|
@@ -36,7 +36,8 @@ var RegistryIndexSchema = z.object({
|
|
|
36
36
|
components: z.array(z.string()),
|
|
37
37
|
primitives: z.array(z.string()),
|
|
38
38
|
composites: z.array(z.string()).default([]),
|
|
39
|
-
rules: z.array(z.string()).default([])
|
|
39
|
+
rules: z.array(z.string()).default([]),
|
|
40
|
+
substrate: z.array(z.string()).default([])
|
|
40
41
|
});
|
|
41
42
|
export {
|
|
42
43
|
RegistryFileSchema,
|
package/package.json
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rafters",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
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",
|
|
7
|
-
"
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/rafters-studio/rafters.git",
|
|
10
|
+
"directory": "packages/cli"
|
|
11
|
+
},
|
|
8
12
|
"bin": {
|
|
9
13
|
"rafters": "./dist/index.js"
|
|
10
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
11
20
|
"exports": {
|
|
12
21
|
".": "./dist/index.js",
|
|
13
22
|
"./registry/types": {
|
|
@@ -15,10 +24,9 @@
|
|
|
15
24
|
"import": "./dist/registry/types.js"
|
|
16
25
|
}
|
|
17
26
|
},
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
],
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
22
30
|
"scripts": {
|
|
23
31
|
"build": "tsup",
|
|
24
32
|
"dev": "tsup --watch",
|
|
@@ -57,13 +65,5 @@
|
|
|
57
65
|
"typescript": "catalog:",
|
|
58
66
|
"vitest": "catalog:",
|
|
59
67
|
"zocker": "catalog:"
|
|
60
|
-
},
|
|
61
|
-
"repository": {
|
|
62
|
-
"type": "git",
|
|
63
|
-
"url": "git+https://github.com/rafters-studio/rafters.git",
|
|
64
|
-
"directory": "packages/cli"
|
|
65
|
-
},
|
|
66
|
-
"publishConfig": {
|
|
67
|
-
"access": "public"
|
|
68
68
|
}
|
|
69
69
|
}
|