material-theme-builder 3.3.0 → 5.0.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/README.md +226 -193
- package/dist/cli.js +65 -283
- package/dist/index.js +22 -15
- package/dist/react.js +29 -30
- package/dist/shadcn.css +6 -6
- package/dist/tailwind-plugin.d.ts +13 -13
- package/package.json +4 -3
- package/dist/tailwind.css +0 -145
package/dist/cli.js
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import * as fs2 from "fs";
|
|
5
5
|
import * as path2 from "path";
|
|
6
|
-
import { Command as
|
|
6
|
+
import { Command, Option as Option2 } from "commander";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
|
|
9
9
|
// src/cli.options.ts
|
|
10
10
|
import {
|
|
11
|
-
Command,
|
|
12
11
|
InvalidArgumentError,
|
|
13
12
|
Option
|
|
14
13
|
} from "commander";
|
|
@@ -683,8 +682,8 @@ function buildShadcnAliases(ctx) {
|
|
|
683
682
|
const lines = Object.entries(toShadcnAliasVars(ctx.prefix)).map(
|
|
684
683
|
([name, value]) => `--${name}: ${value};`
|
|
685
684
|
);
|
|
686
|
-
return `:root,
|
|
687
|
-
.dark {
|
|
685
|
+
return `:root:root,
|
|
686
|
+
.dark.dark {
|
|
688
687
|
${lines.join("\n ")}
|
|
689
688
|
}
|
|
690
689
|
`;
|
|
@@ -870,6 +869,9 @@ function assertHexInputs(source, cores, customColors) {
|
|
|
870
869
|
(color, i) => assertHexColor(`customColors[${i}].hex`, color.hex)
|
|
871
870
|
);
|
|
872
871
|
}
|
|
872
|
+
function optionalHex(hex) {
|
|
873
|
+
return hex?.trim() || void 0;
|
|
874
|
+
}
|
|
873
875
|
var STANDARD_TONES = [
|
|
874
876
|
0,
|
|
875
877
|
4,
|
|
@@ -1038,16 +1040,20 @@ function builder(hexSource, {
|
|
|
1038
1040
|
customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS,
|
|
1039
1041
|
prefix = DEFAULT_PREFIX
|
|
1040
1042
|
} = {}) {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1043
|
+
const cores = {
|
|
1044
|
+
primary: optionalHex(primary),
|
|
1045
|
+
secondary: optionalHex(secondary),
|
|
1046
|
+
tertiary: optionalHex(tertiary),
|
|
1047
|
+
error: optionalHex(error),
|
|
1048
|
+
neutral: optionalHex(neutral),
|
|
1049
|
+
neutralVariant: optionalHex(neutralVariant)
|
|
1050
|
+
};
|
|
1051
|
+
assertHexInputs(hexSource, cores, hexCustomColors);
|
|
1046
1052
|
const sourceArgb = argbFromHex2(hexSource);
|
|
1047
1053
|
const sourceHct = Hct2.fromInt(sourceArgb);
|
|
1048
|
-
const effectiveSource = primary || hexSource;
|
|
1054
|
+
const effectiveSource = cores.primary || hexSource;
|
|
1049
1055
|
const effectiveSourceArgb = argbFromHex2(effectiveSource);
|
|
1050
|
-
const effectiveSourceForHarmonization = primary ? argbFromHex2(primary) : sourceArgb;
|
|
1056
|
+
const effectiveSourceForHarmonization = cores.primary ? argbFromHex2(cores.primary) : sourceArgb;
|
|
1051
1057
|
const SchemeClass = schemesMap[scheme];
|
|
1052
1058
|
const primaryHct = Hct2.fromInt(effectiveSourceArgb);
|
|
1053
1059
|
const baseScheme = new SchemeClass(primaryHct, false, contrast);
|
|
@@ -1055,32 +1061,32 @@ function builder(hexSource, {
|
|
|
1055
1061
|
// Core colors (hex may be undefined)
|
|
1056
1062
|
{
|
|
1057
1063
|
name: "primary",
|
|
1058
|
-
hex: primary,
|
|
1064
|
+
hex: cores.primary,
|
|
1059
1065
|
core: true,
|
|
1060
1066
|
chromaSource: "primary"
|
|
1061
1067
|
},
|
|
1062
1068
|
{
|
|
1063
1069
|
name: "secondary",
|
|
1064
|
-
hex: secondary,
|
|
1070
|
+
hex: cores.secondary,
|
|
1065
1071
|
core: true,
|
|
1066
1072
|
chromaSource: "primary"
|
|
1067
1073
|
},
|
|
1068
1074
|
{
|
|
1069
1075
|
name: "tertiary",
|
|
1070
|
-
hex: tertiary,
|
|
1076
|
+
hex: cores.tertiary,
|
|
1071
1077
|
core: true,
|
|
1072
1078
|
chromaSource: "primary"
|
|
1073
1079
|
},
|
|
1074
|
-
{ name: "error", hex: error, core: true, chromaSource: "primary" },
|
|
1080
|
+
{ name: "error", hex: cores.error, core: true, chromaSource: "primary" },
|
|
1075
1081
|
{
|
|
1076
1082
|
name: "neutral",
|
|
1077
|
-
hex: neutral,
|
|
1083
|
+
hex: cores.neutral,
|
|
1078
1084
|
core: true,
|
|
1079
1085
|
chromaSource: "neutral"
|
|
1080
1086
|
},
|
|
1081
1087
|
{
|
|
1082
1088
|
name: "neutralVariant",
|
|
1083
|
-
hex: neutralVariant,
|
|
1089
|
+
hex: cores.neutralVariant,
|
|
1084
1090
|
core: true,
|
|
1085
1091
|
chromaSource: "neutralVariant"
|
|
1086
1092
|
},
|
|
@@ -1231,7 +1237,6 @@ function addThemeOptions(command) {
|
|
|
1231
1237
|
DEFAULT_PREFIX
|
|
1232
1238
|
);
|
|
1233
1239
|
}
|
|
1234
|
-
var THEME_OPTIONS = addThemeOptions(new Command()).options;
|
|
1235
1240
|
function builderOptions(opts) {
|
|
1236
1241
|
return {
|
|
1237
1242
|
scheme: opts.scheme,
|
|
@@ -1245,16 +1250,6 @@ function builderOptions(opts) {
|
|
|
1245
1250
|
prefix: opts.prefix
|
|
1246
1251
|
};
|
|
1247
1252
|
}
|
|
1248
|
-
function specifiedThemeArgs(command) {
|
|
1249
|
-
const args = [];
|
|
1250
|
-
for (const option of THEME_OPTIONS) {
|
|
1251
|
-
const name = option.attributeName();
|
|
1252
|
-
if (command.getOptionValueSource(name) !== "cli") continue;
|
|
1253
|
-
if (option.long) args.push(option.long);
|
|
1254
|
-
if (!option.negate) args.push(String(command.opts()[name]));
|
|
1255
|
-
}
|
|
1256
|
-
return args;
|
|
1257
|
-
}
|
|
1258
1253
|
function themeFrom(command) {
|
|
1259
1254
|
const opts = command.opts();
|
|
1260
1255
|
return {
|
|
@@ -1263,256 +1258,48 @@ function themeFrom(command) {
|
|
|
1263
1258
|
// opposite of the API's, and deliberately so: a CLI knows the source color,
|
|
1264
1259
|
// which is what makes baking its colors in as the fallbacks free. See
|
|
1265
1260
|
// `buildShadcnRegistryItem()`.
|
|
1266
|
-
fallback: opts.fallback ?? true
|
|
1267
|
-
args: specifiedThemeArgs(command)
|
|
1261
|
+
fallback: opts.fallback ?? true
|
|
1268
1262
|
};
|
|
1269
1263
|
}
|
|
1270
1264
|
|
|
1271
1265
|
// src/cli.shadcn.ts
|
|
1272
1266
|
import { spawnSync } from "child_process";
|
|
1273
1267
|
import * as fs from "fs";
|
|
1274
|
-
import * as os from "os";
|
|
1275
1268
|
import * as path from "path";
|
|
1276
|
-
import
|
|
1269
|
+
import "commander";
|
|
1277
1270
|
var NPX = ["npx", "--yes"];
|
|
1278
1271
|
var DEFAULT_SHADCN = "shadcn@latest";
|
|
1279
|
-
var
|
|
1280
|
-
var INIT_TARGET = "shadcn init";
|
|
1281
|
-
var ADD_TARGET = "shadcn add";
|
|
1272
|
+
var YES = "--yes";
|
|
1282
1273
|
var ITEM = "mtb.json";
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
var YES = { long: "--yes", short: "-y" };
|
|
1286
|
-
var INIT_DEFAULTS = [
|
|
1287
|
-
{ long: "--preset", short: "-p", value: "b0" },
|
|
1288
|
-
{ long: "--template", short: "-t", value: "vite" },
|
|
1289
|
-
NAME,
|
|
1290
|
-
YES
|
|
1291
|
-
];
|
|
1292
|
-
var ADD_DEFAULTS = [YES];
|
|
1293
|
-
function parseShadcnSpec(value) {
|
|
1294
|
-
if (value.startsWith("-"))
|
|
1295
|
-
throw new InvalidArgumentError2(
|
|
1296
|
-
"A package spec cannot start with '-': npx would read it as one of its own options."
|
|
1297
|
-
);
|
|
1298
|
-
if (/^\d/.test(value))
|
|
1299
|
-
throw new InvalidArgumentError2(
|
|
1300
|
-
`That is a version, not a package spec -- write 'shadcn@${value}'.`
|
|
1301
|
-
);
|
|
1302
|
-
return value;
|
|
1303
|
-
}
|
|
1304
|
-
function addChainOptions(command) {
|
|
1305
|
-
return command.option(
|
|
1306
|
-
"--shadcn-cli <spec>",
|
|
1307
|
-
"npx package spec for the shadcn CLI to run (a version, tag, fork or tarball \u2014 anything npx resolves)",
|
|
1308
|
-
parseShadcnSpec,
|
|
1309
|
-
DEFAULT_SHADCN
|
|
1310
|
-
).option(
|
|
1311
|
-
"--print",
|
|
1312
|
-
"Print the equivalent shell chain instead of running it"
|
|
1313
|
-
);
|
|
1314
|
-
}
|
|
1315
|
-
function mentions(args, { long, short }) {
|
|
1316
|
-
return args.some(
|
|
1317
|
-
(arg) => arg === long || arg.startsWith(`${long}=`) || arg.startsWith(short)
|
|
1318
|
-
);
|
|
1319
|
-
}
|
|
1320
|
-
function mergeDefaults(defaults, forwarded) {
|
|
1321
|
-
const injected = defaults.filter((option) => !mentions(forwarded, option)).flatMap(
|
|
1322
|
-
({ long, value }) => value === void 0 ? [long] : [long, value]
|
|
1323
|
-
);
|
|
1324
|
-
return [...injected, ...forwarded];
|
|
1325
|
-
}
|
|
1326
|
-
function lastName(args) {
|
|
1327
|
-
for (let i = args.length - 1; i >= 0; i--) {
|
|
1328
|
-
const arg = args[i] ?? "";
|
|
1329
|
-
if (arg === NAME.long || arg === NAME.short) return args[i + 1];
|
|
1330
|
-
if (arg.startsWith(`${NAME.long}=`)) return arg.slice(NAME.long.length + 1);
|
|
1331
|
-
if (arg.length > NAME.short.length && arg.startsWith(NAME.short))
|
|
1332
|
-
return arg.slice(NAME.short.length);
|
|
1333
|
-
}
|
|
1334
|
-
return void 0;
|
|
1335
|
-
}
|
|
1336
|
-
function ownOptionIn(declared, forwarded) {
|
|
1337
|
-
return forwarded.find(
|
|
1338
|
-
(arg) => declared.some(
|
|
1339
|
-
(option) => arg === option.long || arg === option.short || option.long !== void 0 && arg.startsWith(`${option.long}=`)
|
|
1340
|
-
)
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
function refuseOwnOptions(command, forwarded, target) {
|
|
1344
|
-
const misplaced = ownOptionIn(command.options, forwarded);
|
|
1345
|
-
if (misplaced !== void 0)
|
|
1346
|
-
fail(
|
|
1347
|
-
`${misplaced} is ours, not shadcn's, so it belongs before the \`--\`. Everything after the separator is handed to \`${target}\` untouched.`
|
|
1348
|
-
);
|
|
1349
|
-
}
|
|
1350
|
-
var DEFAULT_THEME = { options: {}, fallback: true, args: [] };
|
|
1351
|
-
function chainOptionsFrom(command) {
|
|
1352
|
-
return { theme: themeFrom(command), shadcn: command.opts().shadcnCli };
|
|
1353
|
-
}
|
|
1354
|
-
function initPlan(source, forwarded = [], {
|
|
1355
|
-
theme = DEFAULT_THEME,
|
|
1356
|
-
shadcn = DEFAULT_SHADCN
|
|
1357
|
-
} = {}) {
|
|
1358
|
-
const args = mergeDefaults(INIT_DEFAULTS, forwarded);
|
|
1359
|
-
const dir = lastName(args) ?? APP_NAME;
|
|
1360
|
-
return {
|
|
1361
|
-
source,
|
|
1362
|
-
theme,
|
|
1363
|
-
dir,
|
|
1364
|
-
steps: [
|
|
1365
|
-
{
|
|
1366
|
-
kind: "spawn",
|
|
1367
|
-
label: INIT_TARGET,
|
|
1368
|
-
argv: [...NPX, shadcn, "init", ...args],
|
|
1369
|
-
where: "cwd"
|
|
1370
|
-
},
|
|
1371
|
-
{ kind: "cd", dir },
|
|
1372
|
-
{ kind: "item", file: ITEM },
|
|
1373
|
-
// The same spec as the step above, deliberately: a chain pinned for the
|
|
1374
|
-
// scaffold and floating for the install is worse than one that floats
|
|
1375
|
-
// throughout, since the two would disagree about the registry format
|
|
1376
|
-
// without saying so.
|
|
1377
|
-
{
|
|
1378
|
-
kind: "spawn",
|
|
1379
|
-
label: ADD_TARGET,
|
|
1380
|
-
argv: [
|
|
1381
|
-
...NPX,
|
|
1382
|
-
shadcn,
|
|
1383
|
-
"add",
|
|
1384
|
-
`./${ITEM}`,
|
|
1385
|
-
...mergeDefaults(ADD_DEFAULTS, [])
|
|
1386
|
-
],
|
|
1387
|
-
where: "project"
|
|
1388
|
-
},
|
|
1389
|
-
{ kind: "rm", file: ITEM },
|
|
1390
|
-
// The handover: long-running by design, stdio inherited, ctrl-C reaching
|
|
1391
|
-
// it. Package-manager detection is out of scope -- `shadcn init` under
|
|
1392
|
-
// `npx` writes a `package-lock.json` and the `dev` script npm will run.
|
|
1393
|
-
{
|
|
1394
|
-
kind: "spawn",
|
|
1395
|
-
label: "npm run dev",
|
|
1396
|
-
argv: ["npm", "run", "dev"],
|
|
1397
|
-
where: "project"
|
|
1398
|
-
}
|
|
1399
|
-
]
|
|
1400
|
-
};
|
|
1401
|
-
}
|
|
1402
|
-
function applyPlan(source, forwarded = [], {
|
|
1403
|
-
theme = DEFAULT_THEME,
|
|
1404
|
-
shadcn = DEFAULT_SHADCN
|
|
1405
|
-
} = {}) {
|
|
1406
|
-
return {
|
|
1407
|
-
source,
|
|
1408
|
-
theme,
|
|
1409
|
-
steps: [
|
|
1410
|
-
{ kind: "item", file: ITEM },
|
|
1411
|
-
{
|
|
1412
|
-
kind: "spawn",
|
|
1413
|
-
label: ADD_TARGET,
|
|
1414
|
-
argv: [
|
|
1415
|
-
...NPX,
|
|
1416
|
-
shadcn,
|
|
1417
|
-
"add",
|
|
1418
|
-
`./${ITEM}`,
|
|
1419
|
-
...mergeDefaults(ADD_DEFAULTS, forwarded)
|
|
1420
|
-
],
|
|
1421
|
-
where: "cwd"
|
|
1422
|
-
},
|
|
1423
|
-
{ kind: "rm", file: ITEM }
|
|
1424
|
-
]
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1427
|
-
var SHELL_SAFE = /^[\w@%+=:,./-]+$/;
|
|
1428
|
-
function quote(argv) {
|
|
1429
|
-
return argv.map(
|
|
1430
|
-
(arg) => SHELL_SAFE.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`
|
|
1431
|
-
).join(" ");
|
|
1432
|
-
}
|
|
1433
|
-
function renderStep(plan, step) {
|
|
1434
|
-
switch (step.kind) {
|
|
1435
|
-
case "spawn":
|
|
1436
|
-
return quote(step.argv);
|
|
1437
|
-
case "cd":
|
|
1438
|
-
return `cd ${step.dir}`;
|
|
1439
|
-
// Rendered as the command someone could have run themselves -- theme options
|
|
1440
|
-
// included, or the line would describe a different theme from the one the
|
|
1441
|
-
// runner generates. The runner does the same thing in-process, being the very
|
|
1442
|
-
// binary this spawns.
|
|
1443
|
-
case "item":
|
|
1444
|
-
return `${quote([...NPX, SELF, plan.source, ...plan.theme.args, "--format", "registry-item"])} > ${step.file}`;
|
|
1445
|
-
case "rm":
|
|
1446
|
-
return `rm ${step.file}`;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
function renderChain(plan) {
|
|
1450
|
-
return plan.steps.map((step) => renderStep(plan, step)).join(" && ");
|
|
1274
|
+
function addArgv(shadcn, forwarded = []) {
|
|
1275
|
+
return [...NPX, shadcn, "add", `./${ITEM}`, YES, ...forwarded];
|
|
1451
1276
|
}
|
|
1452
1277
|
function fail(message, code = 1) {
|
|
1453
1278
|
console.error(`Error: ${message}`);
|
|
1454
1279
|
process.exit(code);
|
|
1455
1280
|
}
|
|
1456
|
-
function
|
|
1457
|
-
const [command = "", ...args] = argv;
|
|
1458
|
-
const { error, status, signal } = spawnSync(command, args, {
|
|
1459
|
-
cwd,
|
|
1460
|
-
stdio: "inherit",
|
|
1461
|
-
shell: false
|
|
1462
|
-
});
|
|
1463
|
-
if (error) fail(`${label} could not be started: ${error.message}`);
|
|
1464
|
-
if (signal) process.exit(128 + (os.constants.signals[signal] ?? 0));
|
|
1465
|
-
if (status !== 0) fail(`${label} failed`, status ?? 1);
|
|
1466
|
-
}
|
|
1467
|
-
function writeItem({ source, theme }, file) {
|
|
1281
|
+
function writeItem(source, command, file) {
|
|
1468
1282
|
if (fs.existsSync(file))
|
|
1469
1283
|
fail(
|
|
1470
1284
|
`${path.basename(file)} already exists and would be overwritten, then deleted. Move it aside first.`
|
|
1471
1285
|
);
|
|
1472
1286
|
process.on("exit", () => fs.rmSync(file, { force: true }));
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1475
|
-
});
|
|
1287
|
+
const { options, fallback } = themeFrom(command);
|
|
1288
|
+
const item = builder(source, options).toShadcnRegistryItem({ fallback });
|
|
1476
1289
|
fs.writeFileSync(file, `${JSON.stringify(item, null, 2)}
|
|
1477
1290
|
`);
|
|
1478
1291
|
}
|
|
1479
|
-
function runStep(plan, step, projectDir) {
|
|
1480
|
-
switch (step.kind) {
|
|
1481
|
-
case "spawn":
|
|
1482
|
-
return run(step, step.where === "project" ? projectDir : process.cwd());
|
|
1483
|
-
case "item":
|
|
1484
|
-
return writeItem(plan, path.join(projectDir, step.file));
|
|
1485
|
-
case "rm":
|
|
1486
|
-
return fs.rmSync(path.join(projectDir, step.file), { force: true });
|
|
1487
|
-
// Nothing to do: the runner resolved the directory up front, where a shell
|
|
1488
|
-
// would have changed into it. The step exists so that `--print` can say so.
|
|
1489
|
-
case "cd":
|
|
1490
|
-
return;
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
function runChain(plan) {
|
|
1494
|
-
const projectDir = plan.dir ? path.resolve(plan.dir) : process.cwd();
|
|
1495
|
-
if (plan.dir && fs.existsSync(projectDir))
|
|
1496
|
-
fail(
|
|
1497
|
-
`./${plan.dir} already exists. Pick another name with \`-- -n other-name\`, or remove it first.`
|
|
1498
|
-
);
|
|
1499
|
-
for (const step of plan.steps) runStep(plan, step, projectDir);
|
|
1500
|
-
}
|
|
1501
|
-
function execute(plan, command) {
|
|
1502
|
-
if (command.opts().print === true) {
|
|
1503
|
-
process.stdout.write(`${renderChain(plan)}
|
|
1504
|
-
`);
|
|
1505
|
-
return;
|
|
1506
|
-
}
|
|
1507
|
-
runChain(plan);
|
|
1508
|
-
}
|
|
1509
|
-
function runInit(source, forwarded, command) {
|
|
1510
|
-
refuseOwnOptions(command, forwarded, INIT_TARGET);
|
|
1511
|
-
execute(initPlan(source, forwarded, chainOptionsFrom(command)), command);
|
|
1512
|
-
}
|
|
1513
1292
|
function runApply(source, forwarded, command) {
|
|
1514
|
-
|
|
1515
|
-
|
|
1293
|
+
const file = path.resolve(ITEM);
|
|
1294
|
+
writeItem(source, command, file);
|
|
1295
|
+
const [bin = "", ...args] = addArgv(command.opts().shadcnCli, forwarded);
|
|
1296
|
+
const { error, status } = spawnSync(bin, args, {
|
|
1297
|
+
stdio: "inherit",
|
|
1298
|
+
shell: false
|
|
1299
|
+
});
|
|
1300
|
+
if (error) fail(`shadcn add could not be started: ${error.message}`);
|
|
1301
|
+
if (status !== 0) fail("shadcn add failed", status ?? 1);
|
|
1302
|
+
fs.rmSync(file, { force: true });
|
|
1516
1303
|
}
|
|
1517
1304
|
|
|
1518
1305
|
// src/cli.ts
|
|
@@ -1534,9 +1321,20 @@ function writeFigmaTokens(theme, outputDir) {
|
|
|
1534
1321
|
console.error(`wrote ${filePath}`);
|
|
1535
1322
|
}
|
|
1536
1323
|
}
|
|
1324
|
+
var FORMATS = [
|
|
1325
|
+
"json",
|
|
1326
|
+
"css",
|
|
1327
|
+
"figma",
|
|
1328
|
+
"tailwind",
|
|
1329
|
+
"shadcn",
|
|
1330
|
+
"registry-item",
|
|
1331
|
+
"flutter"
|
|
1332
|
+
];
|
|
1537
1333
|
function writeOutput(theme, opts) {
|
|
1538
1334
|
const json = (value) => JSON.stringify(value, null, 2) + "\n";
|
|
1539
1335
|
switch (opts.format) {
|
|
1336
|
+
case "json":
|
|
1337
|
+
return process.stdout.write(json(theme.toJson()));
|
|
1540
1338
|
case "css":
|
|
1541
1339
|
return process.stdout.write(theme.toCss());
|
|
1542
1340
|
case "tailwind":
|
|
@@ -1551,11 +1349,9 @@ function writeOutput(theme, opts) {
|
|
|
1551
1349
|
return process.stdout.write(theme.toFlutter());
|
|
1552
1350
|
case "figma":
|
|
1553
1351
|
return writeFigmaTokens(theme, opts.output ?? "material-theme");
|
|
1554
|
-
default:
|
|
1555
|
-
return process.stdout.write(json(theme.toJson()));
|
|
1556
1352
|
}
|
|
1557
1353
|
}
|
|
1558
|
-
var program = new
|
|
1354
|
+
var program = new Command();
|
|
1559
1355
|
addThemeOptions(
|
|
1560
1356
|
addSourceArgument(
|
|
1561
1357
|
program.name("material-theme-builder").description("Generate a color theme from a source color")
|
|
@@ -1563,10 +1359,8 @@ addThemeOptions(
|
|
|
1563
1359
|
).option(
|
|
1564
1360
|
"--custom-colors <json>",
|
|
1565
1361
|
`Custom colors as JSON array (e.g. '[{"name":"brand","hex":"#FF5733","blend":true}]')`
|
|
1566
|
-
).
|
|
1567
|
-
"--format <type>",
|
|
1568
|
-
"Output format: json, css, figma, tailwind, shadcn, registry-item, or flutter",
|
|
1569
|
-
"figma"
|
|
1362
|
+
).addOption(
|
|
1363
|
+
new Option2("--format <type>", "Output format").choices(FORMATS).default("figma")
|
|
1570
1364
|
).option("--output <dir>", "Output directory (required for figma format)").option(
|
|
1571
1365
|
"--shadcn",
|
|
1572
1366
|
"Append the shadcn var() alias block to --format tailwind (for concrete values, use --format shadcn)"
|
|
@@ -1609,29 +1403,17 @@ addThemeOptions(
|
|
|
1609
1403
|
});
|
|
1610
1404
|
writeOutput(result, opts);
|
|
1611
1405
|
});
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
).argument(
|
|
1619
|
-
"[shadcn-args...]",
|
|
1620
|
-
"Options after a `--`, forwarded verbatim to `shadcn init`"
|
|
1621
|
-
)
|
|
1622
|
-
)
|
|
1623
|
-
).action(
|
|
1624
|
-
(source, shadcnArgs, _opts, command) => runInit(source, shadcnArgs, command)
|
|
1625
|
-
);
|
|
1626
|
-
addChainOptions(
|
|
1627
|
-
addThemeOptions(
|
|
1628
|
-
addSourceArgument(
|
|
1629
|
-
program.command("shadcn-apply").description("Theme the shadcn project in the current directory")
|
|
1630
|
-
).argument(
|
|
1631
|
-
"[shadcn-args...]",
|
|
1632
|
-
"Options after a `--`, forwarded verbatim to `shadcn add`"
|
|
1633
|
-
)
|
|
1406
|
+
addThemeOptions(
|
|
1407
|
+
addSourceArgument(
|
|
1408
|
+
program.command("shadcn-apply").description("Theme the shadcn project in the current directory")
|
|
1409
|
+
).argument(
|
|
1410
|
+
"[shadcn-args...]",
|
|
1411
|
+
"Options after a `--`, forwarded verbatim to `shadcn add`"
|
|
1634
1412
|
)
|
|
1413
|
+
).option(
|
|
1414
|
+
"--shadcn-cli <spec>",
|
|
1415
|
+
"npx package spec for the shadcn CLI to run (a version, tag, fork or tarball \u2014 anything npx resolves)",
|
|
1416
|
+
DEFAULT_SHADCN
|
|
1635
1417
|
).action(
|
|
1636
1418
|
(source, shadcnArgs, _opts, command) => runApply(source, shadcnArgs, command)
|
|
1637
1419
|
);
|
package/dist/index.js
CHANGED
|
@@ -668,8 +668,8 @@ function buildShadcnAliases(ctx) {
|
|
|
668
668
|
const lines = Object.entries(toShadcnAliasVars(ctx.prefix)).map(
|
|
669
669
|
([name, value]) => `--${name}: ${value};`
|
|
670
670
|
);
|
|
671
|
-
return `:root,
|
|
672
|
-
.dark {
|
|
671
|
+
return `:root:root,
|
|
672
|
+
.dark.dark {
|
|
673
673
|
${lines.join("\n ")}
|
|
674
674
|
}
|
|
675
675
|
`;
|
|
@@ -846,6 +846,9 @@ function assertHexInputs(source, cores, customColors) {
|
|
|
846
846
|
(color, i) => assertHexColor(`customColors[${i}].hex`, color.hex)
|
|
847
847
|
);
|
|
848
848
|
}
|
|
849
|
+
function optionalHex(hex) {
|
|
850
|
+
return hex?.trim() || void 0;
|
|
851
|
+
}
|
|
849
852
|
var STANDARD_TONES = [
|
|
850
853
|
0,
|
|
851
854
|
4,
|
|
@@ -1014,16 +1017,20 @@ function builder(hexSource, {
|
|
|
1014
1017
|
customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS,
|
|
1015
1018
|
prefix = DEFAULT_PREFIX
|
|
1016
1019
|
} = {}) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1020
|
+
const cores = {
|
|
1021
|
+
primary: optionalHex(primary),
|
|
1022
|
+
secondary: optionalHex(secondary),
|
|
1023
|
+
tertiary: optionalHex(tertiary),
|
|
1024
|
+
error: optionalHex(error),
|
|
1025
|
+
neutral: optionalHex(neutral),
|
|
1026
|
+
neutralVariant: optionalHex(neutralVariant)
|
|
1027
|
+
};
|
|
1028
|
+
assertHexInputs(hexSource, cores, hexCustomColors);
|
|
1022
1029
|
const sourceArgb = argbFromHex2(hexSource);
|
|
1023
1030
|
const sourceHct = Hct2.fromInt(sourceArgb);
|
|
1024
|
-
const effectiveSource = primary || hexSource;
|
|
1031
|
+
const effectiveSource = cores.primary || hexSource;
|
|
1025
1032
|
const effectiveSourceArgb = argbFromHex2(effectiveSource);
|
|
1026
|
-
const effectiveSourceForHarmonization = primary ? argbFromHex2(primary) : sourceArgb;
|
|
1033
|
+
const effectiveSourceForHarmonization = cores.primary ? argbFromHex2(cores.primary) : sourceArgb;
|
|
1027
1034
|
const SchemeClass = schemesMap[scheme];
|
|
1028
1035
|
const primaryHct = Hct2.fromInt(effectiveSourceArgb);
|
|
1029
1036
|
const baseScheme = new SchemeClass(primaryHct, false, contrast);
|
|
@@ -1031,32 +1038,32 @@ function builder(hexSource, {
|
|
|
1031
1038
|
// Core colors (hex may be undefined)
|
|
1032
1039
|
{
|
|
1033
1040
|
name: "primary",
|
|
1034
|
-
hex: primary,
|
|
1041
|
+
hex: cores.primary,
|
|
1035
1042
|
core: true,
|
|
1036
1043
|
chromaSource: "primary"
|
|
1037
1044
|
},
|
|
1038
1045
|
{
|
|
1039
1046
|
name: "secondary",
|
|
1040
|
-
hex: secondary,
|
|
1047
|
+
hex: cores.secondary,
|
|
1041
1048
|
core: true,
|
|
1042
1049
|
chromaSource: "primary"
|
|
1043
1050
|
},
|
|
1044
1051
|
{
|
|
1045
1052
|
name: "tertiary",
|
|
1046
|
-
hex: tertiary,
|
|
1053
|
+
hex: cores.tertiary,
|
|
1047
1054
|
core: true,
|
|
1048
1055
|
chromaSource: "primary"
|
|
1049
1056
|
},
|
|
1050
|
-
{ name: "error", hex: error, core: true, chromaSource: "primary" },
|
|
1057
|
+
{ name: "error", hex: cores.error, core: true, chromaSource: "primary" },
|
|
1051
1058
|
{
|
|
1052
1059
|
name: "neutral",
|
|
1053
|
-
hex: neutral,
|
|
1060
|
+
hex: cores.neutral,
|
|
1054
1061
|
core: true,
|
|
1055
1062
|
chromaSource: "neutral"
|
|
1056
1063
|
},
|
|
1057
1064
|
{
|
|
1058
1065
|
name: "neutralVariant",
|
|
1059
|
-
hex: neutralVariant,
|
|
1066
|
+
hex: cores.neutralVariant,
|
|
1060
1067
|
core: true,
|
|
1061
1068
|
chromaSource: "neutralVariant"
|
|
1062
1069
|
},
|