@beaket/ui 2.1.2 → 2.2.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.js +228 -66
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/add.ts
|
|
7
|
-
import
|
|
8
|
-
import
|
|
7
|
+
import path4 from "path";
|
|
8
|
+
import pc2 from "picocolors";
|
|
9
9
|
|
|
10
10
|
// src/utils/config.ts
|
|
11
11
|
import fs from "fs-extra";
|
|
@@ -117,17 +117,165 @@ async function fetchComponent(componentDef) {
|
|
|
117
117
|
return files;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
// src/utils/theme.ts
|
|
121
|
+
import fs3 from "fs-extra";
|
|
122
|
+
import path3 from "path";
|
|
123
|
+
import pc from "picocolors";
|
|
124
|
+
import prompts2 from "prompts";
|
|
125
|
+
var THEME_START = "/* beaket:theme:start */";
|
|
126
|
+
var THEME_END = "/* beaket:theme:end */";
|
|
127
|
+
var LEGACY_MARKER = "Beaket UI Design System";
|
|
128
|
+
var LEGACY_END_MARKER = "@keyframes navigation-progress";
|
|
129
|
+
function wrapThemeCss(css) {
|
|
130
|
+
return `${THEME_START}
|
|
131
|
+
${css}${THEME_END}
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
function findLegacyBlockEnd(css, searchFrom) {
|
|
135
|
+
const keyframeIdx = css.indexOf(LEGACY_END_MARKER, searchFrom);
|
|
136
|
+
if (keyframeIdx === -1) {
|
|
137
|
+
return css.length;
|
|
138
|
+
}
|
|
139
|
+
let depth = 0;
|
|
140
|
+
let inBlock = false;
|
|
141
|
+
for (let i = keyframeIdx; i < css.length; i++) {
|
|
142
|
+
if (css[i] === "{") {
|
|
143
|
+
depth++;
|
|
144
|
+
inBlock = true;
|
|
145
|
+
} else if (css[i] === "}") {
|
|
146
|
+
depth--;
|
|
147
|
+
if (inBlock && depth === 0) {
|
|
148
|
+
const end = css[i + 1] === "\n" ? i + 2 : i + 1;
|
|
149
|
+
return end;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return css.length;
|
|
154
|
+
}
|
|
155
|
+
function replaceThemeInCss(existingCss, newThemeCss) {
|
|
156
|
+
const wrapped = wrapThemeCss(newThemeCss);
|
|
157
|
+
const startIdx = existingCss.indexOf(THEME_START);
|
|
158
|
+
const endIdx = existingCss.indexOf(THEME_END);
|
|
159
|
+
if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
|
|
160
|
+
const before = existingCss.substring(0, startIdx);
|
|
161
|
+
const afterEnd = endIdx + THEME_END.length;
|
|
162
|
+
const after = existingCss[afterEnd] === "\n" ? existingCss.substring(afterEnd + 1) : existingCss.substring(afterEnd);
|
|
163
|
+
return { css: before + wrapped + after, replaced: true };
|
|
164
|
+
}
|
|
165
|
+
const legacyIdx = existingCss.indexOf(LEGACY_MARKER);
|
|
166
|
+
if (legacyIdx !== -1) {
|
|
167
|
+
const commentStart = existingCss.lastIndexOf("/*", legacyIdx);
|
|
168
|
+
if (commentStart !== -1) {
|
|
169
|
+
const blockEnd = findLegacyBlockEnd(existingCss, commentStart);
|
|
170
|
+
let cutPoint = commentStart;
|
|
171
|
+
if (commentStart > 0 && existingCss[commentStart - 1] === "\n") {
|
|
172
|
+
cutPoint = commentStart - 1;
|
|
173
|
+
}
|
|
174
|
+
const before = existingCss.substring(0, cutPoint);
|
|
175
|
+
const after = existingCss.substring(blockEnd);
|
|
176
|
+
return { css: before + "\n" + wrapped + after, replaced: true };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const separator = existingCss.endsWith("\n") ? "\n" : "\n\n";
|
|
180
|
+
return { css: existingCss + separator + wrapped, replaced: false };
|
|
181
|
+
}
|
|
182
|
+
function extractThemeBlock(cssContent) {
|
|
183
|
+
const startIdx = cssContent.indexOf(THEME_START);
|
|
184
|
+
const endIdx = cssContent.indexOf(THEME_END);
|
|
185
|
+
if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
|
|
186
|
+
const contentStart = startIdx + THEME_START.length;
|
|
187
|
+
const adjustedStart = cssContent[contentStart] === "\n" ? contentStart + 1 : contentStart;
|
|
188
|
+
return cssContent.substring(adjustedStart, endIdx);
|
|
189
|
+
}
|
|
190
|
+
const legacyIdx = cssContent.indexOf(LEGACY_MARKER);
|
|
191
|
+
if (legacyIdx !== -1) {
|
|
192
|
+
const commentStart = cssContent.lastIndexOf("/*", legacyIdx);
|
|
193
|
+
if (commentStart !== -1) {
|
|
194
|
+
const blockEnd = findLegacyBlockEnd(cssContent, commentStart);
|
|
195
|
+
return cssContent.substring(commentStart, blockEnd);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
async function syncTheme(config, themeCssMap, options = {}) {
|
|
201
|
+
const themeName = config.theme || "porcelain";
|
|
202
|
+
const themeCss = themeCssMap[themeName];
|
|
203
|
+
if (!themeCss) {
|
|
204
|
+
console.log(pc.yellow("!"), `Unknown theme "${themeName}". Skipping theme sync.`);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
if (!config.css) {
|
|
208
|
+
console.log(pc.yellow("!"), "No CSS path in config. Skipping theme sync.");
|
|
209
|
+
console.log(" Run", pc.cyan("npx @beaket/ui init"), "to set CSS path.");
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const cssPath = path3.join(process.cwd(), config.css);
|
|
213
|
+
if (!await fs3.pathExists(cssPath)) {
|
|
214
|
+
console.log(pc.yellow("!"), `CSS file not found: ${config.css}. Skipping theme sync.`);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
const existingCss = await fs3.readFile(cssPath, "utf-8");
|
|
218
|
+
const existingTheme = extractThemeBlock(existingCss);
|
|
219
|
+
if (existingTheme !== null && existingTheme.trim() === themeCss.trim()) {
|
|
220
|
+
console.log(pc.green("\u2714"), "Theme tokens are up to date.");
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
if (existingTheme === null) {
|
|
224
|
+
const { css: css2 } = replaceThemeInCss(existingCss, themeCss);
|
|
225
|
+
await fs3.writeFile(cssPath, css2);
|
|
226
|
+
console.log(pc.green("\u2714"), `Added ${themeName} theme tokens to ${config.css}`);
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
if (!options.overwrite) {
|
|
230
|
+
const { confirm } = await prompts2({
|
|
231
|
+
type: "confirm",
|
|
232
|
+
name: "confirm",
|
|
233
|
+
message: `Theme tokens in ${config.css} are outdated. Update to latest ${themeName}?`,
|
|
234
|
+
initial: true
|
|
235
|
+
});
|
|
236
|
+
if (!confirm) {
|
|
237
|
+
console.log(pc.yellow("\u2139"), "Skipped theme update.");
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const { css } = replaceThemeInCss(existingCss, themeCss);
|
|
242
|
+
await fs3.writeFile(cssPath, css);
|
|
243
|
+
console.log(pc.green("\u2714"), `Updated ${themeName} theme tokens in ${config.css}`);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ../../src/themes/eucalyptus.css
|
|
248
|
+
var eucalyptus_default = "/*\n * Beaket UI Design System - Eucalyptus Theme\n * Enterprise titanium. Navy ink, blue-gray surfaces, structured shadows.\n * Cold precision for office and productivity applications.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #0a1025;\n --color-ink: #162036;\n --color-branch: #1c2a42;\n --color-iron: #243250;\n --color-slate: #2f3f58;\n --color-zinc: #384d68;\n --color-steel: #3d5170;\n --color-muted: #5a6d88;\n --color-aluminum: #8295ae;\n --color-chrome: #c0cddb;\n --color-silver: #cdd8e4;\n --color-platinum: #dce3ed;\n --color-frost: #eff2f8;\n --color-paper: #f8f9fc;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 deep cobalt, formal crimson, jade, brass */\n --color-signal-blue: #1535c0;\n --color-signal-red: #b81c38;\n --color-signal-red-hover: #9e1830;\n --color-signal-red-active: #841428;\n --color-signal-red-text: #9e1830;\n --color-signal-green: #0a7860;\n --color-signal-green-hover: #086450;\n --color-signal-green-active: #065040;\n --color-signal-amber: #b87500;\n --color-signal-amber-hover: #9c6300;\n --color-signal-amber-active: #805200;\n --color-signal-amber-text: #9c6300;\n --color-signal-purple: #5b22c8;\n --color-signal-cyan: #0078a8;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #e6ebf2;\n --color-surface-1: #f8f9fc;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 blue-gray, structured */\n --shadow-offset: 2px 2px 0px 0px var(--color-chrome);\n --shadow-offset-dark: 2px 2px 0px 0px var(--color-aluminum);\n --shadow-offset-hover: 3px 3px 0px 0px var(--color-chrome);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-chrome);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 mission control.\n * Command center at night. Navy-blue darkness with structured panels.\n * Navy-tinted neutrals. Signals glow with focused intensity.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 navy-tinted for professional dark authority */\n --color-graphite: #e8ecf4;\n --color-ink: #dce2ec;\n --color-branch: #c4cede;\n --color-iron: #b0bace;\n --color-slate: #98a2b8;\n --color-zinc: #808aa2;\n --color-steel: #687288;\n --color-muted: #546070;\n --color-aluminum: #3c4858;\n --color-chrome: #283444;\n --color-silver: #1e2836;\n --color-platinum: #141a2a;\n --color-frost: #0c1020;\n --color-paper: #060a14;\n\n /* Signal colors \u2014 professional, brightened for dark canvas */\n --color-signal-blue: #3060e0;\n --color-signal-red: #d43450;\n --color-signal-red-hover: #bc2e46;\n --color-signal-red-active: #a4283c;\n --color-signal-red-text: #e84c64;\n --color-signal-green: #14a878;\n --color-signal-green-hover: #108e64;\n --color-signal-green-active: #0c7450;\n --color-signal-amber: #d89420;\n --color-signal-amber-hover: #bc801c;\n --color-signal-amber-active: #a06c18;\n --color-signal-amber-text: #e8a830;\n --color-signal-purple: #9454e8;\n --color-signal-cyan: #2094c8;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #0a0e1a;\n --color-surface-1: #101422;\n --color-surface-2: #18202e;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
249
|
+
|
|
250
|
+
// ../../src/themes/marigold.css
|
|
251
|
+
var marigold_default = "/*\n * Beaket UI Design System - Marigold Theme\n * A neon sign snapping on. Screen-printed posters in a design studio.\n * Light: pure white canvas, ink-black heavy shadows, maximum saturation.\n * Dark: neon signs at night \u2014 vivid electric colors on near-black canvas.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #0a0a0a;\n --color-ink: #121212;\n --color-branch: #1a1a1a;\n --color-iron: #262626;\n --color-slate: #3a3a3a;\n --color-zinc: #4e4e4e;\n --color-steel: #5a5a5a;\n --color-muted: #6e6e6e;\n --color-aluminum: #949494;\n --color-chrome: #c0c0c0;\n --color-silver: #cfcfcf;\n --color-platinum: #e0e0e0;\n --color-frost: #f0f0f0;\n --color-paper: #ffffff;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 LOUD, max saturation, screen-print ink */\n --color-signal-blue: #0044ee;\n --color-signal-red: #e82010;\n --color-signal-red-hover: #cc1c0e;\n --color-signal-red-active: #b0180c;\n --color-signal-red-text: #cc1c0e;\n --color-signal-green: #008050;\n --color-signal-green-hover: #006a42;\n --color-signal-green-active: #005535;\n --color-signal-amber: #f07800;\n --color-signal-amber-hover: #d06800;\n --color-signal-amber-active: #b05800;\n --color-signal-amber-text: #cc6600;\n --color-signal-purple: #8b22ff;\n --color-signal-cyan: #00b4cc;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #ebebeb;\n --color-surface-1: #f8f8f8;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 ink-black, heavy, graphic */\n --shadow-offset: 3px 3px 0px 0px var(--color-ink);\n --shadow-offset-dark: 3px 3px 0px 0px var(--color-graphite);\n --shadow-offset-hover: 4px 4px 0px 0px var(--color-ink);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-ink);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 neon signs at night.\n * Neutrals flip (paper\u2192black, ink\u2192white). Shadows auto-flip via token\n * references (white edge on black = neon glow effect). Signal colors\n * brightened to neon-max for dark canvas contrast.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 pure achromatic for maximum neon contrast */\n --color-graphite: #f5f5f5;\n --color-ink: #ececec;\n --color-branch: #e0e0e0;\n --color-iron: #d0d0d0;\n --color-slate: #bfbfbf;\n --color-zinc: #acacac;\n --color-steel: #999999;\n --color-muted: #858585;\n --color-aluminum: #666666;\n --color-chrome: #404040;\n --color-silver: #303030;\n --color-platinum: #222222;\n --color-frost: #161616;\n --color-paper: #0a0a0a;\n\n /* Signal colors \u2014 neon-bright for dark canvas */\n --color-signal-blue: #4488ff;\n --color-signal-red: #ff2a1a;\n --color-signal-red-hover: #e52518;\n --color-signal-red-active: #cc2012;\n --color-signal-red-text: #ff4838;\n --color-signal-green: #00cc66;\n --color-signal-green-hover: #00b058;\n --color-signal-green-active: #009448;\n --color-signal-amber: #ff8800;\n --color-signal-amber-hover: #e07800;\n --color-signal-amber-active: #c06800;\n --color-signal-amber-text: #ffa030;\n --color-signal-purple: #bb55ff;\n --color-signal-cyan: #00ccdd;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #141414;\n --color-surface-1: #1a1a1a;\n --color-surface-2: #222222;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
252
|
+
|
|
253
|
+
// ../../src/themes/porcelain.css
|
|
254
|
+
var porcelain_default = "/*\n * Beaket UI Design System - Porcelain Theme\n * Industrial precision. Etched on control panels in black synthetic lacquer.\n * Pure white, cold blue-black ink, ghostly shadows, teal accent.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #030508;\n --color-ink: #080b10;\n --color-branch: #05070c;\n --color-iron: #282b2f;\n --color-slate: #3e4145;\n --color-zinc: #53565b;\n --color-steel: #686b6f;\n --color-muted: #7a7d81;\n --color-aluminum: #a0a3a7;\n --color-chrome: #c0c4ca;\n --color-silver: #d5d8dc;\n --color-platinum: #e8eaec;\n --color-frost: #f3f4f6;\n --color-paper: #ffffff;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 cold, precise, teal accent */\n --color-signal-blue: #0c6bae;\n --color-signal-red: #c41028;\n --color-signal-red-hover: #a80d22;\n --color-signal-red-active: #8c0b1c;\n --color-signal-red-text: #a80d22;\n --color-signal-green: #0a7653;\n --color-signal-green-hover: #086248;\n --color-signal-green-active: #064e3a;\n --color-signal-amber: #e09800;\n --color-signal-amber-hover: #c48400;\n --color-signal-amber-active: #a87000;\n --color-signal-amber-text: #b87c00;\n --color-signal-purple: #6122aa;\n --color-signal-cyan: #007e8c;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #eff0f1;\n --color-surface-1: #f8f8f9;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 ghostly, precise */\n --shadow-offset: 1px 1px 0px 0px var(--color-chrome);\n --shadow-offset-dark: 1px 1px 0px 0px var(--color-aluminum);\n --shadow-offset-hover: 2px 2px 0px 0px var(--color-chrome);\n --shadow-offset-active: 0px 0px 0px 0px var(--color-chrome);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 X-ray lightbox.\n * Cold blue-steel instruments in a dark examination room.\n * Neutrals tinted cold blue-black. Ghostly shadows become spectral.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 cold blue-tinted for clinical dark precision */\n --color-graphite: #e6eaee;\n --color-ink: #dce0e6;\n --color-branch: #c8d0da;\n --color-iron: #b4bcc6;\n --color-slate: #9ca4b2;\n --color-zinc: #848c9e;\n --color-steel: #6c7486;\n --color-muted: #586070;\n --color-aluminum: #3e4454;\n --color-chrome: #2a303e;\n --color-silver: #1e242e;\n --color-platinum: #161a22;\n --color-frost: #0e1016;\n --color-paper: #06080c;\n\n /* Signal colors \u2014 cold, brightened for dark canvas */\n --color-signal-blue: #1a8ed8;\n --color-signal-red: #e03040;\n --color-signal-red-hover: #c82a38;\n --color-signal-red-active: #b02430;\n --color-signal-red-text: #f04852;\n --color-signal-green: #10a66e;\n --color-signal-green-hover: #0e8e5e;\n --color-signal-green-active: #0c764e;\n --color-signal-amber: #e89a28;\n --color-signal-amber-hover: #cc8620;\n --color-signal-amber-active: #b07218;\n --color-signal-amber-text: #f0a020;\n --color-signal-purple: #7e3ec4;\n --color-signal-cyan: #1aa0b8;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #0c0e15;\n --color-surface-1: #12141d;\n --color-surface-2: #1a1c27;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
255
|
+
|
|
256
|
+
// ../../src/themes/tobacco.css
|
|
257
|
+
var tobacco_default = "/*\n * Beaket UI Design System - Tobacco Theme\n * Golden hour in a library. Pampas warmth, terracotta accent.\n * Warm gray-cream surface, brown shadows, earthy signals.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #111110;\n --color-ink: #1a1a18;\n --color-branch: #222120;\n --color-iron: #312f2c;\n --color-slate: #46443e;\n --color-zinc: #585650;\n --color-steel: #5e5d54;\n --color-muted: #6b6a60;\n --color-aluminum: #9c9a90;\n --color-chrome: #d0cec5;\n --color-silver: #dddbd3;\n --color-platinum: #e8e7e0;\n --color-frost: #edece6;\n --color-paper: #f4f3ee;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 warm, earthy: old ink, fired brick, forest, ochre */\n --color-signal-blue: #35388a;\n --color-signal-red: #b03525;\n --color-signal-red-hover: #962d1f;\n --color-signal-red-active: #7c2519;\n --color-signal-red-text: #962d1f;\n --color-signal-green: #3a7040;\n --color-signal-green-hover: #305c35;\n --color-signal-green-active: #26482a;\n --color-signal-amber: #a57218;\n --color-signal-amber-hover: #8c6014;\n --color-signal-amber-active: #734f10;\n --color-signal-amber-text: #8c6014;\n --color-signal-purple: #7c336e;\n --color-signal-cyan: #187566;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #e8e7e0;\n --color-surface-1: #f4f3ee;\n --color-surface-2: #faf9f5;\n\n /* Shadows \u2014 warm brown, grounded */\n --shadow-offset: 2px 2px 0px 0px var(--color-iron);\n --shadow-offset-dark: 2px 2px 0px 0px var(--color-slate);\n --shadow-offset-hover: 3px 3px 0px 0px var(--color-iron);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-iron);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 whiskey bar at midnight.\n * Late-night library, amber reading lamps, worn leather.\n * Warm sepia-tinted neutrals. Signals glow like stained glass.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 warm sepia-tinted for intimate darkness */\n --color-graphite: #eceae0;\n --color-ink: #e2e0d6;\n --color-branch: #d4d0c6;\n --color-iron: #c0bcb2;\n --color-slate: #a8a49a;\n --color-zinc: #908c82;\n --color-steel: #787468;\n --color-muted: #646054;\n --color-aluminum: #4a4840;\n --color-chrome: #343230;\n --color-silver: #282624;\n --color-platinum: #1e1c1a;\n --color-frost: #141312;\n --color-paper: #0c0b0a;\n\n /* Signal colors \u2014 warm stained glass glow */\n --color-signal-blue: #5068c0;\n --color-signal-red: #d04838;\n --color-signal-red-hover: #b84030;\n --color-signal-red-active: #a03828;\n --color-signal-red-text: #e06050;\n --color-signal-green: #48a850;\n --color-signal-green-hover: #3c8e44;\n --color-signal-green-active: #307438;\n --color-signal-amber: #d09828;\n --color-signal-amber-hover: #b48420;\n --color-signal-amber-active: #987018;\n --color-signal-amber-text: #e0a838;\n --color-signal-purple: #a05088;\n --color-signal-cyan: #28a890;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #121110;\n --color-surface-1: #1a1918;\n --color-surface-2: #222120;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
258
|
+
|
|
259
|
+
// src/utils/themes.ts
|
|
260
|
+
var THEME_CSS = {
|
|
261
|
+
porcelain: porcelain_default,
|
|
262
|
+
tobacco: tobacco_default,
|
|
263
|
+
marigold: marigold_default,
|
|
264
|
+
eucalyptus: eucalyptus_default
|
|
265
|
+
};
|
|
266
|
+
var VALID_THEMES = Object.keys(THEME_CSS);
|
|
267
|
+
|
|
120
268
|
// src/commands/add.ts
|
|
121
269
|
async function add(componentNames, options) {
|
|
122
270
|
console.log();
|
|
123
271
|
const config = await getConfig();
|
|
124
272
|
if (!config) {
|
|
125
|
-
console.log(
|
|
126
|
-
console.log("Run",
|
|
273
|
+
console.log(pc2.red("Error:"), "beaket.ui.json not found.");
|
|
274
|
+
console.log("Run", pc2.cyan("npx @beaket/ui init"), "first.");
|
|
127
275
|
process.exit(1);
|
|
128
276
|
}
|
|
129
277
|
const registry = await fetchRegistry();
|
|
130
|
-
console.log(
|
|
278
|
+
console.log(pc2.green("\u2714"), "Checking registry.");
|
|
131
279
|
const notFound = [];
|
|
132
280
|
const componentDefs = componentNames.map((name) => {
|
|
133
281
|
const def = registry.components.find((c) => c.name === name);
|
|
@@ -135,7 +283,7 @@ async function add(componentNames, options) {
|
|
|
135
283
|
return def;
|
|
136
284
|
});
|
|
137
285
|
if (notFound.length > 0) {
|
|
138
|
-
console.log(
|
|
286
|
+
console.log(pc2.red("Error:"), `Component(s) not found: ${notFound.join(", ")}`);
|
|
139
287
|
console.log();
|
|
140
288
|
console.log("Available components:");
|
|
141
289
|
registry.components.forEach((c) => {
|
|
@@ -153,9 +301,9 @@ async function add(componentNames, options) {
|
|
|
153
301
|
}
|
|
154
302
|
if (allDependencies.size > 0) {
|
|
155
303
|
await installDependencies([...allDependencies]);
|
|
156
|
-
console.log(
|
|
304
|
+
console.log(pc2.green("\u2714"), "Installing dependencies.");
|
|
157
305
|
}
|
|
158
|
-
const componentsDir =
|
|
306
|
+
const componentsDir = path4.join(process.cwd(), config.components);
|
|
159
307
|
const allWritten = [];
|
|
160
308
|
const allSkipped = [];
|
|
161
309
|
for (const def of componentDefs) {
|
|
@@ -167,7 +315,7 @@ async function add(componentNames, options) {
|
|
|
167
315
|
}
|
|
168
316
|
if (allSkipped.length > 0) {
|
|
169
317
|
console.log(
|
|
170
|
-
|
|
318
|
+
pc2.yellow("\u2139"),
|
|
171
319
|
`Skipped ${allSkipped.length} file(s): (use --overwrite to overwrite)`
|
|
172
320
|
);
|
|
173
321
|
allSkipped.forEach((f) => console.log(` - ${f}`));
|
|
@@ -178,47 +326,26 @@ async function add(componentNames, options) {
|
|
|
178
326
|
}
|
|
179
327
|
console.log();
|
|
180
328
|
console.log("Added:");
|
|
181
|
-
allWritten.forEach((f) => console.log(
|
|
329
|
+
allWritten.forEach((f) => console.log(pc2.cyan(` ${f}`)));
|
|
330
|
+
if (config.css) {
|
|
331
|
+
console.log();
|
|
332
|
+
await syncTheme(config, THEME_CSS, { overwrite: options.overwrite });
|
|
333
|
+
}
|
|
182
334
|
console.log();
|
|
183
335
|
}
|
|
184
336
|
|
|
185
337
|
// src/commands/init.ts
|
|
186
|
-
import
|
|
187
|
-
import
|
|
188
|
-
import
|
|
189
|
-
import
|
|
190
|
-
|
|
191
|
-
// ../../src/css-variables.css
|
|
192
|
-
var css_variables_default = "/*\n * Beaket UI Design System - Core Variables (Porcelain)\n * This file is the single source of truth for CSS variables.\n * Used by: styles.css (via @import) and CLI init command (via build script)\n *\n * BREAKING CHANGE: Colors now use --color-* prefix (Tailwind v4 convention).\n * Components use clean utilities: bg-paper, text-ink, border-chrome\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #030509;\n --color-ink: #080b12;\n --color-branch: #05070d;\n --color-iron: #282b30;\n --color-slate: #3e4146;\n --color-zinc: #53565c;\n --color-steel: #686b70;\n --color-muted: #7a7d82;\n --color-aluminum: #a0a3a8;\n --color-chrome: #c0c5cc;\n --color-silver: #d5d8dd;\n --color-platinum: #e8eaed;\n --color-frost: #f3f4f6;\n --color-paper: #ffffff;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 cold, precise, teal accent */\n --color-signal-blue: #0c6daa;\n --color-signal-red: #c41028;\n --color-signal-red-hover: #a80d22;\n --color-signal-red-active: #8c0b1c;\n --color-signal-red-text: #a80d22;\n --color-signal-green: #0a7855;\n --color-signal-green-hover: #08644a;\n --color-signal-green-active: #06503c;\n --color-signal-amber: #e09800;\n --color-signal-amber-hover: #c48400;\n --color-signal-amber-active: #a87000;\n --color-signal-amber-text: #b87c00;\n --color-signal-purple: #6122aa;\n --color-signal-cyan: #007e8c;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #eff0f2;\n --color-surface-1: #f8f8fa;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 ghostly, precise */\n --shadow-offset: 1px 1px 0px 0px var(--color-chrome);\n --shadow-offset-dark: 1px 1px 0px 0px var(--color-aluminum);\n --shadow-offset-hover: 2px 2px 0px 0px var(--color-chrome);\n --shadow-offset-active: 0px 0px 0px 0px var(--color-chrome);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
193
|
-
|
|
194
|
-
// ../../src/themes/eucalyptus.css
|
|
195
|
-
var eucalyptus_default = "/*\n * Beaket UI Design System - Eucalyptus Theme\n * Enterprise titanium. Navy ink, blue-gray surfaces, structured shadows.\n * Cold precision for office and productivity applications.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #0a1025;\n --color-ink: #162036;\n --color-branch: #1c2a42;\n --color-iron: #243250;\n --color-slate: #2f3f58;\n --color-zinc: #384d68;\n --color-steel: #3d5170;\n --color-muted: #5a6d88;\n --color-aluminum: #8295ae;\n --color-chrome: #c0cddb;\n --color-silver: #cdd8e4;\n --color-platinum: #dce3ed;\n --color-frost: #eff2f8;\n --color-paper: #f8f9fc;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 deep cobalt, formal crimson, jade, brass */\n --color-signal-blue: #1535c0;\n --color-signal-red: #b81c38;\n --color-signal-red-hover: #9e1830;\n --color-signal-red-active: #841428;\n --color-signal-red-text: #9e1830;\n --color-signal-green: #0a7860;\n --color-signal-green-hover: #086450;\n --color-signal-green-active: #065040;\n --color-signal-amber: #b87500;\n --color-signal-amber-hover: #9c6300;\n --color-signal-amber-active: #805200;\n --color-signal-amber-text: #9c6300;\n --color-signal-purple: #5b22c8;\n --color-signal-cyan: #0078a8;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #e6ebf2;\n --color-surface-1: #f8f9fc;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 blue-gray, structured */\n --shadow-offset: 2px 2px 0px 0px var(--color-chrome);\n --shadow-offset-dark: 2px 2px 0px 0px var(--color-aluminum);\n --shadow-offset-hover: 3px 3px 0px 0px var(--color-chrome);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-chrome);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 mission control.\n * Command center at night. Navy-blue darkness with structured panels.\n * Navy-tinted neutrals. Signals glow with focused intensity.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 navy-tinted for professional dark authority */\n --color-graphite: #e8ecf4;\n --color-ink: #dce2ec;\n --color-branch: #c4cede;\n --color-iron: #b0bace;\n --color-slate: #98a2b8;\n --color-zinc: #808aa2;\n --color-steel: #687288;\n --color-muted: #546070;\n --color-aluminum: #3c4858;\n --color-chrome: #283444;\n --color-silver: #1e2836;\n --color-platinum: #141a2a;\n --color-frost: #0c1020;\n --color-paper: #060a14;\n\n /* Signal colors \u2014 professional, brightened for dark canvas */\n --color-signal-blue: #3060e0;\n --color-signal-red: #d43450;\n --color-signal-red-hover: #bc2e46;\n --color-signal-red-active: #a4283c;\n --color-signal-red-text: #e84c64;\n --color-signal-green: #14a878;\n --color-signal-green-hover: #108e64;\n --color-signal-green-active: #0c7450;\n --color-signal-amber: #d89420;\n --color-signal-amber-hover: #bc801c;\n --color-signal-amber-active: #a06c18;\n --color-signal-amber-text: #e8a830;\n --color-signal-purple: #9454e8;\n --color-signal-cyan: #2094c8;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #0a0e1a;\n --color-surface-1: #101422;\n --color-surface-2: #18202e;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
196
|
-
|
|
197
|
-
// ../../src/themes/marigold.css
|
|
198
|
-
var marigold_default = "/*\n * Beaket UI Design System - Marigold Theme\n * A neon sign snapping on. Screen-printed posters in a design studio.\n * Light: pure white canvas, ink-black heavy shadows, maximum saturation.\n * Dark: neon signs at night \u2014 vivid electric colors on near-black canvas.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #0a0a0a;\n --color-ink: #121212;\n --color-branch: #1a1a1a;\n --color-iron: #262626;\n --color-slate: #3a3a3a;\n --color-zinc: #4e4e4e;\n --color-steel: #5a5a5a;\n --color-muted: #6e6e6e;\n --color-aluminum: #949494;\n --color-chrome: #c0c0c0;\n --color-silver: #cfcfcf;\n --color-platinum: #e0e0e0;\n --color-frost: #f0f0f0;\n --color-paper: #ffffff;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 LOUD, max saturation, screen-print ink */\n --color-signal-blue: #0044ee;\n --color-signal-red: #e82010;\n --color-signal-red-hover: #cc1c0e;\n --color-signal-red-active: #b0180c;\n --color-signal-red-text: #cc1c0e;\n --color-signal-green: #008050;\n --color-signal-green-hover: #006a42;\n --color-signal-green-active: #005535;\n --color-signal-amber: #f07800;\n --color-signal-amber-hover: #d06800;\n --color-signal-amber-active: #b05800;\n --color-signal-amber-text: #cc6600;\n --color-signal-purple: #8b22ff;\n --color-signal-cyan: #00b4cc;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #ebebeb;\n --color-surface-1: #f8f8f8;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 ink-black, heavy, graphic */\n --shadow-offset: 3px 3px 0px 0px var(--color-ink);\n --shadow-offset-dark: 3px 3px 0px 0px var(--color-graphite);\n --shadow-offset-hover: 4px 4px 0px 0px var(--color-ink);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-ink);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 neon signs at night.\n * Neutrals flip (paper\u2192black, ink\u2192white). Shadows auto-flip via token\n * references (white edge on black = neon glow effect). Signal colors\n * brightened to neon-max for dark canvas contrast.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 pure achromatic for maximum neon contrast */\n --color-graphite: #f5f5f5;\n --color-ink: #ececec;\n --color-branch: #e0e0e0;\n --color-iron: #d0d0d0;\n --color-slate: #bfbfbf;\n --color-zinc: #acacac;\n --color-steel: #999999;\n --color-muted: #858585;\n --color-aluminum: #666666;\n --color-chrome: #404040;\n --color-silver: #303030;\n --color-platinum: #222222;\n --color-frost: #161616;\n --color-paper: #0a0a0a;\n\n /* Signal colors \u2014 neon-bright for dark canvas */\n --color-signal-blue: #4488ff;\n --color-signal-red: #ff2a1a;\n --color-signal-red-hover: #e52518;\n --color-signal-red-active: #cc2012;\n --color-signal-red-text: #ff4838;\n --color-signal-green: #00cc66;\n --color-signal-green-hover: #00b058;\n --color-signal-green-active: #009448;\n --color-signal-amber: #ff8800;\n --color-signal-amber-hover: #e07800;\n --color-signal-amber-active: #c06800;\n --color-signal-amber-text: #ffa030;\n --color-signal-purple: #bb55ff;\n --color-signal-cyan: #00ccdd;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #141414;\n --color-surface-1: #1a1a1a;\n --color-surface-2: #222222;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
199
|
-
|
|
200
|
-
// ../../src/themes/porcelain.css
|
|
201
|
-
var porcelain_default = "/*\n * Beaket UI Design System - Porcelain Theme\n * Industrial precision. Etched on control panels in black synthetic lacquer.\n * Pure white, cold blue-black ink, ghostly shadows, teal accent.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #030508;\n --color-ink: #080b10;\n --color-branch: #05070c;\n --color-iron: #282b2f;\n --color-slate: #3e4145;\n --color-zinc: #53565b;\n --color-steel: #686b6f;\n --color-muted: #7a7d81;\n --color-aluminum: #a0a3a7;\n --color-chrome: #c0c4ca;\n --color-silver: #d5d8dc;\n --color-platinum: #e8eaec;\n --color-frost: #f3f4f6;\n --color-paper: #ffffff;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 cold, precise, teal accent */\n --color-signal-blue: #0c6bae;\n --color-signal-red: #c41028;\n --color-signal-red-hover: #a80d22;\n --color-signal-red-active: #8c0b1c;\n --color-signal-red-text: #a80d22;\n --color-signal-green: #0a7653;\n --color-signal-green-hover: #086248;\n --color-signal-green-active: #064e3a;\n --color-signal-amber: #e09800;\n --color-signal-amber-hover: #c48400;\n --color-signal-amber-active: #a87000;\n --color-signal-amber-text: #b87c00;\n --color-signal-purple: #6122aa;\n --color-signal-cyan: #007e8c;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #eff0f1;\n --color-surface-1: #f8f8f9;\n --color-surface-2: #ffffff;\n\n /* Shadows \u2014 ghostly, precise */\n --shadow-offset: 1px 1px 0px 0px var(--color-chrome);\n --shadow-offset-dark: 1px 1px 0px 0px var(--color-aluminum);\n --shadow-offset-hover: 2px 2px 0px 0px var(--color-chrome);\n --shadow-offset-active: 0px 0px 0px 0px var(--color-chrome);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 X-ray lightbox.\n * Cold blue-steel instruments in a dark examination room.\n * Neutrals tinted cold blue-black. Ghostly shadows become spectral.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 cold blue-tinted for clinical dark precision */\n --color-graphite: #e6eaee;\n --color-ink: #dce0e6;\n --color-branch: #c8d0da;\n --color-iron: #b4bcc6;\n --color-slate: #9ca4b2;\n --color-zinc: #848c9e;\n --color-steel: #6c7486;\n --color-muted: #586070;\n --color-aluminum: #3e4454;\n --color-chrome: #2a303e;\n --color-silver: #1e242e;\n --color-platinum: #161a22;\n --color-frost: #0e1016;\n --color-paper: #06080c;\n\n /* Signal colors \u2014 cold, brightened for dark canvas */\n --color-signal-blue: #1a8ed8;\n --color-signal-red: #e03040;\n --color-signal-red-hover: #c82a38;\n --color-signal-red-active: #b02430;\n --color-signal-red-text: #f04852;\n --color-signal-green: #10a66e;\n --color-signal-green-hover: #0e8e5e;\n --color-signal-green-active: #0c764e;\n --color-signal-amber: #e89a28;\n --color-signal-amber-hover: #cc8620;\n --color-signal-amber-active: #b07218;\n --color-signal-amber-text: #f0a020;\n --color-signal-purple: #7e3ec4;\n --color-signal-cyan: #1aa0b8;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #0c0e15;\n --color-surface-1: #12141d;\n --color-surface-2: #1a1c27;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
202
|
-
|
|
203
|
-
// ../../src/themes/tobacco.css
|
|
204
|
-
var tobacco_default = "/*\n * Beaket UI Design System - Tobacco Theme\n * Golden hour in a library. Pampas warmth, terracotta accent.\n * Warm gray-cream surface, brown shadows, earthy signals.\n */\n\n@theme {\n /* Neutral palette */\n --color-graphite: #111110;\n --color-ink: #1a1a18;\n --color-branch: #222120;\n --color-iron: #312f2c;\n --color-slate: #46443e;\n --color-zinc: #585650;\n --color-steel: #5e5d54;\n --color-muted: #6b6a60;\n --color-aluminum: #9c9a90;\n --color-chrome: #d0cec5;\n --color-silver: #dddbd3;\n --color-platinum: #e8e7e0;\n --color-frost: #edece6;\n --color-paper: #f4f3ee;\n --color-inverse: var(--color-paper);\n\n /* Signal colors \u2014 warm, earthy: old ink, fired brick, forest, ochre */\n --color-signal-blue: #35388a;\n --color-signal-red: #b03525;\n --color-signal-red-hover: #962d1f;\n --color-signal-red-active: #7c2519;\n --color-signal-red-text: #962d1f;\n --color-signal-green: #3a7040;\n --color-signal-green-hover: #305c35;\n --color-signal-green-active: #26482a;\n --color-signal-amber: #a57218;\n --color-signal-amber-hover: #8c6014;\n --color-signal-amber-active: #734f10;\n --color-signal-amber-text: #8c6014;\n --color-signal-purple: #7c336e;\n --color-signal-cyan: #187566;\n\n /* Surface layers (visual depth) */\n --color-surface-0: #e8e7e0;\n --color-surface-1: #f4f3ee;\n --color-surface-2: #faf9f5;\n\n /* Shadows \u2014 warm brown, grounded */\n --shadow-offset: 2px 2px 0px 0px var(--color-iron);\n --shadow-offset-dark: 2px 2px 0px 0px var(--color-slate);\n --shadow-offset-hover: 3px 3px 0px 0px var(--color-iron);\n --shadow-offset-active: 1px 1px 0px 0px var(--color-iron);\n\n /* Animations */\n --animate-navigation-progress: navigation-progress 1s ease-in-out infinite;\n}\n\n/*\n * Dark mode \u2014 whiskey bar at midnight.\n * Late-night library, amber reading lamps, worn leather.\n * Warm sepia-tinted neutrals. Signals glow like stained glass.\n */\n@media (prefers-color-scheme: dark) {\n :root {\n /* Neutral palette \u2014 warm sepia-tinted for intimate darkness */\n --color-graphite: #eceae0;\n --color-ink: #e2e0d6;\n --color-branch: #d4d0c6;\n --color-iron: #c0bcb2;\n --color-slate: #a8a49a;\n --color-zinc: #908c82;\n --color-steel: #787468;\n --color-muted: #646054;\n --color-aluminum: #4a4840;\n --color-chrome: #343230;\n --color-silver: #282624;\n --color-platinum: #1e1c1a;\n --color-frost: #141312;\n --color-paper: #0c0b0a;\n\n /* Signal colors \u2014 warm stained glass glow */\n --color-signal-blue: #5068c0;\n --color-signal-red: #d04838;\n --color-signal-red-hover: #b84030;\n --color-signal-red-active: #a03828;\n --color-signal-red-text: #e06050;\n --color-signal-green: #48a850;\n --color-signal-green-hover: #3c8e44;\n --color-signal-green-active: #307438;\n --color-signal-amber: #d09828;\n --color-signal-amber-hover: #b48420;\n --color-signal-amber-active: #987018;\n --color-signal-amber-text: #e0a838;\n --color-signal-purple: #a05088;\n --color-signal-cyan: #28a890;\n\n /* Surface layers \u2014 elevation = lighter */\n --color-surface-0: #121110;\n --color-surface-1: #1a1918;\n --color-surface-2: #222120;\n }\n}\n\n@keyframes navigation-progress {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n";
|
|
205
|
-
|
|
206
|
-
// src/commands/init.ts
|
|
207
|
-
var THEME_CSS = {
|
|
208
|
-
porcelain: porcelain_default,
|
|
209
|
-
tobacco: tobacco_default,
|
|
210
|
-
marigold: marigold_default,
|
|
211
|
-
eucalyptus: eucalyptus_default,
|
|
212
|
-
default: css_variables_default
|
|
213
|
-
};
|
|
214
|
-
var VALID_THEMES = Object.keys(THEME_CSS);
|
|
338
|
+
import fs4 from "fs-extra";
|
|
339
|
+
import path5 from "path";
|
|
340
|
+
import pc3 from "picocolors";
|
|
341
|
+
import prompts3 from "prompts";
|
|
215
342
|
async function detectAliasPath() {
|
|
216
343
|
const cwd = process.cwd();
|
|
217
344
|
for (const configFile of ["tsconfig.json", "tsconfig.app.json"]) {
|
|
218
|
-
const configPath =
|
|
219
|
-
if (await
|
|
345
|
+
const configPath = path5.join(cwd, configFile);
|
|
346
|
+
if (await fs4.pathExists(configPath)) {
|
|
220
347
|
try {
|
|
221
|
-
const content = await
|
|
348
|
+
const content = await fs4.readFile(configPath, "utf-8");
|
|
222
349
|
const tsconfig = JSON.parse(content);
|
|
223
350
|
const paths = tsconfig.compilerOptions?.paths;
|
|
224
351
|
if (paths?.["@/*"]) {
|
|
@@ -230,10 +357,10 @@ async function detectAliasPath() {
|
|
|
230
357
|
}
|
|
231
358
|
}
|
|
232
359
|
}
|
|
233
|
-
const pkgPath =
|
|
234
|
-
if (await
|
|
360
|
+
const pkgPath = path5.join(cwd, "package.json");
|
|
361
|
+
if (await fs4.pathExists(pkgPath)) {
|
|
235
362
|
try {
|
|
236
|
-
const content = await
|
|
363
|
+
const content = await fs4.readFile(pkgPath, "utf-8");
|
|
237
364
|
const pkg = JSON.parse(content);
|
|
238
365
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
239
366
|
if (deps.next) {
|
|
@@ -246,10 +373,10 @@ async function detectAliasPath() {
|
|
|
246
373
|
}
|
|
247
374
|
async function detectCssPath() {
|
|
248
375
|
const cwd = process.cwd();
|
|
249
|
-
const pkgPath =
|
|
250
|
-
if (await
|
|
376
|
+
const pkgPath = path5.join(cwd, "package.json");
|
|
377
|
+
if (await fs4.pathExists(pkgPath)) {
|
|
251
378
|
try {
|
|
252
|
-
const content = await
|
|
379
|
+
const content = await fs4.readFile(pkgPath, "utf-8");
|
|
253
380
|
const pkg = JSON.parse(content);
|
|
254
381
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
255
382
|
if (deps.next) {
|
|
@@ -262,11 +389,11 @@ async function detectCssPath() {
|
|
|
262
389
|
}
|
|
263
390
|
async function init(options) {
|
|
264
391
|
console.log();
|
|
265
|
-
console.log(
|
|
392
|
+
console.log(pc3.bold("Initializing Beaket UI..."));
|
|
266
393
|
console.log();
|
|
267
394
|
if (options.theme && !VALID_THEMES.includes(options.theme)) {
|
|
268
395
|
console.log(
|
|
269
|
-
|
|
396
|
+
pc3.red("Error:"),
|
|
270
397
|
`Invalid theme "${options.theme}". Choose from: ${VALID_THEMES.join(", ")}`
|
|
271
398
|
);
|
|
272
399
|
process.exit(1);
|
|
@@ -281,7 +408,7 @@ async function init(options) {
|
|
|
281
408
|
theme: options.theme || "porcelain"
|
|
282
409
|
};
|
|
283
410
|
} else {
|
|
284
|
-
const answers = await
|
|
411
|
+
const answers = await prompts3([
|
|
285
412
|
{
|
|
286
413
|
type: "text",
|
|
287
414
|
name: "components",
|
|
@@ -308,7 +435,7 @@ async function init(options) {
|
|
|
308
435
|
}
|
|
309
436
|
]);
|
|
310
437
|
if (!answers.components) {
|
|
311
|
-
console.log(
|
|
438
|
+
console.log(pc3.red("Cancelled."));
|
|
312
439
|
process.exit(1);
|
|
313
440
|
}
|
|
314
441
|
response = {
|
|
@@ -320,40 +447,75 @@ async function init(options) {
|
|
|
320
447
|
const config = {
|
|
321
448
|
$schema: "https://beaket.dev/schema.json",
|
|
322
449
|
components: response.components,
|
|
450
|
+
css: response.css || void 0,
|
|
323
451
|
theme: response.theme
|
|
324
452
|
};
|
|
325
453
|
await writeConfig(config);
|
|
326
|
-
console.log(
|
|
454
|
+
console.log(pc3.green("\u2714"), "Created beaket.ui.json");
|
|
327
455
|
const selectedCss = THEME_CSS[response.theme];
|
|
456
|
+
if (!selectedCss) {
|
|
457
|
+
console.log(pc3.red("Error:"), `Unknown theme "${response.theme}".`);
|
|
458
|
+
process.exit(1);
|
|
459
|
+
}
|
|
328
460
|
if (response.css) {
|
|
329
|
-
const cssPath =
|
|
330
|
-
if (await
|
|
331
|
-
const cssContent = await
|
|
332
|
-
if (!cssContent.includes("Beaket UI Design System")) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
console.log(
|
|
461
|
+
const cssPath = path5.join(process.cwd(), response.css);
|
|
462
|
+
if (await fs4.pathExists(cssPath)) {
|
|
463
|
+
const cssContent = await fs4.readFile(cssPath, "utf-8");
|
|
464
|
+
if (!cssContent.includes("Beaket UI Design System") && !cssContent.includes("beaket:theme:start")) {
|
|
465
|
+
const { css } = replaceThemeInCss(cssContent, selectedCss);
|
|
466
|
+
await fs4.writeFile(cssPath, css);
|
|
467
|
+
console.log(pc3.green("\u2714"), `Added CSS variables to ${response.css}`);
|
|
468
|
+
console.log(pc3.green("\u2714"), `Using ${response.theme} theme`);
|
|
336
469
|
} else {
|
|
337
|
-
console.log(
|
|
470
|
+
console.log(pc3.yellow("\u2139"), "CSS variables already exist");
|
|
338
471
|
}
|
|
339
472
|
} else {
|
|
340
|
-
console.log(
|
|
473
|
+
console.log(pc3.yellow("!"), `CSS file not found: ${response.css}`);
|
|
341
474
|
console.log(" Add CSS variables manually:");
|
|
342
|
-
console.log(
|
|
475
|
+
console.log(pc3.cyan(" https://beaket.github.io/ui/installation"));
|
|
343
476
|
}
|
|
344
477
|
}
|
|
345
478
|
console.log();
|
|
346
|
-
console.log(
|
|
479
|
+
console.log(pc3.green("Done!"), "Beaket UI is ready.");
|
|
347
480
|
console.log();
|
|
348
481
|
console.log("Add components:");
|
|
349
|
-
console.log(
|
|
482
|
+
console.log(pc3.cyan(" npx @beaket/ui add button"));
|
|
483
|
+
console.log();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// src/commands/theme.ts
|
|
487
|
+
import pc4 from "picocolors";
|
|
488
|
+
async function theme(options) {
|
|
489
|
+
console.log();
|
|
490
|
+
const config = await getConfig();
|
|
491
|
+
if (!config) {
|
|
492
|
+
console.log(pc4.red("Error:"), "beaket.ui.json not found.");
|
|
493
|
+
console.log("Run", pc4.cyan("npx @beaket/ui init"), "first.");
|
|
494
|
+
process.exit(1);
|
|
495
|
+
}
|
|
496
|
+
if (options.theme) {
|
|
497
|
+
if (!VALID_THEMES.includes(options.theme)) {
|
|
498
|
+
console.log(
|
|
499
|
+
pc4.red("Error:"),
|
|
500
|
+
`Invalid theme "${options.theme}". Choose from: ${VALID_THEMES.join(", ")}`
|
|
501
|
+
);
|
|
502
|
+
process.exit(1);
|
|
503
|
+
}
|
|
504
|
+
config.theme = options.theme;
|
|
505
|
+
}
|
|
506
|
+
await syncTheme(config, THEME_CSS, { overwrite: true });
|
|
507
|
+
if (options.theme) {
|
|
508
|
+
await writeConfig(config);
|
|
509
|
+
console.log(pc4.green("\u2714"), `Switched to ${options.theme} theme.`);
|
|
510
|
+
}
|
|
350
511
|
console.log();
|
|
351
512
|
}
|
|
352
513
|
|
|
353
514
|
// src/index.ts
|
|
354
|
-
var version = "2.
|
|
515
|
+
var version = "2.2.0";
|
|
355
516
|
var program = new Command();
|
|
356
517
|
program.name("@beaket/ui").description("CLI for adding Beaket UI components to your project").version(version);
|
|
357
518
|
program.command("init").description("Initialize Beaket UI in your project").option("-y, --yes", "Use defaults without prompting").option("--theme <preset>", "Theme: porcelain, tobacco, marigold, or eucalyptus").action(init);
|
|
358
519
|
program.command("add").description("Add components to your project").argument("<components...>", "Component names to add").option("-o, --overwrite", "Overwrite existing files").action(add);
|
|
520
|
+
program.command("theme").description("Sync theme CSS tokens to your project").option("--theme <preset>", "Switch theme: porcelain, tobacco, marigold, or eucalyptus").action(theme);
|
|
359
521
|
program.parse();
|