@bison-lab/create-theme 3.2.0 → 3.6.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/dist/index.mjs +62 -168
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,8 @@ import pc from "picocolors";
|
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
6
6
|
import { dirname, join, relative, resolve } from "path";
|
|
7
|
-
import {
|
|
7
|
+
import { buildThemeCss, isThemeHex } from "@bison-lab/tokens";
|
|
8
|
+
import { catalog, findFontByFamily, isFontId } from "@bison-lab/fonts";
|
|
8
9
|
//#region src/preview.ts
|
|
9
10
|
function hexToRgb(hex) {
|
|
10
11
|
hex = hex.replace("#", "");
|
|
@@ -20,8 +21,17 @@ function previewHexColor(hex) {
|
|
|
20
21
|
}
|
|
21
22
|
//#endregion
|
|
22
23
|
//#region src/prompts.ts
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
/** The same rule `buildThemeCss` enforces, so the CLI never writes a config the derivation refuses. */
|
|
25
|
+
const isValidHex = isThemeHex;
|
|
26
|
+
/**
|
|
27
|
+
* The catalogue id to preselect for a stored value: the id itself, the id
|
|
28
|
+
* of a legacy family name (a config written before the catalogue), else
|
|
29
|
+
* the fallback.
|
|
30
|
+
*/
|
|
31
|
+
function catalogueId(stored, fallback) {
|
|
32
|
+
if (!stored) return fallback;
|
|
33
|
+
if (isFontId(stored)) return stored;
|
|
34
|
+
return findFontByFamily(stored)?.id ?? fallback;
|
|
25
35
|
}
|
|
26
36
|
async function runPrompts(existing) {
|
|
27
37
|
p.log.info(pc.bold("Brand Colors"));
|
|
@@ -237,10 +247,15 @@ async function runPrompts(existing) {
|
|
|
237
247
|
});
|
|
238
248
|
if (p.isCancel(density)) return null;
|
|
239
249
|
p.log.info(pc.bold("Typography"));
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
250
|
+
const fontOptions = catalog.map((font) => ({
|
|
251
|
+
value: font.id,
|
|
252
|
+
label: font.family,
|
|
253
|
+
hint: font.hint
|
|
254
|
+
}));
|
|
255
|
+
const fontBody = await p.select({
|
|
256
|
+
message: "Body font",
|
|
257
|
+
initialValue: catalogueId(existing?.fontBody, "inter"),
|
|
258
|
+
options: fontOptions
|
|
244
259
|
});
|
|
245
260
|
if (p.isCancel(fontBody)) return null;
|
|
246
261
|
const wantsHeading = await p.confirm({
|
|
@@ -250,10 +265,10 @@ async function runPrompts(existing) {
|
|
|
250
265
|
if (p.isCancel(wantsHeading)) return null;
|
|
251
266
|
let fontHeading = null;
|
|
252
267
|
if (wantsHeading) {
|
|
253
|
-
const heading = await p.
|
|
254
|
-
message: "Heading font
|
|
255
|
-
|
|
256
|
-
|
|
268
|
+
const heading = await p.select({
|
|
269
|
+
message: "Heading font",
|
|
270
|
+
initialValue: catalogueId(existing?.fontHeading, "playfair-display"),
|
|
271
|
+
options: fontOptions
|
|
257
272
|
});
|
|
258
273
|
if (p.isCancel(heading)) return null;
|
|
259
274
|
fontHeading = heading;
|
|
@@ -321,151 +336,13 @@ async function runPrompts(existing) {
|
|
|
321
336
|
}
|
|
322
337
|
//#endregion
|
|
323
338
|
//#region src/generate.ts
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
l: 10
|
|
332
|
-
}) : hslToString({
|
|
333
|
-
h: color.h,
|
|
334
|
-
s: clamp(color.s - 25, 0, 100),
|
|
335
|
-
l: 98
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
function boostForDark(color) {
|
|
339
|
-
if (color.l < 40) return {
|
|
340
|
-
...color,
|
|
341
|
-
l: clamp(color.l + 25, 0, 100)
|
|
342
|
-
};
|
|
343
|
-
return color;
|
|
344
|
-
}
|
|
345
|
-
function deriveLight(primary, secondary, accent, highlight, success, grey) {
|
|
346
|
-
return {
|
|
347
|
-
background: grey["50"],
|
|
348
|
-
foreground: grey["950"],
|
|
349
|
-
card: "0 0% 100%",
|
|
350
|
-
"card-foreground": grey["950"],
|
|
351
|
-
"surface-tertiary": grey["100"],
|
|
352
|
-
popover: "0 0% 100%",
|
|
353
|
-
"popover-foreground": grey["950"],
|
|
354
|
-
primary: hslToString(primary),
|
|
355
|
-
"primary-foreground": contrastForeground(primary),
|
|
356
|
-
secondary: hslToString(secondary),
|
|
357
|
-
"secondary-foreground": contrastForeground(secondary),
|
|
358
|
-
accent: grey["100"],
|
|
359
|
-
"accent-foreground": grey["950"],
|
|
360
|
-
"brand-accent": hslToString(accent),
|
|
361
|
-
"brand-accent-foreground": contrastForeground(accent),
|
|
362
|
-
highlight: hslToString(highlight),
|
|
363
|
-
"highlight-foreground": contrastForeground(highlight),
|
|
364
|
-
success: hslToString(success),
|
|
365
|
-
"success-foreground": contrastForeground(success),
|
|
366
|
-
muted: grey["100"],
|
|
367
|
-
"muted-foreground": grey["500"],
|
|
368
|
-
"content-secondary": grey["400"],
|
|
369
|
-
destructive: "0 84% 60%",
|
|
370
|
-
"destructive-foreground": "0 0% 98%",
|
|
371
|
-
border: grey["200"],
|
|
372
|
-
"border-strong": grey["300"],
|
|
373
|
-
"border-subtle": grey["100"],
|
|
374
|
-
input: grey["200"],
|
|
375
|
-
ring: hslToString(primary)
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
function deriveDark(primary, secondary, accent, highlight, success, grey) {
|
|
379
|
-
const dp = boostForDark(primary);
|
|
380
|
-
const ds = boostForDark(secondary);
|
|
381
|
-
const da = boostForDark(accent);
|
|
382
|
-
const dh = boostForDark(highlight);
|
|
383
|
-
const dsu = boostForDark(success);
|
|
384
|
-
return {
|
|
385
|
-
background: grey["950"],
|
|
386
|
-
foreground: grey["50"],
|
|
387
|
-
card: grey["900"],
|
|
388
|
-
"card-foreground": grey["50"],
|
|
389
|
-
"surface-tertiary": grey["800"],
|
|
390
|
-
popover: grey["900"],
|
|
391
|
-
"popover-foreground": grey["50"],
|
|
392
|
-
primary: hslToString(dp),
|
|
393
|
-
"primary-foreground": contrastForeground(dp),
|
|
394
|
-
secondary: hslToString(ds),
|
|
395
|
-
"secondary-foreground": contrastForeground(ds),
|
|
396
|
-
accent: grey["800"],
|
|
397
|
-
"accent-foreground": grey["50"],
|
|
398
|
-
"brand-accent": hslToString(da),
|
|
399
|
-
"brand-accent-foreground": contrastForeground(da),
|
|
400
|
-
highlight: hslToString(dh),
|
|
401
|
-
"highlight-foreground": contrastForeground(dh),
|
|
402
|
-
success: hslToString(dsu),
|
|
403
|
-
"success-foreground": contrastForeground(dsu),
|
|
404
|
-
muted: grey["800"],
|
|
405
|
-
"muted-foreground": grey["400"],
|
|
406
|
-
"content-secondary": grey["500"],
|
|
407
|
-
destructive: "0 62% 30%",
|
|
408
|
-
"destructive-foreground": "0 0% 98%",
|
|
409
|
-
border: grey["800"],
|
|
410
|
-
"border-strong": grey["700"],
|
|
411
|
-
"border-subtle": grey["900"],
|
|
412
|
-
input: grey["800"],
|
|
413
|
-
ring: hslToString(dp)
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
function generateThemeCSS(config) {
|
|
417
|
-
const primary = hexToHSL(config.brandPrimary);
|
|
418
|
-
const secondary = hexToHSL(config.brandSecondary);
|
|
419
|
-
const accent = hexToHSL(config.brandAccent);
|
|
420
|
-
const highlight = hexToHSL(config.brandHighlight);
|
|
421
|
-
const success = hexToHSL(config.brandSuccess);
|
|
422
|
-
const grey = GREY_SCALES[config.greyScale];
|
|
423
|
-
const light = deriveLight(primary, secondary, accent, highlight, success, grey);
|
|
424
|
-
const dark = deriveDark(primary, secondary, accent, highlight, success, grey);
|
|
425
|
-
const scales = generateBrandScales({
|
|
426
|
-
primary: config.brandPrimary,
|
|
427
|
-
secondary: config.brandSecondary,
|
|
428
|
-
accent: config.brandAccent,
|
|
429
|
-
highlight: config.brandHighlight,
|
|
430
|
-
success: config.brandSuccess
|
|
431
|
-
});
|
|
432
|
-
return [
|
|
433
|
-
`/* Bison Lab Theme — Generated by @bison-lab/create-theme */`,
|
|
434
|
-
`/* Brand: ${config.brandPrimary} / ${config.brandSecondary} / ${config.brandAccent} / ${config.brandHighlight} / ${config.brandSuccess} */`,
|
|
435
|
-
`/* Grey: ${config.greyScale} */`,
|
|
436
|
-
``,
|
|
437
|
-
`:root {`,
|
|
438
|
-
...Object.entries(light).map(([k, v]) => ` --${k}: ${v};`),
|
|
439
|
-
``,
|
|
440
|
-
` /* Brand color scales (50–950) */`,
|
|
441
|
-
generateScaleCSS(scales),
|
|
442
|
-
``,
|
|
443
|
-
` /* Destructive scale (50–950) — soft danger surfaces */`,
|
|
444
|
-
generateDestructiveScaleCSS(),
|
|
445
|
-
``,
|
|
446
|
-
` /* Typography */`,
|
|
447
|
-
` --font-body: '${config.fontBody}', ui-sans-serif, system-ui, sans-serif;`,
|
|
448
|
-
` --font-heading: '${config.fontHeading ?? config.fontBody}', ui-sans-serif, system-ui, sans-serif;`,
|
|
449
|
-
` --font-weight-normal: ${config.fontWeights.normal};`,
|
|
450
|
-
` --font-weight-medium: ${config.fontWeights.medium};`,
|
|
451
|
-
` --font-weight-semibold: ${config.fontWeights.semibold};`,
|
|
452
|
-
` --font-weight-bold: ${config.fontWeights.bold};`,
|
|
453
|
-
` --font-weight-extrabold: 800;`,
|
|
454
|
-
`}`,
|
|
455
|
-
``,
|
|
456
|
-
...config.darkSelector === "@media" ? [
|
|
457
|
-
`@media (prefers-color-scheme: dark) {`,
|
|
458
|
-
` :root {`,
|
|
459
|
-
...Object.entries(dark).map(([k, v]) => ` --${k}: ${v};`),
|
|
460
|
-
` }`,
|
|
461
|
-
`}`
|
|
462
|
-
] : [
|
|
463
|
-
`${config.darkSelector} {`,
|
|
464
|
-
...Object.entries(dark).map(([k, v]) => ` --${k}: ${v};`),
|
|
465
|
-
`}`
|
|
466
|
-
],
|
|
467
|
-
``
|
|
468
|
-
].join("\n");
|
|
339
|
+
/**
|
|
340
|
+
* `bison-theme.css` for a config. The derivation lives in `@bison-lab/tokens`
|
|
341
|
+
* (`buildThemeCss`) so this file, `BisonProvider` and a CMS theme rendered at
|
|
342
|
+
* request time all agree; the CLI only writes the result to disk.
|
|
343
|
+
*/
|
|
344
|
+
function generateThemeCSS(config, options) {
|
|
345
|
+
return buildThemeCss(config, options);
|
|
469
346
|
}
|
|
470
347
|
function generateTailwindConfig() {
|
|
471
348
|
return [
|
|
@@ -475,23 +352,36 @@ function generateTailwindConfig() {
|
|
|
475
352
|
`/* @import "./bison-theme.css"; */`
|
|
476
353
|
].join("\n");
|
|
477
354
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
`import '${themeImportPath}';`
|
|
486
|
-
].join("\n");
|
|
355
|
+
/**
|
|
356
|
+
* The layout imports. The theme CSS carries the radius, shadow, motion and
|
|
357
|
+
* density variables itself, so the four preset files are no longer imported;
|
|
358
|
+
* they stay published for consumers composing a theme by hand.
|
|
359
|
+
*/
|
|
360
|
+
function generateImports(themeImportPath) {
|
|
361
|
+
return [`import '@bison-lab/tokens/css/base.css';`, `import '${themeImportPath}';`].join("\n");
|
|
487
362
|
}
|
|
488
363
|
//#endregion
|
|
489
364
|
//#region src/index.ts
|
|
490
365
|
const BISON_PACKAGES = [
|
|
491
366
|
"@bison-lab/tokens",
|
|
492
367
|
"@bison-lab/ui",
|
|
493
|
-
"@bison-lab/tailwind-preset"
|
|
368
|
+
"@bison-lab/tailwind-preset",
|
|
369
|
+
"@bison-lab/fonts"
|
|
494
370
|
];
|
|
371
|
+
/**
|
|
372
|
+
* The theme CSS carries the `@font-face` rules for the chosen families under
|
|
373
|
+
* `/fonts`; this is the route that answers them, and the config line that
|
|
374
|
+
* keeps the package's font files reachable from the route.
|
|
375
|
+
*/
|
|
376
|
+
const FONT_ROUTE_SNIPPET = [
|
|
377
|
+
`// app/fonts/[...path]/route.ts`,
|
|
378
|
+
`import { serveFont } from "@bison-lab/fonts/server";`,
|
|
379
|
+
`export const GET = serveFont;`,
|
|
380
|
+
`export const HEAD = serveFont;`,
|
|
381
|
+
``,
|
|
382
|
+
`// next.config.ts`,
|
|
383
|
+
`// serverExternalPackages: ["@bison-lab/fonts"],`
|
|
384
|
+
].join("\n");
|
|
495
385
|
function copyToClipboard(text) {
|
|
496
386
|
try {
|
|
497
387
|
const platform = process.platform;
|
|
@@ -630,7 +520,7 @@ async function main() {
|
|
|
630
520
|
} else p.log.success("Bison Lab packages already installed.");
|
|
631
521
|
const s = p.spinner();
|
|
632
522
|
s.start("Generating theme files...");
|
|
633
|
-
const themeCSS = generateThemeCSS(config);
|
|
523
|
+
const themeCSS = generateThemeCSS(config, { fontsBaseUrl: "/fonts" });
|
|
634
524
|
const themePath = resolve(outDir, THEME_FILE);
|
|
635
525
|
writeFileSync(themePath, themeCSS, "utf-8");
|
|
636
526
|
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
@@ -663,7 +553,7 @@ async function main() {
|
|
|
663
553
|
}
|
|
664
554
|
const layoutPath = findLayoutFile(outDir);
|
|
665
555
|
const themeImportPath = layoutPath ? relative(dirname(layoutPath), themePath).replace(/\\/g, "/") : `./${THEME_FILE}`;
|
|
666
|
-
const importsSnippet = generateImports(
|
|
556
|
+
const importsSnippet = generateImports(themeImportPath.startsWith(".") ? themeImportPath : `./${themeImportPath}`);
|
|
667
557
|
if (layoutPath) if (injectImportsIntoLayout(layoutPath, importsSnippet)) {
|
|
668
558
|
const rel = relative(process.cwd(), layoutPath);
|
|
669
559
|
p.log.success(`${pc.green("Updated:")} ${rel} with Bison Lab imports.`);
|
|
@@ -683,6 +573,10 @@ async function main() {
|
|
|
683
573
|
if (!p.isCancel(action) && action === "copy") if (copyToClipboard(importsSnippet)) p.log.success("Copied CSS imports to clipboard!");
|
|
684
574
|
else p.log.warning("Could not access clipboard — copy manually from above.");
|
|
685
575
|
}
|
|
576
|
+
const routePath = resolve(outDir, "app/fonts/[...path]/route.ts");
|
|
577
|
+
const srcRoutePath = resolve(outDir, "src/app/fonts/[...path]/route.ts");
|
|
578
|
+
if (existsSync(routePath) || existsSync(srcRoutePath)) p.log.success("Font route already exists.");
|
|
579
|
+
else p.note(FONT_ROUTE_SNIPPET, "Serve the fonts: add this route");
|
|
686
580
|
p.outro(pc.green("Done! Your Bison Lab theme is ready."));
|
|
687
581
|
}
|
|
688
582
|
main().catch(console.error);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/preview.ts","../src/prompts.ts","../src/generate.ts","../src/index.ts"],"sourcesContent":["import pc from \"picocolors\";\n\nexport function hexToRgb(hex: string): [number, number, number] {\n hex = hex.replace(\"#\", \"\");\n return [\n parseInt(hex.substring(0, 2), 16),\n parseInt(hex.substring(2, 4), 16),\n parseInt(hex.substring(4, 6), 16),\n ];\n}\n\nexport function previewHexColor(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n // Use ANSI 24-bit color for background\n return `\\x1b[48;2;${r};${g};${b}m \\x1b[0m ${pc.dim(hex)}`;\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { previewHexColor } from \"./preview\";\n\nexport type GreyScale = \"slate\" | \"gray\" | \"zinc\" | \"neutral\" | \"stone\";\n\nexport interface ThemeConfig {\n brandPrimary: string;\n brandSecondary: string;\n brandAccent: string;\n brandHighlight: string;\n brandSuccess: string;\n greyScale: GreyScale;\n darkSelector: string;\n defaultTheme: \"light\" | \"dark\" | \"system\";\n radius: \"sharp\" | \"subtle\" | \"rounded\" | \"pill\";\n shadow: \"flat\" | \"subtle\" | \"elevated\";\n motion: \"snappy\" | \"smooth\" | \"minimal\";\n density: \"compact\" | \"default\" | \"spacious\";\n fontBody: string;\n fontHeading: string | null;\n fontWeights: {\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n };\n}\n\nfunction isValidHex(hex: string | undefined): boolean {\n return hex != null && /^#[0-9A-Fa-f]{6}$/.test(hex);\n}\n\nexport async function runPrompts(existing?: ThemeConfig): Promise<ThemeConfig | null> {\n // Brand colors\n p.log.info(pc.bold(\"Brand Colors\"));\n\n if (existing) {\n p.log.message(\n `Current: Primary ${previewHexColor(existing.brandPrimary)} Secondary ${previewHexColor(existing.brandSecondary)} Accent ${previewHexColor(existing.brandAccent)} Highlight ${previewHexColor(existing.brandHighlight)} Success ${previewHexColor(existing.brandSuccess)}`\n );\n }\n\n const brandPrimary = await p.text({\n message: \"Primary brand color (hex)\",\n placeholder: \"#1e3a5f\",\n ...(existing?.brandPrimary && { defaultValue: existing.brandPrimary }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #1e3a5f)\" : undefined),\n });\n if (p.isCancel(brandPrimary)) return null;\n\n p.log.message(` ${previewHexColor(brandPrimary as string)} Primary`);\n\n const brandSecondary = await p.text({\n message: \"Secondary brand color (hex)\",\n placeholder: \"#2d9d6e\",\n ...(existing?.brandSecondary && { defaultValue: existing.brandSecondary }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #2d9d6e)\" : undefined),\n });\n if (p.isCancel(brandSecondary)) return null;\n\n p.log.message(` ${previewHexColor(brandSecondary as string)} Secondary`);\n\n const brandAccent = await p.text({\n message: \"Accent color (hex)\",\n placeholder: \"#e89b20\",\n ...(existing?.brandAccent && { defaultValue: existing.brandAccent }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #e89b20)\" : undefined),\n });\n if (p.isCancel(brandAccent)) return null;\n\n p.log.message(` ${previewHexColor(brandAccent as string)} Accent`);\n\n const brandHighlight = await p.text({\n message: \"Highlight color (hex)\",\n placeholder: \"#7c3aed\",\n ...(existing?.brandHighlight && { defaultValue: existing.brandHighlight }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #7c3aed)\" : undefined),\n });\n if (p.isCancel(brandHighlight)) return null;\n\n p.log.message(` ${previewHexColor(brandHighlight as string)} Highlight`);\n\n const brandSuccess = await p.text({\n message: \"Success color (hex)\",\n placeholder: \"#22c55e\",\n ...(existing?.brandSuccess && { defaultValue: existing.brandSuccess }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #22c55e)\" : undefined),\n });\n if (p.isCancel(brandSuccess)) return null;\n\n p.log.message(` ${previewHexColor(brandSuccess as string)} Success`);\n\n // Grey scale\n p.log.info(pc.bold(\"Grey Scale\"));\n\n const greyScale = await p.select({\n message: \"Grey palette for borders, text, backgrounds\",\n initialValue: existing?.greyScale ?? \"slate\",\n options: [\n { value: \"slate\" as const, label: \"Slate\", hint: \"Cool blue-grey — modern, tech-forward\" },\n { value: \"gray\" as const, label: \"Gray\", hint: \"Balanced blue-grey — neutral default\" },\n { value: \"zinc\" as const, label: \"Zinc\", hint: \"Cool desaturated — minimal, sharp\" },\n { value: \"neutral\" as const, label: \"Neutral\", hint: \"Pure grey — zero hue bias\" },\n { value: \"stone\" as const, label: \"Stone\", hint: \"Warm earthy grey — organic, approachable\" },\n ],\n });\n if (p.isCancel(greyScale)) return null;\n\n // Dark mode selector\n const darkSelector = await p.select({\n message: \"Dark mode CSS selector\",\n initialValue: existing?.darkSelector ?? '[data-theme=\"dark\"]',\n options: [\n { value: '[data-theme=\"dark\"]' as const, label: '[data-theme=\"dark\"]', hint: \"Attribute selector — works with class & attribute strategies (recommended)\" },\n { value: \".dark\" as const, label: \".dark\", hint: \"Class selector — Tailwind default\" },\n { value: \"@media\" as const, label: \"@media (prefers-color-scheme: dark)\", hint: \"System preference — no JS needed\" },\n ],\n });\n if (p.isCancel(darkSelector)) return null;\n\n // Default theme\n const defaultTheme = await p.select({\n message: \"Default theme mode\",\n initialValue: existing?.defaultTheme ?? \"system\",\n options: [\n { value: \"system\" as const, label: \"System\", hint: \"Follow OS preference (recommended)\" },\n { value: \"light\" as const, label: \"Light\", hint: \"Always start in light mode\" },\n { value: \"dark\" as const, label: \"Dark\", hint: \"Always start in dark mode\" },\n ],\n });\n if (p.isCancel(defaultTheme)) return null;\n\n // Radius\n const radius = await p.select({\n message: \"Border radius preset\",\n initialValue: existing?.radius ?? \"rounded\",\n options: [\n { value: \"sharp\" as const, label: \"Sharp\", hint: \"0px — square corners\" },\n { value: \"subtle\" as const, label: \"Subtle\", hint: \"6px — barely rounded\" },\n { value: \"rounded\" as const, label: \"Rounded\", hint: \"8px — balanced (default)\" },\n { value: \"pill\" as const, label: \"Pill\", hint: \"12px — soft, bubbly\" },\n ],\n });\n if (p.isCancel(radius)) return null;\n\n // Shadow\n const shadow = await p.select({\n message: \"Shadow preset\",\n initialValue: existing?.shadow ?? \"subtle\",\n options: [\n { value: \"flat\" as const, label: \"Flat\", hint: \"No shadows — clean, modern\" },\n { value: \"subtle\" as const, label: \"Subtle\", hint: \"Soft low-opacity shadows (default)\" },\n { value: \"elevated\" as const, label: \"Elevated\", hint: \"Prominent layered shadows\" },\n ],\n });\n if (p.isCancel(shadow)) return null;\n\n // Motion\n const motion = await p.select({\n message: \"Motion preset\",\n initialValue: existing?.motion ?? \"smooth\",\n options: [\n { value: \"snappy\" as const, label: \"Snappy\", hint: \"Fast, spring-like (150ms)\" },\n { value: \"smooth\" as const, label: \"Smooth\", hint: \"Balanced ease-out (200ms, default)\" },\n { value: \"minimal\" as const, label: \"Minimal\", hint: \"Barely-there, linear (100ms)\" },\n ],\n });\n if (p.isCancel(motion)) return null;\n\n // Density\n const density = await p.select({\n message: \"Component density\",\n initialValue: existing?.density ?? \"default\",\n options: [\n { value: \"compact\" as const, label: \"Compact\", hint: \"Tight padding, smaller components\" },\n { value: \"default\" as const, label: \"Default\", hint: \"Balanced spacing\" },\n { value: \"spacious\" as const, label: \"Spacious\", hint: \"Generous padding, larger components\" },\n ],\n });\n if (p.isCancel(density)) return null;\n\n // Font\n p.log.info(pc.bold(\"Typography\"));\n\n const fontBody = await p.text({\n message: \"Body font family\",\n placeholder: \"Inter\",\n defaultValue: existing?.fontBody ?? \"Inter\",\n });\n if (p.isCancel(fontBody)) return null;\n\n const wantsHeading = await p.confirm({\n message: \"Use a separate display/heading font?\",\n initialValue: existing?.fontHeading != null,\n });\n if (p.isCancel(wantsHeading)) return null;\n\n let fontHeading: string | null = null;\n if (wantsHeading) {\n const heading = await p.text({\n message: \"Heading font family\",\n placeholder: \"Playfair Display\",\n ...(existing?.fontHeading && { defaultValue: existing.fontHeading }),\n });\n if (p.isCancel(heading)) return null;\n fontHeading = heading as string;\n }\n\n // Font weights\n const customizeWeights = await p.confirm({\n message: \"Customize font weights? (default: 400/500/600/700)\",\n initialValue: false,\n });\n if (p.isCancel(customizeWeights)) return null;\n\n let fontWeights = existing?.fontWeights ?? { normal: 400, medium: 500, semibold: 600, bold: 700 };\n\n if (customizeWeights) {\n const normal = await p.text({\n message: \"Normal weight\",\n defaultValue: String(fontWeights.normal),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(normal)) return null;\n\n const medium = await p.text({\n message: \"Medium weight\",\n defaultValue: String(fontWeights.medium),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(medium)) return null;\n\n const semibold = await p.text({\n message: \"Semibold weight\",\n defaultValue: String(fontWeights.semibold),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(semibold)) return null;\n\n const bold = await p.text({\n message: \"Bold weight\",\n defaultValue: String(fontWeights.bold),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(bold)) return null;\n\n fontWeights = {\n normal: Number(normal),\n medium: Number(medium),\n semibold: Number(semibold),\n bold: Number(bold),\n };\n }\n\n return {\n brandPrimary: brandPrimary as string,\n brandSecondary: brandSecondary as string,\n brandAccent: brandAccent as string,\n brandHighlight: brandHighlight as string,\n brandSuccess: brandSuccess as string,\n greyScale: greyScale as GreyScale,\n darkSelector: darkSelector as string,\n defaultTheme: defaultTheme as ThemeConfig[\"defaultTheme\"],\n radius: radius as ThemeConfig[\"radius\"],\n shadow: shadow as ThemeConfig[\"shadow\"],\n motion: motion as ThemeConfig[\"motion\"],\n density: density as ThemeConfig[\"density\"],\n fontBody: fontBody as string,\n fontHeading,\n fontWeights,\n };\n}\n","import type { ThemeConfig } from \"./prompts\";\nimport {\n hexToHSL,\n hslToString,\n GREY_SCALES,\n generateBrandScales,\n generateScaleCSS,\n generateDestructiveScaleCSS,\n type GreyScale,\n} from \"@bison-lab/tokens\";\n\n// --- Local HSL utilities (not exported from tokens) ---\n\nfunction clamp(v: number, min: number, max: number): number {\n return Math.min(Math.max(v, min), max);\n}\n\nfunction contrastForeground(color: { h: number; s: number; l: number }): string {\n return color.l > 55\n ? hslToString({ h: color.h, s: clamp(color.s - 20, 0, 100), l: 10 })\n : hslToString({ h: color.h, s: clamp(color.s - 25, 0, 100), l: 98 });\n}\n\nfunction boostForDark(color: { h: number; s: number; l: number }): { h: number; s: number; l: number } {\n if (color.l < 40) {\n return { ...color, l: clamp(color.l + 25, 0, 100) };\n }\n return color;\n}\n\n// --- Palette derivation ---\n\ntype GreyShade = \"50\" | \"100\" | \"200\" | \"300\" | \"400\" | \"500\" | \"600\" | \"700\" | \"800\" | \"900\" | \"950\";\n\nfunction deriveLight(\n primary: { h: number; s: number; l: number },\n secondary: { h: number; s: number; l: number },\n accent: { h: number; s: number; l: number },\n highlight: { h: number; s: number; l: number },\n success: { h: number; s: number; l: number },\n grey: Record<GreyShade, string>,\n): Record<string, string> {\n return {\n background: grey[\"50\"],\n foreground: grey[\"950\"],\n card: \"0 0% 100%\",\n \"card-foreground\": grey[\"950\"],\n \"surface-tertiary\": grey[\"100\"],\n popover: \"0 0% 100%\",\n \"popover-foreground\": grey[\"950\"],\n primary: hslToString(primary),\n \"primary-foreground\": contrastForeground(primary),\n secondary: hslToString(secondary),\n \"secondary-foreground\": contrastForeground(secondary),\n accent: grey[\"100\"],\n \"accent-foreground\": grey[\"950\"],\n \"brand-accent\": hslToString(accent),\n \"brand-accent-foreground\": contrastForeground(accent),\n highlight: hslToString(highlight),\n \"highlight-foreground\": contrastForeground(highlight),\n success: hslToString(success),\n \"success-foreground\": contrastForeground(success),\n muted: grey[\"100\"],\n \"muted-foreground\": grey[\"500\"],\n \"content-secondary\": grey[\"400\"],\n destructive: \"0 84% 60%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"200\"],\n \"border-strong\": grey[\"300\"],\n \"border-subtle\": grey[\"100\"],\n input: grey[\"200\"],\n ring: hslToString(primary),\n };\n}\n\nfunction deriveDark(\n primary: { h: number; s: number; l: number },\n secondary: { h: number; s: number; l: number },\n accent: { h: number; s: number; l: number },\n highlight: { h: number; s: number; l: number },\n success: { h: number; s: number; l: number },\n grey: Record<GreyShade, string>,\n): Record<string, string> {\n const dp = boostForDark(primary);\n const ds = boostForDark(secondary);\n const da = boostForDark(accent);\n const dh = boostForDark(highlight);\n const dsu = boostForDark(success);\n\n return {\n background: grey[\"950\"],\n foreground: grey[\"50\"],\n card: grey[\"900\"],\n \"card-foreground\": grey[\"50\"],\n \"surface-tertiary\": grey[\"800\"],\n popover: grey[\"900\"],\n \"popover-foreground\": grey[\"50\"],\n primary: hslToString(dp),\n \"primary-foreground\": contrastForeground(dp),\n secondary: hslToString(ds),\n \"secondary-foreground\": contrastForeground(ds),\n accent: grey[\"800\"],\n \"accent-foreground\": grey[\"50\"],\n \"brand-accent\": hslToString(da),\n \"brand-accent-foreground\": contrastForeground(da),\n highlight: hslToString(dh),\n \"highlight-foreground\": contrastForeground(dh),\n success: hslToString(dsu),\n \"success-foreground\": contrastForeground(dsu),\n muted: grey[\"800\"],\n \"muted-foreground\": grey[\"400\"],\n \"content-secondary\": grey[\"500\"],\n destructive: \"0 62% 30%\",\n \"destructive-foreground\": \"0 0% 98%\",\n border: grey[\"800\"],\n \"border-strong\": grey[\"700\"],\n \"border-subtle\": grey[\"900\"],\n input: grey[\"800\"],\n ring: hslToString(dp),\n };\n}\n\n// --- Public generators ---\n\nexport function generateThemeCSS(config: ThemeConfig): string {\n const primary = hexToHSL(config.brandPrimary);\n const secondary = hexToHSL(config.brandSecondary);\n const accent = hexToHSL(config.brandAccent);\n const highlight = hexToHSL(config.brandHighlight);\n const success = hexToHSL(config.brandSuccess);\n const grey = GREY_SCALES[config.greyScale as GreyScale];\n\n const light = deriveLight(primary, secondary, accent, highlight, success, grey);\n const dark = deriveDark(primary, secondary, accent, highlight, success, grey);\n\n const scales = generateBrandScales({\n primary: config.brandPrimary,\n secondary: config.brandSecondary,\n accent: config.brandAccent,\n highlight: config.brandHighlight,\n success: config.brandSuccess,\n });\n\n const lines: string[] = [\n `/* Bison Lab Theme — Generated by @bison-lab/create-theme */`,\n `/* Brand: ${config.brandPrimary} / ${config.brandSecondary} / ${config.brandAccent} / ${config.brandHighlight} / ${config.brandSuccess} */`,\n `/* Grey: ${config.greyScale} */`,\n ``,\n `:root {`,\n ...Object.entries(light).map(([k, v]) => ` --${k}: ${v};`),\n ``,\n ` /* Brand color scales (50–950) */`,\n generateScaleCSS(scales),\n ``,\n ` /* Destructive scale (50–950) — soft danger surfaces */`,\n generateDestructiveScaleCSS(),\n ``,\n ` /* Typography */`,\n ` --font-body: '${config.fontBody}', ui-sans-serif, system-ui, sans-serif;`,\n ` --font-heading: '${config.fontHeading ?? config.fontBody}', ui-sans-serif, system-ui, sans-serif;`,\n ` --font-weight-normal: ${config.fontWeights.normal};`,\n ` --font-weight-medium: ${config.fontWeights.medium};`,\n ` --font-weight-semibold: ${config.fontWeights.semibold};`,\n ` --font-weight-bold: ${config.fontWeights.bold};`,\n ` --font-weight-extrabold: 800;`,\n `}`,\n ``,\n ...(config.darkSelector === \"@media\"\n ? [\n `@media (prefers-color-scheme: dark) {`,\n ` :root {`,\n ...Object.entries(dark).map(([k, v]) => ` --${k}: ${v};`),\n ` }`,\n `}`,\n ]\n : [\n `${config.darkSelector} {`,\n ...Object.entries(dark).map(([k, v]) => ` --${k}: ${v};`),\n `}`,\n ]),\n ``,\n ];\n\n return lines.join(\"\\n\");\n}\n\nexport function generateTailwindConfig(): string {\n return [\n `/* Add to your main CSS file (e.g. globals.css): */`,\n `/* @import \"tailwindcss\"; */`,\n `/* @import \"@bison-lab/tailwind-preset/css\"; */`,\n `/* @import \"./bison-theme.css\"; */`,\n ].join(\"\\n\");\n}\n\nexport function generateImports(config: ThemeConfig, themeImportPath: string): string {\n return [\n `import '@bison-lab/tokens/css/base.css';`,\n `import '@bison-lab/tokens/css/themes/radius-${config.radius}.css';`,\n `import '@bison-lab/tokens/css/themes/shadow-${config.shadow}.css';`,\n `import '@bison-lab/tokens/css/themes/motion-${config.motion}.css';`,\n `import '@bison-lab/tokens/css/themes/density-${config.density}.css';`,\n `import '${themeImportPath}';`,\n ].join(\"\\n\");\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execSync } from \"child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { resolve, join, relative, dirname } from \"path\";\nimport { runPrompts, type ThemeConfig } from \"./prompts\";\nimport { generateThemeCSS, generateTailwindConfig, generateImports } from \"./generate\";\n\nconst BISON_PACKAGES = [\n \"@bison-lab/tokens\",\n \"@bison-lab/ui\",\n \"@bison-lab/tailwind-preset\",\n];\n\nfunction copyToClipboard(text: string): boolean {\n try {\n const platform = process.platform;\n if (platform === \"darwin\") {\n execSync(\"pbcopy\", { input: text });\n } else if (platform === \"linux\") {\n execSync(\"xclip -selection clipboard\", { input: text });\n } else if (platform === \"win32\") {\n execSync(\"clip\", { input: text });\n } else {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\nfunction detectPackageManager(): \"pnpm\" | \"npm\" | \"yarn\" | \"bun\" {\n const cwd = process.cwd();\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\"))) return \"bun\";\n if (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n return \"npm\";\n}\n\nfunction installCommand(pm: \"pnpm\" | \"npm\" | \"yarn\" | \"bun\"): string {\n const pkgs = BISON_PACKAGES.join(\" \");\n switch (pm) {\n case \"pnpm\": return `pnpm add ${pkgs}`;\n case \"yarn\": return `yarn add ${pkgs}`;\n case \"bun\": return `bun add ${pkgs}`;\n default: return `npm install ${pkgs}`;\n }\n}\n\nfunction areBisonPackagesInstalled(): boolean {\n return BISON_PACKAGES.every((pkg) => {\n try {\n const pkgJsonPath = join(process.cwd(), \"node_modules\", pkg, \"package.json\");\n return existsSync(pkgJsonPath);\n } catch {\n return false;\n }\n });\n}\n\nfunction findLayoutFile(baseDir: string): string | null {\n const candidates = [\n \"app/layout.tsx\",\n \"app/layout.jsx\",\n \"src/app/layout.tsx\",\n \"src/app/layout.jsx\",\n ];\n for (const candidate of candidates) {\n const full = resolve(baseDir, candidate);\n if (existsSync(full)) return full;\n }\n return null;\n}\n\nfunction injectImportsIntoLayout(layoutPath: string, imports: string): boolean {\n const content = readFileSync(layoutPath, \"utf-8\");\n\n // Check if already injected\n if (content.includes(\"@bison-lab/tokens/css/base.css\") || content.includes(\"@bison-lab/tokens/css/globals.css\")) {\n return false;\n }\n\n // Match all import statements including multiline ones (e.g. import { \\n Foo,\\n } from \"bar\";)\n const importRegex = /^import\\s[\\s\\S]*?from\\s+['\"][^'\"]+['\"];?\\s*$/gm;\n let lastMatchEnd = -1;\n let match: RegExpExecArray | null;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastMatchEnd = match.index + match[0].length;\n }\n\n if (lastMatchEnd === -1) {\n // No imports found, prepend to file\n writeFileSync(layoutPath, imports + \"\\n\\n\" + content, \"utf-8\");\n } else {\n // Insert after the last import statement\n const before = content.slice(0, lastMatchEnd);\n const after = content.slice(lastMatchEnd);\n writeFileSync(layoutPath, before + \"\\n\\n\" + imports + after, \"utf-8\");\n }\n\n return true;\n}\n\nconst CONFIG_FILE = \"bison.config.json\";\nconst THEME_FILE = \"bison-theme.css\";\n\nasync function main() {\n p.intro(pc.bgCyan(pc.black(\" Bison Lab Theme Generator \")));\n\n // --- Output directory ---\n const outputDir = await p.text({\n message: \"Output directory for generated files\",\n placeholder: \".\",\n defaultValue: \".\",\n validate: (v) => {\n if (!v) return undefined;\n const resolved = resolve(process.cwd(), v);\n if (!existsSync(resolved)) return `Directory does not exist: ${v}`;\n return undefined;\n },\n });\n\n if (p.isCancel(outputDir)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n const outDir = resolve(process.cwd(), outputDir as string);\n\n if (outDir !== process.cwd()) {\n p.log.info(`Output directory: ${pc.cyan(relative(process.cwd(), outDir) || \".\")}`);\n }\n\n const configPath = resolve(outDir, CONFIG_FILE);\n let existingConfig: ThemeConfig | undefined;\n\n if (existsSync(configPath)) {\n const raw = JSON.parse(readFileSync(configPath, \"utf-8\")) as ThemeConfig;\n existingConfig = raw;\n\n const mode = await p.select({\n message: \"An existing theme was found. What would you like to do?\",\n options: [\n { value: \"update\", label: \"Update existing theme\", hint: \"Modify individual properties\" },\n { value: \"fresh\", label: \"Start fresh\", hint: \"Overwrite everything\" },\n ],\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n if (mode === \"fresh\") {\n existingConfig = undefined;\n }\n }\n\n const config = await runPrompts(existingConfig);\n\n if (!config) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n // --- Install dependencies ---\n if (!areBisonPackagesInstalled()) {\n const pm = detectPackageManager();\n const cmd = installCommand(pm);\n\n const shouldInstall = await p.confirm({\n message: `Install Bison Lab packages? (${pc.dim(cmd)})`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldInstall)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n if (shouldInstall) {\n const s = p.spinner();\n s.start(`Installing packages with ${pm}...`);\n try {\n execSync(cmd, { cwd: process.cwd(), stdio: \"pipe\" });\n s.stop(\"Packages installed!\");\n } catch (err) {\n s.stop(\"Package installation failed.\");\n p.log.warning(`Run manually: ${pc.cyan(cmd)}`);\n }\n } else {\n p.log.warning(`Skipped. Run manually: ${pc.cyan(installCommand(pm))}`);\n }\n } else {\n p.log.success(\"Bison Lab packages already installed.\");\n }\n\n // --- Generate theme files ---\n const s = p.spinner();\n s.start(\"Generating theme files...\");\n\n const themeCSS = generateThemeCSS(config);\n const themePath = resolve(outDir, THEME_FILE);\n writeFileSync(themePath, themeCSS, \"utf-8\");\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n s.stop(\"Theme files generated!\");\n\n const outPrefix = outDir === process.cwd() ? \"\" : relative(process.cwd(), outDir) + \"/\";\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}${THEME_FILE}`);\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}${CONFIG_FILE}`);\n\n // --- Tailwind config guidance ---\n const tailwindPath = resolve(outDir, \"tailwind.config.ts\");\n const presetSnippet = `import bisonPreset from '@bison-lab/tailwind-preset';\\n\\n// Add to your Tailwind config:\\n// presets: [bisonPreset],\\n// content: [..., './node_modules/@bison-lab/ui/dist/**/*.js'],`;\n\n if (existsSync(tailwindPath)) {\n const existing = readFileSync(tailwindPath, \"utf-8\");\n if (existing.includes(\"@bison-lab/tailwind-preset\")) {\n p.log.success(\"tailwind.config.ts already includes Bison Lab preset.\");\n } else {\n p.note(presetSnippet, \"Add to your tailwind.config.ts\");\n\n const action = await p.select({\n message: \"Add the Bison Lab preset to your existing tailwind.config.ts manually:\",\n options: [\n { value: \"copy\", label: \"Copy snippet to clipboard\" },\n { value: \"skip\", label: \"Skip\", hint: \"I'll handle it\" },\n ],\n });\n\n if (!p.isCancel(action) && action === \"copy\") {\n if (copyToClipboard(presetSnippet)) {\n p.log.success(\"Copied Tailwind preset snippet to clipboard!\");\n } else {\n p.log.warning(\"Could not access clipboard — copy manually from above.\");\n }\n }\n }\n } else {\n // No config exists — safe to create one\n const tailwindConfig = generateTailwindConfig();\n writeFileSync(tailwindPath, tailwindConfig, \"utf-8\");\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}tailwind.config.ts`);\n }\n\n // --- Layout imports ---\n const layoutPath = findLayoutFile(outDir);\n\n // Compute relative path from layout directory to the theme file\n const themeImportPath = layoutPath\n ? relative(dirname(layoutPath), themePath).replace(/\\\\/g, \"/\")\n : `./${THEME_FILE}`;\n const importsSnippet = generateImports(config, themeImportPath.startsWith(\".\") ? themeImportPath : `./${themeImportPath}`);\n\n if (layoutPath) {\n const injected = injectImportsIntoLayout(layoutPath, importsSnippet);\n if (injected) {\n const rel = relative(process.cwd(), layoutPath);\n p.log.success(`${pc.green(\"Updated:\")} ${rel} with Bison Lab imports.`);\n } else {\n p.log.success(\"Layout file already includes Bison Lab imports.\");\n }\n } else {\n p.note(importsSnippet, \"app/layout.tsx imports\");\n\n const action = await p.select({\n message: \"No layout file found. Copy imports to clipboard?\",\n options: [\n { value: \"copy\", label: \"Copy to clipboard\" },\n { value: \"skip\", label: \"Skip\" },\n ],\n });\n\n if (!p.isCancel(action) && action === \"copy\") {\n if (copyToClipboard(importsSnippet)) {\n p.log.success(\"Copied CSS imports to clipboard!\");\n } else {\n p.log.warning(\"Could not access clipboard — copy manually from above.\");\n }\n }\n }\n\n p.outro(pc.green(\"Done! Your Bison Lab theme is ready.\"));\n}\n\nmain().catch(console.error);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/preview.ts","../src/prompts.ts","../src/generate.ts","../src/index.ts"],"sourcesContent":["import pc from \"picocolors\";\n\nexport function hexToRgb(hex: string): [number, number, number] {\n hex = hex.replace(\"#\", \"\");\n return [\n parseInt(hex.substring(0, 2), 16),\n parseInt(hex.substring(2, 4), 16),\n parseInt(hex.substring(4, 6), 16),\n ];\n}\n\nexport function previewHexColor(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n // Use ANSI 24-bit color for background\n return `\\x1b[48;2;${r};${g};${b}m \\x1b[0m ${pc.dim(hex)}`;\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { isThemeHex, type GreyScale, type ThemeConfig } from \"@bison-lab/tokens\";\nimport { catalog, findFontByFamily, isFontId, type FontId } from \"@bison-lab/fonts\";\nimport { previewHexColor } from \"./preview\";\n\n/** The `bison.config.json` shape. Lives in `@bison-lab/tokens` so the derivation and the CLI share it. */\nexport type { ThemeConfig, GreyScale };\n\n/** The same rule `buildThemeCss` enforces, so the CLI never writes a config the derivation refuses. */\nconst isValidHex = isThemeHex;\n\n/**\n * The catalogue id to preselect for a stored value: the id itself, the id\n * of a legacy family name (a config written before the catalogue), else\n * the fallback.\n */\nfunction catalogueId(stored: string | null | undefined, fallback: FontId): FontId {\n if (!stored) return fallback;\n if (isFontId(stored)) return stored;\n return findFontByFamily(stored)?.id ?? fallback;\n}\n\nexport async function runPrompts(existing?: ThemeConfig): Promise<ThemeConfig | null> {\n // Brand colors\n p.log.info(pc.bold(\"Brand Colors\"));\n\n if (existing) {\n p.log.message(\n `Current: Primary ${previewHexColor(existing.brandPrimary)} Secondary ${previewHexColor(existing.brandSecondary)} Accent ${previewHexColor(existing.brandAccent)} Highlight ${previewHexColor(existing.brandHighlight)} Success ${previewHexColor(existing.brandSuccess)}`\n );\n }\n\n const brandPrimary = await p.text({\n message: \"Primary brand color (hex)\",\n placeholder: \"#1e3a5f\",\n ...(existing?.brandPrimary && { defaultValue: existing.brandPrimary }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #1e3a5f)\" : undefined),\n });\n if (p.isCancel(brandPrimary)) return null;\n\n p.log.message(` ${previewHexColor(brandPrimary as string)} Primary`);\n\n const brandSecondary = await p.text({\n message: \"Secondary brand color (hex)\",\n placeholder: \"#2d9d6e\",\n ...(existing?.brandSecondary && { defaultValue: existing.brandSecondary }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #2d9d6e)\" : undefined),\n });\n if (p.isCancel(brandSecondary)) return null;\n\n p.log.message(` ${previewHexColor(brandSecondary as string)} Secondary`);\n\n const brandAccent = await p.text({\n message: \"Accent color (hex)\",\n placeholder: \"#e89b20\",\n ...(existing?.brandAccent && { defaultValue: existing.brandAccent }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #e89b20)\" : undefined),\n });\n if (p.isCancel(brandAccent)) return null;\n\n p.log.message(` ${previewHexColor(brandAccent as string)} Accent`);\n\n const brandHighlight = await p.text({\n message: \"Highlight color (hex)\",\n placeholder: \"#7c3aed\",\n ...(existing?.brandHighlight && { defaultValue: existing.brandHighlight }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #7c3aed)\" : undefined),\n });\n if (p.isCancel(brandHighlight)) return null;\n\n p.log.message(` ${previewHexColor(brandHighlight as string)} Highlight`);\n\n const brandSuccess = await p.text({\n message: \"Success color (hex)\",\n placeholder: \"#22c55e\",\n ...(existing?.brandSuccess && { defaultValue: existing.brandSuccess }),\n validate: (v) => (!isValidHex(v) ? \"Enter a valid hex color (e.g. #22c55e)\" : undefined),\n });\n if (p.isCancel(brandSuccess)) return null;\n\n p.log.message(` ${previewHexColor(brandSuccess as string)} Success`);\n\n // Grey scale\n p.log.info(pc.bold(\"Grey Scale\"));\n\n const greyScale = await p.select({\n message: \"Grey palette for borders, text, backgrounds\",\n initialValue: existing?.greyScale ?? \"slate\",\n options: [\n { value: \"slate\" as const, label: \"Slate\", hint: \"Cool blue-grey — modern, tech-forward\" },\n { value: \"gray\" as const, label: \"Gray\", hint: \"Balanced blue-grey — neutral default\" },\n { value: \"zinc\" as const, label: \"Zinc\", hint: \"Cool desaturated — minimal, sharp\" },\n { value: \"neutral\" as const, label: \"Neutral\", hint: \"Pure grey — zero hue bias\" },\n { value: \"stone\" as const, label: \"Stone\", hint: \"Warm earthy grey — organic, approachable\" },\n ],\n });\n if (p.isCancel(greyScale)) return null;\n\n // Dark mode selector\n const darkSelector = await p.select({\n message: \"Dark mode CSS selector\",\n initialValue: existing?.darkSelector ?? '[data-theme=\"dark\"]',\n options: [\n { value: '[data-theme=\"dark\"]' as const, label: '[data-theme=\"dark\"]', hint: \"Attribute selector — works with class & attribute strategies (recommended)\" },\n { value: \".dark\" as const, label: \".dark\", hint: \"Class selector — Tailwind default\" },\n { value: \"@media\" as const, label: \"@media (prefers-color-scheme: dark)\", hint: \"System preference — no JS needed\" },\n ],\n });\n if (p.isCancel(darkSelector)) return null;\n\n // Default theme\n const defaultTheme = await p.select({\n message: \"Default theme mode\",\n initialValue: existing?.defaultTheme ?? \"system\",\n options: [\n { value: \"system\" as const, label: \"System\", hint: \"Follow OS preference (recommended)\" },\n { value: \"light\" as const, label: \"Light\", hint: \"Always start in light mode\" },\n { value: \"dark\" as const, label: \"Dark\", hint: \"Always start in dark mode\" },\n ],\n });\n if (p.isCancel(defaultTheme)) return null;\n\n // Radius\n const radius = await p.select({\n message: \"Border radius preset\",\n initialValue: existing?.radius ?? \"rounded\",\n options: [\n { value: \"sharp\" as const, label: \"Sharp\", hint: \"0px — square corners\" },\n { value: \"subtle\" as const, label: \"Subtle\", hint: \"6px — barely rounded\" },\n { value: \"rounded\" as const, label: \"Rounded\", hint: \"8px — balanced (default)\" },\n { value: \"pill\" as const, label: \"Pill\", hint: \"12px — soft, bubbly\" },\n ],\n });\n if (p.isCancel(radius)) return null;\n\n // Shadow\n const shadow = await p.select({\n message: \"Shadow preset\",\n initialValue: existing?.shadow ?? \"subtle\",\n options: [\n { value: \"flat\" as const, label: \"Flat\", hint: \"No shadows — clean, modern\" },\n { value: \"subtle\" as const, label: \"Subtle\", hint: \"Soft low-opacity shadows (default)\" },\n { value: \"elevated\" as const, label: \"Elevated\", hint: \"Prominent layered shadows\" },\n ],\n });\n if (p.isCancel(shadow)) return null;\n\n // Motion\n const motion = await p.select({\n message: \"Motion preset\",\n initialValue: existing?.motion ?? \"smooth\",\n options: [\n { value: \"snappy\" as const, label: \"Snappy\", hint: \"Fast, spring-like (150ms)\" },\n { value: \"smooth\" as const, label: \"Smooth\", hint: \"Balanced ease-out (200ms, default)\" },\n { value: \"minimal\" as const, label: \"Minimal\", hint: \"Barely-there, linear (100ms)\" },\n ],\n });\n if (p.isCancel(motion)) return null;\n\n // Density\n const density = await p.select({\n message: \"Component density\",\n initialValue: existing?.density ?? \"default\",\n options: [\n { value: \"compact\" as const, label: \"Compact\", hint: \"Tight padding, smaller components\" },\n { value: \"default\" as const, label: \"Default\", hint: \"Balanced spacing\" },\n { value: \"spacious\" as const, label: \"Spacious\", hint: \"Generous padding, larger components\" },\n ],\n });\n if (p.isCancel(density)) return null;\n\n // Font\n p.log.info(pc.bold(\"Typography\"));\n\n const fontOptions = catalog.map((font) => ({ value: font.id, label: font.family, hint: font.hint }));\n const fontBody = await p.select({\n message: \"Body font\",\n initialValue: catalogueId(existing?.fontBody, \"inter\"),\n options: fontOptions,\n });\n if (p.isCancel(fontBody)) return null;\n\n const wantsHeading = await p.confirm({\n message: \"Use a separate display/heading font?\",\n initialValue: existing?.fontHeading != null,\n });\n if (p.isCancel(wantsHeading)) return null;\n\n let fontHeading: FontId | null = null;\n if (wantsHeading) {\n const heading = await p.select({\n message: \"Heading font\",\n initialValue: catalogueId(existing?.fontHeading, \"playfair-display\"),\n options: fontOptions,\n });\n if (p.isCancel(heading)) return null;\n fontHeading = heading as FontId;\n }\n\n // Font weights\n const customizeWeights = await p.confirm({\n message: \"Customize font weights? (default: 400/500/600/700)\",\n initialValue: false,\n });\n if (p.isCancel(customizeWeights)) return null;\n\n let fontWeights = existing?.fontWeights ?? { normal: 400, medium: 500, semibold: 600, bold: 700 };\n\n if (customizeWeights) {\n const normal = await p.text({\n message: \"Normal weight\",\n defaultValue: String(fontWeights.normal),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(normal)) return null;\n\n const medium = await p.text({\n message: \"Medium weight\",\n defaultValue: String(fontWeights.medium),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(medium)) return null;\n\n const semibold = await p.text({\n message: \"Semibold weight\",\n defaultValue: String(fontWeights.semibold),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(semibold)) return null;\n\n const bold = await p.text({\n message: \"Bold weight\",\n defaultValue: String(fontWeights.bold),\n validate: (v) => (isNaN(Number(v)) ? \"Must be a number\" : undefined),\n });\n if (p.isCancel(bold)) return null;\n\n fontWeights = {\n normal: Number(normal),\n medium: Number(medium),\n semibold: Number(semibold),\n bold: Number(bold),\n };\n }\n\n return {\n brandPrimary: brandPrimary as string,\n brandSecondary: brandSecondary as string,\n brandAccent: brandAccent as string,\n brandHighlight: brandHighlight as string,\n brandSuccess: brandSuccess as string,\n greyScale: greyScale as GreyScale,\n darkSelector: darkSelector as string,\n defaultTheme: defaultTheme as ThemeConfig[\"defaultTheme\"],\n radius: radius as ThemeConfig[\"radius\"],\n shadow: shadow as ThemeConfig[\"shadow\"],\n motion: motion as ThemeConfig[\"motion\"],\n density: density as ThemeConfig[\"density\"],\n fontBody: fontBody as FontId,\n fontHeading,\n fontWeights,\n };\n}\n","import { buildThemeCss, type BuildThemeCssOptions, type ThemeConfig } from \"@bison-lab/tokens\";\n\n/**\n * `bison-theme.css` for a config. The derivation lives in `@bison-lab/tokens`\n * (`buildThemeCss`) so this file, `BisonProvider` and a CMS theme rendered at\n * request time all agree; the CLI only writes the result to disk.\n */\nexport function generateThemeCSS(config: ThemeConfig, options?: BuildThemeCssOptions): string {\n return buildThemeCss(config, options);\n}\n\nexport function generateTailwindConfig(): string {\n return [\n `/* Add to your main CSS file (e.g. globals.css): */`,\n `/* @import \"tailwindcss\"; */`,\n `/* @import \"@bison-lab/tailwind-preset/css\"; */`,\n `/* @import \"./bison-theme.css\"; */`,\n ].join(\"\\n\");\n}\n\n/**\n * The layout imports. The theme CSS carries the radius, shadow, motion and\n * density variables itself, so the four preset files are no longer imported;\n * they stay published for consumers composing a theme by hand.\n */\nexport function generateImports(themeImportPath: string): string {\n return [\n `import '@bison-lab/tokens/css/base.css';`,\n `import '${themeImportPath}';`,\n ].join(\"\\n\");\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { execSync } from \"child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { resolve, join, relative, dirname } from \"path\";\nimport { runPrompts, type ThemeConfig } from \"./prompts\";\nimport { generateThemeCSS, generateTailwindConfig, generateImports } from \"./generate\";\n\nconst BISON_PACKAGES = [\n \"@bison-lab/tokens\",\n \"@bison-lab/ui\",\n \"@bison-lab/tailwind-preset\",\n \"@bison-lab/fonts\",\n];\n\n/**\n * The theme CSS carries the `@font-face` rules for the chosen families under\n * `/fonts`; this is the route that answers them, and the config line that\n * keeps the package's font files reachable from the route.\n */\nconst FONT_ROUTE_SNIPPET = [\n `// app/fonts/[...path]/route.ts`,\n `import { serveFont } from \"@bison-lab/fonts/server\";`,\n `export const GET = serveFont;`,\n `export const HEAD = serveFont;`,\n ``,\n `// next.config.ts`,\n `// serverExternalPackages: [\"@bison-lab/fonts\"],`,\n].join(\"\\n\");\n\nfunction copyToClipboard(text: string): boolean {\n try {\n const platform = process.platform;\n if (platform === \"darwin\") {\n execSync(\"pbcopy\", { input: text });\n } else if (platform === \"linux\") {\n execSync(\"xclip -selection clipboard\", { input: text });\n } else if (platform === \"win32\") {\n execSync(\"clip\", { input: text });\n } else {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\nfunction detectPackageManager(): \"pnpm\" | \"npm\" | \"yarn\" | \"bun\" {\n const cwd = process.cwd();\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\"))) return \"bun\";\n if (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n return \"npm\";\n}\n\nfunction installCommand(pm: \"pnpm\" | \"npm\" | \"yarn\" | \"bun\"): string {\n const pkgs = BISON_PACKAGES.join(\" \");\n switch (pm) {\n case \"pnpm\": return `pnpm add ${pkgs}`;\n case \"yarn\": return `yarn add ${pkgs}`;\n case \"bun\": return `bun add ${pkgs}`;\n default: return `npm install ${pkgs}`;\n }\n}\n\nfunction areBisonPackagesInstalled(): boolean {\n return BISON_PACKAGES.every((pkg) => {\n try {\n const pkgJsonPath = join(process.cwd(), \"node_modules\", pkg, \"package.json\");\n return existsSync(pkgJsonPath);\n } catch {\n return false;\n }\n });\n}\n\nfunction findLayoutFile(baseDir: string): string | null {\n const candidates = [\n \"app/layout.tsx\",\n \"app/layout.jsx\",\n \"src/app/layout.tsx\",\n \"src/app/layout.jsx\",\n ];\n for (const candidate of candidates) {\n const full = resolve(baseDir, candidate);\n if (existsSync(full)) return full;\n }\n return null;\n}\n\nfunction injectImportsIntoLayout(layoutPath: string, imports: string): boolean {\n const content = readFileSync(layoutPath, \"utf-8\");\n\n // Check if already injected\n if (content.includes(\"@bison-lab/tokens/css/base.css\") || content.includes(\"@bison-lab/tokens/css/globals.css\")) {\n return false;\n }\n\n // Match all import statements including multiline ones (e.g. import { \\n Foo,\\n } from \"bar\";)\n const importRegex = /^import\\s[\\s\\S]*?from\\s+['\"][^'\"]+['\"];?\\s*$/gm;\n let lastMatchEnd = -1;\n let match: RegExpExecArray | null;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastMatchEnd = match.index + match[0].length;\n }\n\n if (lastMatchEnd === -1) {\n // No imports found, prepend to file\n writeFileSync(layoutPath, imports + \"\\n\\n\" + content, \"utf-8\");\n } else {\n // Insert after the last import statement\n const before = content.slice(0, lastMatchEnd);\n const after = content.slice(lastMatchEnd);\n writeFileSync(layoutPath, before + \"\\n\\n\" + imports + after, \"utf-8\");\n }\n\n return true;\n}\n\nconst CONFIG_FILE = \"bison.config.json\";\nconst THEME_FILE = \"bison-theme.css\";\n\nasync function main() {\n p.intro(pc.bgCyan(pc.black(\" Bison Lab Theme Generator \")));\n\n // --- Output directory ---\n const outputDir = await p.text({\n message: \"Output directory for generated files\",\n placeholder: \".\",\n defaultValue: \".\",\n validate: (v) => {\n if (!v) return undefined;\n const resolved = resolve(process.cwd(), v);\n if (!existsSync(resolved)) return `Directory does not exist: ${v}`;\n return undefined;\n },\n });\n\n if (p.isCancel(outputDir)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n const outDir = resolve(process.cwd(), outputDir as string);\n\n if (outDir !== process.cwd()) {\n p.log.info(`Output directory: ${pc.cyan(relative(process.cwd(), outDir) || \".\")}`);\n }\n\n const configPath = resolve(outDir, CONFIG_FILE);\n let existingConfig: ThemeConfig | undefined;\n\n if (existsSync(configPath)) {\n const raw = JSON.parse(readFileSync(configPath, \"utf-8\")) as ThemeConfig;\n existingConfig = raw;\n\n const mode = await p.select({\n message: \"An existing theme was found. What would you like to do?\",\n options: [\n { value: \"update\", label: \"Update existing theme\", hint: \"Modify individual properties\" },\n { value: \"fresh\", label: \"Start fresh\", hint: \"Overwrite everything\" },\n ],\n });\n\n if (p.isCancel(mode)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n if (mode === \"fresh\") {\n existingConfig = undefined;\n }\n }\n\n const config = await runPrompts(existingConfig);\n\n if (!config) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n // --- Install dependencies ---\n if (!areBisonPackagesInstalled()) {\n const pm = detectPackageManager();\n const cmd = installCommand(pm);\n\n const shouldInstall = await p.confirm({\n message: `Install Bison Lab packages? (${pc.dim(cmd)})`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldInstall)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n if (shouldInstall) {\n const s = p.spinner();\n s.start(`Installing packages with ${pm}...`);\n try {\n execSync(cmd, { cwd: process.cwd(), stdio: \"pipe\" });\n s.stop(\"Packages installed!\");\n } catch (err) {\n s.stop(\"Package installation failed.\");\n p.log.warning(`Run manually: ${pc.cyan(cmd)}`);\n }\n } else {\n p.log.warning(`Skipped. Run manually: ${pc.cyan(installCommand(pm))}`);\n }\n } else {\n p.log.success(\"Bison Lab packages already installed.\");\n }\n\n // --- Generate theme files ---\n const s = p.spinner();\n s.start(\"Generating theme files...\");\n\n const themeCSS = generateThemeCSS(config, { fontsBaseUrl: \"/fonts\" });\n const themePath = resolve(outDir, THEME_FILE);\n writeFileSync(themePath, themeCSS, \"utf-8\");\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n s.stop(\"Theme files generated!\");\n\n const outPrefix = outDir === process.cwd() ? \"\" : relative(process.cwd(), outDir) + \"/\";\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}${THEME_FILE}`);\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}${CONFIG_FILE}`);\n\n // --- Tailwind config guidance ---\n const tailwindPath = resolve(outDir, \"tailwind.config.ts\");\n const presetSnippet = `import bisonPreset from '@bison-lab/tailwind-preset';\\n\\n// Add to your Tailwind config:\\n// presets: [bisonPreset],\\n// content: [..., './node_modules/@bison-lab/ui/dist/**/*.js'],`;\n\n if (existsSync(tailwindPath)) {\n const existing = readFileSync(tailwindPath, \"utf-8\");\n if (existing.includes(\"@bison-lab/tailwind-preset\")) {\n p.log.success(\"tailwind.config.ts already includes Bison Lab preset.\");\n } else {\n p.note(presetSnippet, \"Add to your tailwind.config.ts\");\n\n const action = await p.select({\n message: \"Add the Bison Lab preset to your existing tailwind.config.ts manually:\",\n options: [\n { value: \"copy\", label: \"Copy snippet to clipboard\" },\n { value: \"skip\", label: \"Skip\", hint: \"I'll handle it\" },\n ],\n });\n\n if (!p.isCancel(action) && action === \"copy\") {\n if (copyToClipboard(presetSnippet)) {\n p.log.success(\"Copied Tailwind preset snippet to clipboard!\");\n } else {\n p.log.warning(\"Could not access clipboard — copy manually from above.\");\n }\n }\n }\n } else {\n // No config exists — safe to create one\n const tailwindConfig = generateTailwindConfig();\n writeFileSync(tailwindPath, tailwindConfig, \"utf-8\");\n p.log.success(`${pc.green(\"Created:\")} ${outPrefix}tailwind.config.ts`);\n }\n\n // --- Layout imports ---\n const layoutPath = findLayoutFile(outDir);\n\n // Compute relative path from layout directory to the theme file\n const themeImportPath = layoutPath\n ? relative(dirname(layoutPath), themePath).replace(/\\\\/g, \"/\")\n : `./${THEME_FILE}`;\n const importsSnippet = generateImports(themeImportPath.startsWith(\".\") ? themeImportPath : `./${themeImportPath}`);\n\n if (layoutPath) {\n const injected = injectImportsIntoLayout(layoutPath, importsSnippet);\n if (injected) {\n const rel = relative(process.cwd(), layoutPath);\n p.log.success(`${pc.green(\"Updated:\")} ${rel} with Bison Lab imports.`);\n } else {\n p.log.success(\"Layout file already includes Bison Lab imports.\");\n }\n } else {\n p.note(importsSnippet, \"app/layout.tsx imports\");\n\n const action = await p.select({\n message: \"No layout file found. Copy imports to clipboard?\",\n options: [\n { value: \"copy\", label: \"Copy to clipboard\" },\n { value: \"skip\", label: \"Skip\" },\n ],\n });\n\n if (!p.isCancel(action) && action === \"copy\") {\n if (copyToClipboard(importsSnippet)) {\n p.log.success(\"Copied CSS imports to clipboard!\");\n } else {\n p.log.warning(\"Could not access clipboard — copy manually from above.\");\n }\n }\n }\n\n // --- Font route ---\n const routePath = resolve(outDir, \"app/fonts/[...path]/route.ts\");\n const srcRoutePath = resolve(outDir, \"src/app/fonts/[...path]/route.ts\");\n if (existsSync(routePath) || existsSync(srcRoutePath)) {\n p.log.success(\"Font route already exists.\");\n } else {\n p.note(FONT_ROUTE_SNIPPET, \"Serve the fonts: add this route\");\n }\n\n p.outro(pc.green(\"Done! Your Bison Lab theme is ready.\"));\n}\n\nmain().catch(console.error);\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bison-lab/create-theme",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Interactive CLI for generating and updating Bison Lab theme files",
|
|
5
5
|
"homepage": "https://components.bisonlab.ai",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@clack/prompts": "^1.1.0",
|
|
23
23
|
"picocolors": "^1.1.1",
|
|
24
|
-
"@bison-lab/
|
|
24
|
+
"@bison-lab/fonts": "3.6.0",
|
|
25
|
+
"@bison-lab/tokens": "3.6.0"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/node": "^25.5.0",
|