@motion-proto/live-tokens 0.65.1 → 0.67.0
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/CHANGELOG.md +184 -0
- package/dist-plugin/{chunk-NDJJORKJ.js → chunk-T4PMCFJN.js} +220 -114
- package/dist-plugin/index.cjs +253 -129
- package/dist-plugin/index.js +27 -9
- package/dist-plugin/migrateData/index.cjs +220 -114
- package/dist-plugin/migrateData/index.js +1 -1
- package/package.json +8 -1
- package/src/editor/bootstrap.ts +12 -0
- package/src/editor/core/productionPulse.ts +1 -1
- package/src/editor/core/sketch/index.ts +78 -21
- package/src/editor/core/sketch/maskField.ts +200 -62
- package/src/editor/core/sketch/sketchLayer.ts +10 -4
- package/src/editor/core/sketch/sketchRegistry.ts +98 -0
- package/src/editor/core/sketch/sketchStore.ts +110 -31
- package/src/editor/core/sketch/sketchStyleService.ts +3 -0
- package/src/editor/core/sketch/sketchStyles.ts +63 -96
- package/src/editor/core/themes/themeInit.ts +4 -13
- package/src/editor/docs/content/sketch-mode.md +82 -13
- package/src/editor/docs/content.generated.ts +1 -1
- package/src/editor/ui/sketch/SketchTab.svelte +219 -74
- package/src/live-tokens/data/sketch-styles/dashed.json +47 -0
- package/src/live-tokens/data/sketch-styles/dry.json +47 -0
- package/src/live-tokens/data/sketch-styles/hatched.json +47 -0
- package/src/live-tokens/data/sketch-styles/marker.json +47 -0
- package/src/live-tokens/data/sketch-styles/napkin.json +47 -0
- package/src/live-tokens/data/sketch-styles/pencil.json +47 -0
- package/src/live-tokens/data/sketch-styles/whiteboard.json +47 -0
- package/src/live-tokens/data/themes/autumn.json +4 -4
- package/src/live-tokens/data/themes/halloween.json +4 -4
- package/src/live-tokens/data/themes/midnight-study.json +4 -4
- package/src/live-tokens/data/themes/ocean.json +4 -4
- package/src/live-tokens/data/themes/royal-velvet.json +4 -4
- package/src/live-tokens/data/themes/sketchy.json +4 -4
- package/src/live-tokens/data/themes/spring-meadow.json +4 -4
- package/src/live-tokens/data/themes/sunset.json +4 -4
- package/src/system/components/Button.svelte +2 -2
- package/src/system/components/IconButton.svelte +2 -2
- package/src/system/styles/fonts.css +6 -6
- package/template/src/main.ts +14 -1
package/dist-plugin/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
nextAvailableName,
|
|
14
14
|
normalizeTheme,
|
|
15
15
|
versionedFileResourceServer
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-T4PMCFJN.js";
|
|
17
17
|
import {
|
|
18
18
|
CURRENT_COMPONENT_SCHEMA_VERSION
|
|
19
19
|
} from "./chunk-NE6N66EE.js";
|
|
@@ -243,12 +243,14 @@ function themeFileApi(opts) {
|
|
|
243
243
|
const packageColorsAndTypeDir = path.join(packageDataDir, "colors-and-type");
|
|
244
244
|
const packageThemesDir = path.join(packageDataDir, "themes");
|
|
245
245
|
const packageComponentConfigsDir = path.join(packageDataDir, "component-configs");
|
|
246
|
-
|
|
246
|
+
const packageSketchStylesDir = path.join(packageDataDir, "sketch-styles");
|
|
247
|
+
function shippedNames(dataDir, subdir) {
|
|
247
248
|
try {
|
|
248
249
|
const pkgRoot = path.resolve(dataDir, "..", "..", "..");
|
|
249
250
|
const pkg = JSON.parse(fs.readFileSync(path.join(pkgRoot, "package.json"), "utf-8"));
|
|
250
251
|
const files = Array.isArray(pkg.files) ? pkg.files : [];
|
|
251
|
-
|
|
252
|
+
const owned = new RegExp(`^src/live-tokens/data/${subdir}/[^/]+\\.json$`);
|
|
253
|
+
return files.filter((f) => owned.test(f)).map((f) => path.basename(f, ".json"));
|
|
252
254
|
} catch {
|
|
253
255
|
return [];
|
|
254
256
|
}
|
|
@@ -260,7 +262,7 @@ function themeFileApi(opts) {
|
|
|
260
262
|
const colorsAndTypeResource = versionedFileResourceServer({
|
|
261
263
|
dir: COLORS_AND_TYPE_DIR,
|
|
262
264
|
packageDir: packageColorsAndTypeDir,
|
|
263
|
-
packageOwnedNames:
|
|
265
|
+
packageOwnedNames: shippedNames(packageDataDir, "colors-and-type")
|
|
264
266
|
});
|
|
265
267
|
const componentResourceCache = /* @__PURE__ */ new Map();
|
|
266
268
|
function componentResource(comp) {
|
|
@@ -278,7 +280,11 @@ function themeFileApi(opts) {
|
|
|
278
280
|
dir: THEMES_DIR,
|
|
279
281
|
packageDir: packageThemesDir
|
|
280
282
|
});
|
|
281
|
-
const sketchStylesResource = versionedFileResourceServer({
|
|
283
|
+
const sketchStylesResource = versionedFileResourceServer({
|
|
284
|
+
dir: SKETCH_STYLES_DIR,
|
|
285
|
+
packageDir: packageSketchStylesDir,
|
|
286
|
+
packageOwnedNames: shippedNames(packageDataDir, "sketch-styles")
|
|
287
|
+
});
|
|
282
288
|
function ensureColorsAndTypeDir() {
|
|
283
289
|
colorsAndTypeResource.ensureDir();
|
|
284
290
|
}
|
|
@@ -1090,7 +1096,8 @@ ${lines.join("\n")}
|
|
|
1090
1096
|
return {
|
|
1091
1097
|
name: data?.name || fileName,
|
|
1092
1098
|
fileName,
|
|
1093
|
-
updatedAt: data?.updatedAt || ""
|
|
1099
|
+
updatedAt: data?.updatedAt || "",
|
|
1100
|
+
isPackage: sketchStylesResource.isPackageFile(fileName)
|
|
1094
1101
|
};
|
|
1095
1102
|
});
|
|
1096
1103
|
jsonResponse(res, 200, { component: comp, files });
|
|
@@ -1406,7 +1413,8 @@ ${lines.join("\n")}
|
|
|
1406
1413
|
return {
|
|
1407
1414
|
name: data?.name || fileName,
|
|
1408
1415
|
fileName,
|
|
1409
|
-
updatedAt: data?.updatedAt || ""
|
|
1416
|
+
updatedAt: data?.updatedAt || "",
|
|
1417
|
+
isPackage: sketchStylesResource.isPackageFile(fileName)
|
|
1410
1418
|
};
|
|
1411
1419
|
});
|
|
1412
1420
|
jsonResponse(res, 200, { files });
|
|
@@ -1446,7 +1454,15 @@ ${lines.join("\n")}
|
|
|
1446
1454
|
return;
|
|
1447
1455
|
}
|
|
1448
1456
|
if (req.method === "DELETE") {
|
|
1449
|
-
if (fs.existsSync(filePath))
|
|
1457
|
+
if (fs.existsSync(filePath)) {
|
|
1458
|
+
fs.unlinkSync(filePath);
|
|
1459
|
+
} else if (sketchStylesResource.existingPath(fileName)) {
|
|
1460
|
+
jsonResponse(res, 403, {
|
|
1461
|
+
error: "Cannot delete a sketchstyle shipped with the package. Saving it creates a local copy; deleting that copy restores the shipped version.",
|
|
1462
|
+
code: "PACKAGE_SKETCH_STYLE"
|
|
1463
|
+
});
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1450
1466
|
jsonResponse(res, 200, { ok: true });
|
|
1451
1467
|
return;
|
|
1452
1468
|
}
|
|
@@ -1540,6 +1556,7 @@ ${lines.join("\n")}
|
|
|
1540
1556
|
{ method: "POST", pattern: PRODUCTION_ROUTE, handler: methodNotAllowed },
|
|
1541
1557
|
{ method: "DELETE", pattern: PRODUCTION_ROUTE, handler: methodNotAllowed }
|
|
1542
1558
|
];
|
|
1559
|
+
const isEditorOwnedJson = (file) => file.endsWith(".json") && path.resolve(file).startsWith(dataDirs.dataDir + path.sep);
|
|
1543
1560
|
return {
|
|
1544
1561
|
name: "theme-file-api",
|
|
1545
1562
|
config() {
|
|
@@ -1548,7 +1565,8 @@ ${lines.join("\n")}
|
|
|
1548
1565
|
__PROJECT_ROOT__: JSON.stringify(process.cwd()),
|
|
1549
1566
|
__APP_VERSION__: JSON.stringify(PKG_VERSION),
|
|
1550
1567
|
__LIVE_TOKENS_API_BASE__: JSON.stringify(API_BASE)
|
|
1551
|
-
}
|
|
1568
|
+
},
|
|
1569
|
+
server: { watch: { ignored: [isEditorOwnedJson] } }
|
|
1552
1570
|
};
|
|
1553
1571
|
},
|
|
1554
1572
|
configureServer(server) {
|
|
@@ -1053,65 +1053,38 @@ var KNOWN_COMPONENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
1053
1053
|
"--sectiondivider-sm-color-family"
|
|
1054
1054
|
]);
|
|
1055
1055
|
|
|
1056
|
-
// src/
|
|
1057
|
-
var
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
fillTravel: 1.5,
|
|
1061
|
-
strokeTravel: 1.5,
|
|
1062
|
-
wobble: 45,
|
|
1063
|
-
roughness: 3,
|
|
1064
|
-
borderWavelength: 1,
|
|
1065
|
-
waveform: 1,
|
|
1066
|
-
strokeWidth: 1.5,
|
|
1067
|
-
doubleStroke: false,
|
|
1068
|
-
retraceOffset: 1.2,
|
|
1069
|
-
retracePass: "copy",
|
|
1070
|
-
fillStyle: "solid",
|
|
1071
|
-
hatchInk: 0.4,
|
|
1072
|
-
strokeStyle: "solid",
|
|
1073
|
-
pressure: 0.25,
|
|
1074
|
-
pressureMod: 0.35,
|
|
1075
|
-
pooling: 1.2,
|
|
1076
|
-
strokeInk: 1,
|
|
1077
|
-
maskOn: true,
|
|
1078
|
-
maskBlob: 100,
|
|
1079
|
-
maskOutputMin: 0.45,
|
|
1080
|
-
maskOutputMax: 1,
|
|
1081
|
-
maskOctaves: 2,
|
|
1082
|
-
maskGrain: "fractal",
|
|
1083
|
-
maskPosterize: 1,
|
|
1084
|
-
maskSoftness: 1.5,
|
|
1085
|
-
jitterX: 2.5,
|
|
1086
|
-
jitterY: 2.5,
|
|
1087
|
-
jitterRot: 0.6,
|
|
1088
|
-
jitterScale: 0.035,
|
|
1089
|
-
cornerSpread: 10,
|
|
1090
|
-
cornerTravel: 8,
|
|
1091
|
-
iconTravel: 1.25,
|
|
1092
|
-
iconWavelength: 0.625,
|
|
1093
|
-
iconMaskOn: true,
|
|
1094
|
-
iconMaskScale: 1
|
|
1095
|
-
};
|
|
1096
|
-
var SKETCH_STYLES = {
|
|
1097
|
-
pencil: {
|
|
1098
|
-
...base,
|
|
1056
|
+
// src/live-tokens/data/sketch-styles/pencil.json
|
|
1057
|
+
var pencil_default = {
|
|
1058
|
+
name: "Pencil",
|
|
1059
|
+
settings: {
|
|
1099
1060
|
label: "Pencil",
|
|
1100
1061
|
blurb: "Two graphite passes on their own seeds, so the outline disagrees with itself the way a hand coming back round does. Tight grain, little else.",
|
|
1101
1062
|
fillTravel: 0.75,
|
|
1102
1063
|
strokeTravel: 1.25,
|
|
1103
1064
|
wobble: 30,
|
|
1104
1065
|
roughness: 3,
|
|
1066
|
+
borderWavelength: 1,
|
|
1105
1067
|
waveform: 1,
|
|
1106
1068
|
strokeWidth: 1.25,
|
|
1107
1069
|
doubleStroke: true,
|
|
1108
|
-
retracePass: "reseeded",
|
|
1109
1070
|
retraceOffset: 1.5,
|
|
1071
|
+
retracePass: "reseeded",
|
|
1072
|
+
fillStyle: "solid",
|
|
1073
|
+
hatchInk: 0.4,
|
|
1074
|
+
strokeStyle: "solid",
|
|
1075
|
+
pressure: 0.15,
|
|
1076
|
+
pressureMod: 0.3,
|
|
1077
|
+
pooling: 0,
|
|
1110
1078
|
strokeInk: 0.85,
|
|
1111
|
-
|
|
1112
|
-
|
|
1079
|
+
maskOn: true,
|
|
1080
|
+
maskBlobX: 525,
|
|
1081
|
+
maskBlobY: 47,
|
|
1082
|
+
maskBlobLinked: false,
|
|
1083
|
+
maskAngle: 67,
|
|
1084
|
+
maskOutputMin: 0.59,
|
|
1113
1085
|
maskOutputMax: 1,
|
|
1114
1086
|
maskOctaves: 3,
|
|
1087
|
+
maskGrain: "turbulence",
|
|
1115
1088
|
maskPosterize: 1,
|
|
1116
1089
|
maskSoftness: 0,
|
|
1117
1090
|
jitterX: 1.5,
|
|
@@ -1120,147 +1093,243 @@ var SKETCH_STYLES = {
|
|
|
1120
1093
|
jitterScale: 0.022,
|
|
1121
1094
|
cornerSpread: 6,
|
|
1122
1095
|
cornerTravel: 4.5,
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1096
|
+
iconTravel: 0.75,
|
|
1097
|
+
iconWavelength: 0.625,
|
|
1098
|
+
iconMaskOn: true,
|
|
1099
|
+
iconMaskScale: 1
|
|
1127
1100
|
},
|
|
1128
|
-
|
|
1129
|
-
|
|
1101
|
+
updatedAt: "2026-08-28T14:35:06.291Z",
|
|
1102
|
+
createdAt: "2026-08-28T14:35:06.291Z"
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1105
|
+
// src/live-tokens/data/sketch-styles/marker.json
|
|
1106
|
+
var marker_default = {
|
|
1107
|
+
name: "Marker",
|
|
1108
|
+
settings: {
|
|
1130
1109
|
label: "Marker",
|
|
1131
1110
|
blurb: "Broad translucent nib gone round twice on the same line, so the overlap darkens and the ink pools where it slows.",
|
|
1132
1111
|
fillTravel: 2,
|
|
1133
1112
|
strokeTravel: 1.5,
|
|
1134
1113
|
wobble: 56,
|
|
1135
|
-
|
|
1114
|
+
roughness: 3,
|
|
1136
1115
|
borderWavelength: 1.3,
|
|
1116
|
+
waveform: 1.4,
|
|
1137
1117
|
strokeWidth: 4,
|
|
1138
1118
|
doubleStroke: true,
|
|
1119
|
+
retraceOffset: 2.2,
|
|
1139
1120
|
retracePass: "copy",
|
|
1121
|
+
fillStyle: "solid",
|
|
1122
|
+
hatchInk: 0.4,
|
|
1123
|
+
strokeStyle: "solid",
|
|
1124
|
+
pressure: 0.2,
|
|
1125
|
+
pressureMod: 0.25,
|
|
1126
|
+
pooling: 2,
|
|
1140
1127
|
strokeInk: 0.52,
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1128
|
+
maskOn: true,
|
|
1129
|
+
maskBlobX: 230,
|
|
1130
|
+
maskBlobY: 230,
|
|
1131
|
+
maskBlobLinked: true,
|
|
1132
|
+
maskAngle: 0,
|
|
1133
|
+
maskOutputMin: 0.76,
|
|
1144
1134
|
maskOutputMax: 1,
|
|
1145
1135
|
maskOctaves: 3,
|
|
1136
|
+
maskGrain: "fractal",
|
|
1146
1137
|
maskPosterize: 4,
|
|
1147
|
-
maskSoftness:
|
|
1138
|
+
maskSoftness: 0,
|
|
1148
1139
|
jitterX: 3,
|
|
1149
1140
|
jitterY: 3,
|
|
1150
1141
|
jitterRot: 0.8,
|
|
1151
1142
|
jitterScale: 0.045,
|
|
1152
1143
|
cornerSpread: 10,
|
|
1153
1144
|
cornerTravel: 8,
|
|
1154
|
-
pressure: 0.2,
|
|
1155
|
-
pressureMod: 0.25,
|
|
1156
|
-
pooling: 2,
|
|
1157
1145
|
iconTravel: 1.25,
|
|
1146
|
+
iconWavelength: 0.625,
|
|
1147
|
+
iconMaskOn: true,
|
|
1158
1148
|
iconMaskScale: 4
|
|
1159
1149
|
},
|
|
1160
|
-
|
|
1161
|
-
|
|
1150
|
+
updatedAt: "2026-08-28T14:45:04.324Z",
|
|
1151
|
+
createdAt: "2026-08-28T14:45:04.324Z"
|
|
1152
|
+
};
|
|
1153
|
+
|
|
1154
|
+
// src/live-tokens/data/sketch-styles/whiteboard.json
|
|
1155
|
+
var whiteboard_default = {
|
|
1156
|
+
name: "Whiteboard",
|
|
1157
|
+
settings: {
|
|
1162
1158
|
label: "Whiteboard",
|
|
1163
1159
|
blurb: "The fattest nib on glass. One long smooth undulation, and a veined mask that streaks the fill like a half-wiped board.",
|
|
1164
1160
|
fillTravel: 2.5,
|
|
1165
1161
|
strokeTravel: 2.5,
|
|
1166
1162
|
wobble: 90,
|
|
1167
1163
|
roughness: 1,
|
|
1168
|
-
waveform: 1,
|
|
1169
1164
|
borderWavelength: 1.5,
|
|
1165
|
+
waveform: 1,
|
|
1170
1166
|
strokeWidth: 5.5,
|
|
1171
1167
|
doubleStroke: true,
|
|
1168
|
+
retraceOffset: 3,
|
|
1172
1169
|
retracePass: "copy",
|
|
1170
|
+
fillStyle: "solid",
|
|
1171
|
+
hatchInk: 0.4,
|
|
1172
|
+
strokeStyle: "solid",
|
|
1173
|
+
pressure: 0.15,
|
|
1174
|
+
pressureMod: 0.15,
|
|
1175
|
+
pooling: 3.5,
|
|
1173
1176
|
strokeInk: 0.66,
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1177
|
+
maskOn: true,
|
|
1178
|
+
maskBlobX: 180,
|
|
1179
|
+
maskBlobY: 38,
|
|
1180
|
+
maskBlobLinked: false,
|
|
1181
|
+
maskAngle: 0,
|
|
1182
|
+
maskOutputMin: 0.68,
|
|
1178
1183
|
maskOutputMax: 1,
|
|
1179
|
-
maskOctaves:
|
|
1184
|
+
maskOctaves: 3,
|
|
1185
|
+
maskGrain: "turbulence",
|
|
1180
1186
|
maskPosterize: 3,
|
|
1181
|
-
maskSoftness:
|
|
1187
|
+
maskSoftness: 0,
|
|
1182
1188
|
jitterX: 4.5,
|
|
1183
1189
|
jitterY: 4.5,
|
|
1184
|
-
jitterRot:
|
|
1190
|
+
jitterRot: 3,
|
|
1185
1191
|
jitterScale: 0.07,
|
|
1186
1192
|
cornerSpread: 14,
|
|
1187
1193
|
cornerTravel: 11,
|
|
1188
|
-
pressure: 0.15,
|
|
1189
|
-
pressureMod: 0.15,
|
|
1190
|
-
pooling: 3.5,
|
|
1191
1194
|
iconTravel: 1.75,
|
|
1195
|
+
iconWavelength: 0.625,
|
|
1196
|
+
iconMaskOn: true,
|
|
1192
1197
|
iconMaskScale: 1.5
|
|
1193
1198
|
},
|
|
1194
|
-
|
|
1195
|
-
|
|
1199
|
+
updatedAt: "2026-08-28T14:46:58.140Z",
|
|
1200
|
+
createdAt: "2026-08-28T14:46:58.140Z"
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
// src/live-tokens/data/sketch-styles/hatched.json
|
|
1204
|
+
var hatched_default = {
|
|
1205
|
+
name: "Hatched",
|
|
1206
|
+
settings: {
|
|
1196
1207
|
label: "Hatched",
|
|
1197
1208
|
blurb: "An etching. The fill is angled shading, the outline a single hard-edged scratch that chatters along its length. No mask: the hatch is the texture.",
|
|
1198
1209
|
fillTravel: 1.25,
|
|
1199
1210
|
strokeTravel: 1.5,
|
|
1200
1211
|
wobble: 24,
|
|
1201
1212
|
roughness: 3,
|
|
1213
|
+
borderWavelength: 1,
|
|
1202
1214
|
waveform: 3,
|
|
1203
1215
|
strokeWidth: 1.5,
|
|
1216
|
+
doubleStroke: false,
|
|
1217
|
+
retraceOffset: 1.2,
|
|
1218
|
+
retracePass: "copy",
|
|
1204
1219
|
fillStyle: "hatched",
|
|
1205
1220
|
hatchInk: 0.5,
|
|
1206
|
-
|
|
1221
|
+
strokeStyle: "solid",
|
|
1222
|
+
pressure: 0.3,
|
|
1223
|
+
pressureMod: 0.45,
|
|
1224
|
+
pooling: 0.8,
|
|
1225
|
+
strokeInk: 1,
|
|
1207
1226
|
maskOn: false,
|
|
1208
|
-
|
|
1227
|
+
maskBlobX: 100,
|
|
1228
|
+
maskBlobY: 100,
|
|
1229
|
+
maskBlobLinked: true,
|
|
1230
|
+
maskAngle: 0,
|
|
1231
|
+
maskOutputMin: 0.45,
|
|
1232
|
+
maskOutputMax: 1,
|
|
1233
|
+
maskOctaves: 2,
|
|
1234
|
+
maskGrain: "fractal",
|
|
1235
|
+
maskPosterize: 1,
|
|
1236
|
+
maskSoftness: 1.5,
|
|
1209
1237
|
jitterX: 1.5,
|
|
1210
1238
|
jitterY: 1.5,
|
|
1211
1239
|
jitterRot: 0.4,
|
|
1212
1240
|
jitterScale: 0.03,
|
|
1213
1241
|
cornerSpread: 6,
|
|
1214
1242
|
cornerTravel: 6,
|
|
1215
|
-
pressure: 0.3,
|
|
1216
|
-
pressureMod: 0.45,
|
|
1217
|
-
pooling: 0.8,
|
|
1218
1243
|
iconTravel: 1.25,
|
|
1219
|
-
iconWavelength: 0.5
|
|
1244
|
+
iconWavelength: 0.5,
|
|
1245
|
+
iconMaskOn: false,
|
|
1246
|
+
iconMaskScale: 1
|
|
1220
1247
|
},
|
|
1221
|
-
|
|
1222
|
-
|
|
1248
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
1249
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
1250
|
+
};
|
|
1251
|
+
|
|
1252
|
+
// src/live-tokens/data/sketch-styles/dashed.json
|
|
1253
|
+
var dashed_default = {
|
|
1254
|
+
name: "Dashed",
|
|
1255
|
+
settings: {
|
|
1223
1256
|
label: "Dashed",
|
|
1224
1257
|
blurb: "A drafting outline. One slow drift along the ruler, broken into strokes, with jitter, mask and pressure all off. The clean pole.",
|
|
1225
|
-
strokeStyle: "dashed",
|
|
1226
|
-
strokeTravel: 1,
|
|
1227
1258
|
fillTravel: 0.5,
|
|
1259
|
+
strokeTravel: 1,
|
|
1228
1260
|
wobble: 120,
|
|
1229
1261
|
roughness: 1,
|
|
1262
|
+
borderWavelength: 1,
|
|
1230
1263
|
waveform: 1,
|
|
1231
1264
|
strokeWidth: 1.5,
|
|
1232
1265
|
doubleStroke: false,
|
|
1266
|
+
retraceOffset: 1.2,
|
|
1267
|
+
retracePass: "copy",
|
|
1268
|
+
fillStyle: "solid",
|
|
1269
|
+
hatchInk: 0.4,
|
|
1270
|
+
strokeStyle: "dashed",
|
|
1271
|
+
pressure: 0,
|
|
1272
|
+
pressureMod: 0,
|
|
1273
|
+
pooling: 0,
|
|
1274
|
+
strokeInk: 1,
|
|
1233
1275
|
maskOn: false,
|
|
1234
|
-
|
|
1276
|
+
maskBlobX: 100,
|
|
1277
|
+
maskBlobY: 100,
|
|
1278
|
+
maskBlobLinked: true,
|
|
1279
|
+
maskAngle: 0,
|
|
1280
|
+
maskOutputMin: 0.45,
|
|
1281
|
+
maskOutputMax: 1,
|
|
1282
|
+
maskOctaves: 2,
|
|
1283
|
+
maskGrain: "fractal",
|
|
1284
|
+
maskPosterize: 1,
|
|
1285
|
+
maskSoftness: 1.5,
|
|
1235
1286
|
jitterX: 0,
|
|
1236
1287
|
jitterY: 0,
|
|
1237
1288
|
jitterRot: 0,
|
|
1238
1289
|
jitterScale: 0,
|
|
1239
1290
|
cornerSpread: 4,
|
|
1240
1291
|
cornerTravel: 3,
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1292
|
+
iconTravel: 0,
|
|
1293
|
+
iconWavelength: 0.625,
|
|
1294
|
+
iconMaskOn: false,
|
|
1295
|
+
iconMaskScale: 1
|
|
1245
1296
|
},
|
|
1246
|
-
|
|
1247
|
-
|
|
1297
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
1298
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
1299
|
+
};
|
|
1300
|
+
|
|
1301
|
+
// src/live-tokens/data/sketch-styles/napkin.json
|
|
1302
|
+
var napkin_default = {
|
|
1303
|
+
name: "Napkin",
|
|
1304
|
+
settings: {
|
|
1248
1305
|
label: "Napkin",
|
|
1249
1306
|
blurb: "Ballpoint in a hurry. Everything loose at once: a square wave sends every edge to full travel, and the second pass lands wherever it lands.",
|
|
1250
1307
|
fillTravel: 3,
|
|
1251
1308
|
strokeTravel: 2.25,
|
|
1252
1309
|
wobble: 50,
|
|
1253
1310
|
roughness: 3,
|
|
1311
|
+
borderWavelength: 1,
|
|
1254
1312
|
waveform: 2.5,
|
|
1255
1313
|
strokeWidth: 2.25,
|
|
1256
1314
|
doubleStroke: true,
|
|
1257
|
-
retracePass: "reseeded",
|
|
1258
1315
|
retraceOffset: 4,
|
|
1316
|
+
retracePass: "reseeded",
|
|
1317
|
+
fillStyle: "solid",
|
|
1318
|
+
hatchInk: 0.4,
|
|
1319
|
+
strokeStyle: "solid",
|
|
1320
|
+
pressure: 0.45,
|
|
1321
|
+
pressureMod: 0.6,
|
|
1322
|
+
pooling: 2.5,
|
|
1259
1323
|
strokeInk: 1,
|
|
1260
|
-
|
|
1324
|
+
maskOn: true,
|
|
1325
|
+
maskBlobX: 150,
|
|
1326
|
+
maskBlobY: 150,
|
|
1327
|
+
maskBlobLinked: true,
|
|
1328
|
+
maskAngle: 0,
|
|
1261
1329
|
maskOutputMin: 0.43,
|
|
1262
1330
|
maskOutputMax: 0.95,
|
|
1263
1331
|
maskOctaves: 2,
|
|
1332
|
+
maskGrain: "fractal",
|
|
1264
1333
|
maskPosterize: 2,
|
|
1265
1334
|
maskSoftness: 10,
|
|
1266
1335
|
jitterX: 6,
|
|
@@ -1269,28 +1338,47 @@ var SKETCH_STYLES = {
|
|
|
1269
1338
|
jitterScale: 0.1,
|
|
1270
1339
|
cornerSpread: 20,
|
|
1271
1340
|
cornerTravel: 17,
|
|
1272
|
-
pressure: 0.45,
|
|
1273
|
-
pressureMod: 0.6,
|
|
1274
|
-
pooling: 2.5,
|
|
1275
1341
|
iconTravel: 2.25,
|
|
1342
|
+
iconWavelength: 0.625,
|
|
1343
|
+
iconMaskOn: true,
|
|
1276
1344
|
iconMaskScale: 3.6
|
|
1277
1345
|
},
|
|
1278
|
-
|
|
1279
|
-
|
|
1346
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
1347
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
1348
|
+
};
|
|
1349
|
+
|
|
1350
|
+
// src/live-tokens/data/sketch-styles/dry.json
|
|
1351
|
+
var dry_default = {
|
|
1352
|
+
name: "Dry marker",
|
|
1353
|
+
settings: {
|
|
1280
1354
|
label: "Dry marker",
|
|
1281
1355
|
blurb: "Ink that ran out. One scratchy pass that breaks up along its length, over a fill the mask has worn nearly through in patches.",
|
|
1282
1356
|
fillTravel: 2.25,
|
|
1283
1357
|
strokeTravel: 1.75,
|
|
1284
1358
|
wobble: 50,
|
|
1285
|
-
|
|
1359
|
+
roughness: 3,
|
|
1286
1360
|
borderWavelength: 0.5,
|
|
1361
|
+
waveform: 2,
|
|
1287
1362
|
strokeWidth: 3.5,
|
|
1288
1363
|
doubleStroke: false,
|
|
1364
|
+
retraceOffset: 1.2,
|
|
1365
|
+
retracePass: "copy",
|
|
1366
|
+
fillStyle: "solid",
|
|
1367
|
+
hatchInk: 0.4,
|
|
1368
|
+
strokeStyle: "solid",
|
|
1369
|
+
pressure: 0.4,
|
|
1370
|
+
pressureMod: 0.8,
|
|
1371
|
+
pooling: 1.5,
|
|
1289
1372
|
strokeInk: 0.4,
|
|
1290
|
-
|
|
1373
|
+
maskOn: true,
|
|
1374
|
+
maskBlobX: 150,
|
|
1375
|
+
maskBlobY: 150,
|
|
1376
|
+
maskBlobLinked: true,
|
|
1377
|
+
maskAngle: 0,
|
|
1291
1378
|
maskOutputMin: 0.24,
|
|
1292
1379
|
maskOutputMax: 0.91,
|
|
1293
1380
|
maskOctaves: 2,
|
|
1381
|
+
maskGrain: "fractal",
|
|
1294
1382
|
maskPosterize: 4,
|
|
1295
1383
|
maskSoftness: 1.75,
|
|
1296
1384
|
jitterX: 5,
|
|
@@ -1299,26 +1387,34 @@ var SKETCH_STYLES = {
|
|
|
1299
1387
|
jitterScale: 0.08,
|
|
1300
1388
|
cornerSpread: 16,
|
|
1301
1389
|
cornerTravel: 13,
|
|
1302
|
-
pressure: 0.4,
|
|
1303
|
-
pressureMod: 0.8,
|
|
1304
|
-
pooling: 1.5,
|
|
1305
1390
|
iconTravel: 1.75,
|
|
1391
|
+
iconWavelength: 0.625,
|
|
1392
|
+
iconMaskOn: true,
|
|
1306
1393
|
iconMaskScale: 3.8
|
|
1307
|
-
}
|
|
1394
|
+
},
|
|
1395
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
1396
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
1308
1397
|
};
|
|
1398
|
+
|
|
1399
|
+
// src/editor/core/sketch/sketchStyles.ts
|
|
1400
|
+
var SHIPPED_FILES = { pencil: pencil_default, marker: marker_default, whiteboard: whiteboard_default, hatched: hatched_default, dashed: dashed_default, napkin: napkin_default, dry: dry_default };
|
|
1401
|
+
var SKETCH_STYLES = Object.fromEntries(
|
|
1402
|
+
Object.entries(SHIPPED_FILES).map(([id, file]) => [id, file.settings])
|
|
1403
|
+
);
|
|
1309
1404
|
var DEFAULT_SKETCH_STYLE = "marker";
|
|
1310
1405
|
function hydrateSketchStyle(raw) {
|
|
1311
|
-
const
|
|
1406
|
+
const base = SKETCH_STYLES[DEFAULT_SKETCH_STYLE];
|
|
1312
1407
|
const stored = raw ?? {};
|
|
1313
|
-
const out = { ...
|
|
1314
|
-
for (const key of Object.keys(
|
|
1408
|
+
const out = { ...base };
|
|
1409
|
+
for (const key of Object.keys(base)) {
|
|
1315
1410
|
if (stored[key] !== void 0) out[key] = stored[key];
|
|
1316
1411
|
}
|
|
1317
|
-
if (out.fillStyle === "none") out.fillStyle =
|
|
1412
|
+
if (out.fillStyle === "none") out.fillStyle = base.fillStyle;
|
|
1318
1413
|
convertTiledMask(stored, out);
|
|
1319
1414
|
convertCutToLevels(stored, out);
|
|
1320
1415
|
carryLevelsToOutput(stored, out);
|
|
1321
1416
|
halveSwingDials(stored, out);
|
|
1417
|
+
splitBlobAxes(stored, out);
|
|
1322
1418
|
convertCyclesToWavelength(stored, out);
|
|
1323
1419
|
convertIconTileToScale(stored, out);
|
|
1324
1420
|
restoreDerivedRetrace(stored, out);
|
|
@@ -1350,6 +1446,13 @@ function convertCyclesToWavelength(stored, out) {
|
|
|
1350
1446
|
const layers = stored.octaves;
|
|
1351
1447
|
if (typeof layers === "number") out.roughness = Math.min(3, Math.max(1, layers));
|
|
1352
1448
|
}
|
|
1449
|
+
function splitBlobAxes(stored, out) {
|
|
1450
|
+
const blob = stored.maskBlob;
|
|
1451
|
+
if (typeof blob !== "number") return;
|
|
1452
|
+
out.maskBlobX = blob;
|
|
1453
|
+
out.maskBlobY = blob;
|
|
1454
|
+
out.maskBlobLinked = true;
|
|
1455
|
+
}
|
|
1353
1456
|
function convertIconTileToScale(stored, out) {
|
|
1354
1457
|
const tile = stored.iconMaskTile;
|
|
1355
1458
|
if (typeof tile !== "number") return;
|
|
@@ -1365,7 +1468,10 @@ function convertTiledMask(stored, out) {
|
|
|
1365
1468
|
const scale = stored.maskScale;
|
|
1366
1469
|
if (typeof scale !== "number") return;
|
|
1367
1470
|
const freq = stored.maskFrequency;
|
|
1368
|
-
if (typeof freq === "number")
|
|
1471
|
+
if (typeof freq === "number") {
|
|
1472
|
+
out.maskBlobX = Math.round(scale / (freq * LEGACY_TILE));
|
|
1473
|
+
out.maskBlobY = out.maskBlobX;
|
|
1474
|
+
}
|
|
1369
1475
|
const soft = stored.maskSoftness;
|
|
1370
1476
|
if (typeof soft === "number") out.maskSoftness = Number((soft * scale / LEGACY_TILE).toFixed(1));
|
|
1371
1477
|
}
|
|
@@ -1478,12 +1584,12 @@ function normalizeTheme(raw, resolvers) {
|
|
|
1478
1584
|
}
|
|
1479
1585
|
const filled = { components: [], aliases: 0, orphans: 0 };
|
|
1480
1586
|
for (const comp of resolvers.listComponentNames()) {
|
|
1481
|
-
const
|
|
1482
|
-
const baseAliases =
|
|
1483
|
-
if (!
|
|
1587
|
+
const base = asObject(resolvers.readComponentConfig(comp, "default"));
|
|
1588
|
+
const baseAliases = base ? asObject(base.aliases) : null;
|
|
1589
|
+
if (!base || !baseAliases) continue;
|
|
1484
1590
|
const entry = componentConfigs[comp];
|
|
1485
1591
|
if (!entry) {
|
|
1486
|
-
const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(
|
|
1592
|
+
const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(base);
|
|
1487
1593
|
componentConfigs[comp] = structuredClone(rest);
|
|
1488
1594
|
filled.components.push(comp);
|
|
1489
1595
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.67.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Design token editor with live CSS variable editing. Svelte 5 + Vite 8.",
|
|
6
6
|
"keywords": [
|
|
@@ -41,6 +41,13 @@
|
|
|
41
41
|
"src/live-tokens/data/themes/sketchy.json",
|
|
42
42
|
"src/live-tokens/data/themes/spring-meadow.json",
|
|
43
43
|
"src/live-tokens/data/themes/sunset.json",
|
|
44
|
+
"src/live-tokens/data/sketch-styles/pencil.json",
|
|
45
|
+
"src/live-tokens/data/sketch-styles/marker.json",
|
|
46
|
+
"src/live-tokens/data/sketch-styles/whiteboard.json",
|
|
47
|
+
"src/live-tokens/data/sketch-styles/hatched.json",
|
|
48
|
+
"src/live-tokens/data/sketch-styles/dashed.json",
|
|
49
|
+
"src/live-tokens/data/sketch-styles/napkin.json",
|
|
50
|
+
"src/live-tokens/data/sketch-styles/dry.json",
|
|
44
51
|
"dist-plugin",
|
|
45
52
|
".claude/skills",
|
|
46
53
|
"bin",
|
package/src/editor/bootstrap.ts
CHANGED
|
@@ -22,10 +22,16 @@ import * as editorStore from './core/store/editorStore';
|
|
|
22
22
|
import * as themeDocumentSync from './core/themes/themeDocumentSync';
|
|
23
23
|
import { initializeTheme } from './core/themes/themeInit';
|
|
24
24
|
import { registerComponent, type RegisterComponentEntry } from './component-editor/registry';
|
|
25
|
+
import { registerSketchLook, type RegisterSketchLookInput } from './core/sketch/sketchRegistry';
|
|
25
26
|
|
|
26
27
|
export interface BootLiveTokensOptions {
|
|
27
28
|
/** Consumer-authored components to register with the editor before mount. Dev-only. */
|
|
28
29
|
components?: RegisterComponentEntry[];
|
|
30
|
+
/** Sketchstyles this project ships, joining the shipped looks in every
|
|
31
|
+
picker. Registered in a build as well as in dev: carrying a customized
|
|
32
|
+
sketchstyle to a published site is the whole point, so these must not sit
|
|
33
|
+
behind the DEV guard `components` sits behind. */
|
|
34
|
+
sketchLooks?: RegisterSketchLookInput[];
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
export async function bootLiveTokens(
|
|
@@ -38,6 +44,12 @@ export async function bootLiveTokens(
|
|
|
38
44
|
columnsOverlay.init();
|
|
39
45
|
editorStore.init();
|
|
40
46
|
|
|
47
|
+
// Before the DEV block: `initializeTheme` recovers the open theme's look by
|
|
48
|
+
// name against the pool, so the pool has to be whole by the time it runs.
|
|
49
|
+
if (opts.sketchLooks) {
|
|
50
|
+
for (const look of opts.sketchLooks) registerSketchLook(look);
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
if (import.meta.env.DEV) {
|
|
42
54
|
themeDocumentSync.init();
|
|
43
55
|
if (opts.components) {
|
|
@@ -37,7 +37,7 @@ export function bumpComponentActiveRevision(): void {
|
|
|
37
37
|
* Set by the client writes that move the live look (`writeWorkingColorsAndType`,
|
|
38
38
|
* `writeWorkingComponentConfig`, `saveActiveTheme`, `saveAsTheme`, and every
|
|
39
39
|
* sketch gesture that changes what the effect paints: `setSketchEnabled`,
|
|
40
|
-
* `updateSketchSettings`, `selectSketchStyle
|
|
40
|
+
* `updateSketchSettings`, `selectSketchStyle`);
|
|
41
41
|
* cleared by `adoptLook` and by `hydrateAppliedTheme`, on this document and on
|
|
42
42
|
* every peer an Apply broadcasts to. Module-level, so it survives the
|
|
43
43
|
* remounts a view switch causes.
|