inai-react-components 0.1.4 → 0.1.6
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/commands/add.d.ts +3 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +195 -3
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -2
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/package.json +1 -2
package/dist/commands/add.d.ts
CHANGED
|
@@ -30,5 +30,7 @@ export declare function getTargetDir(component: RegistryComponent, aliases: {
|
|
|
30
30
|
blocks: string;
|
|
31
31
|
}): string;
|
|
32
32
|
export declare function runAdd(componentSpec: string, rootDir: string): Promise<AddResult>;
|
|
33
|
-
export declare function addCommand(componentSpec?: string
|
|
33
|
+
export declare function addCommand(componentSpec?: string, options?: {
|
|
34
|
+
all?: boolean;
|
|
35
|
+
}): Promise<void>;
|
|
34
36
|
//# sourceMappingURL=add.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,aAAa,CAAC;AASrB,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAChD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAQA;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE;IAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,iBAAiB,EAAE,CAAA;CAAE,EAC1G,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,iBAAiB,GAAG,IAAI,CAc1B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9C,MAAM,CAUR;AAED,wBAAsB,MAAM,CAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC,CAsHpB;AAuBD,wBAAsB,UAAU,CAC9B,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgCf"}
|
package/dist/commands/add.js
CHANGED
|
@@ -5,6 +5,7 @@ import ora from "ora";
|
|
|
5
5
|
import prompts from "prompts";
|
|
6
6
|
import { readComponentsJson, readRegistryJson, } from "./status.js";
|
|
7
7
|
import { resolveRegistryDir } from "../utils/registry-resolver.js";
|
|
8
|
+
import { normalizeThemeCss, getLocalTailwindCssTemplate, getLegacyTailwindCssTemplate, } from "./init.js";
|
|
8
9
|
/**
|
|
9
10
|
* Parse a component spec like "button", "block/auth-login", or "template/admin-dashboard"
|
|
10
11
|
* into its type prefix and name.
|
|
@@ -166,7 +167,12 @@ function printAddResult(result) {
|
|
|
166
167
|
console.log(chalk.cyan(` pnpm add ${result.npmDeps.join(" ")}`));
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
|
-
export async function addCommand(componentSpec) {
|
|
170
|
+
export async function addCommand(componentSpec, options) {
|
|
171
|
+
// If --all flag, install everything
|
|
172
|
+
if (options?.all) {
|
|
173
|
+
await installAll();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
170
176
|
// If no component specified, show interactive picker
|
|
171
177
|
if (!componentSpec) {
|
|
172
178
|
await interactiveAdd();
|
|
@@ -190,6 +196,173 @@ export async function addCommand(componentSpec) {
|
|
|
190
196
|
process.exit(1);
|
|
191
197
|
}
|
|
192
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Discover available themes from the registry's tokens directory.
|
|
201
|
+
*/
|
|
202
|
+
function discoverThemes(registryDir) {
|
|
203
|
+
const themesDir = path.join(registryDir, "packages", "tokens", "src", "themes");
|
|
204
|
+
if (fs.existsSync(themesDir)) {
|
|
205
|
+
return fs
|
|
206
|
+
.readdirSync(themesDir)
|
|
207
|
+
.filter((f) => f.endsWith(".css"))
|
|
208
|
+
.map((f) => f.replace(/\.css$/, ""))
|
|
209
|
+
.sort();
|
|
210
|
+
}
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Switch the project's theme. Copies the new theme CSS (normalized),
|
|
215
|
+
* updates components.json, and regenerates the CSS entry point.
|
|
216
|
+
*/
|
|
217
|
+
async function changeTheme(rootDir, registryDir) {
|
|
218
|
+
const componentsJson = readComponentsJson(rootDir);
|
|
219
|
+
const currentTheme = componentsJson.theme ?? "monday";
|
|
220
|
+
const themes = discoverThemes(registryDir);
|
|
221
|
+
if (themes.length === 0) {
|
|
222
|
+
console.log(chalk.red("No themes found in registry."));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const currentIdx = themes.indexOf(currentTheme);
|
|
226
|
+
const response = await prompts({
|
|
227
|
+
type: "select",
|
|
228
|
+
name: "theme",
|
|
229
|
+
message: `Select a theme ${chalk.dim(`(current: ${currentTheme})`)}`,
|
|
230
|
+
choices: themes.map((t) => ({
|
|
231
|
+
title: t === currentTheme ? `${t} ${chalk.green("(current)")}` : t,
|
|
232
|
+
value: t,
|
|
233
|
+
})),
|
|
234
|
+
initial: currentIdx >= 0 ? currentIdx : 0,
|
|
235
|
+
});
|
|
236
|
+
if (!response.theme) {
|
|
237
|
+
console.log(chalk.yellow("\nTheme change cancelled."));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const newTheme = response.theme;
|
|
241
|
+
if (newTheme === currentTheme) {
|
|
242
|
+
console.log(chalk.dim("\nTheme unchanged."));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const spinner = ora(`Switching theme to "${newTheme}"...`).start();
|
|
246
|
+
try {
|
|
247
|
+
const tokensSrc = path.join(registryDir, "packages", "tokens", "src");
|
|
248
|
+
const isRemote = !!componentsJson.registrySource;
|
|
249
|
+
if (isRemote) {
|
|
250
|
+
// Remote mode: copy and normalize theme file
|
|
251
|
+
const themesSrc = path.join(tokensSrc, "themes");
|
|
252
|
+
const themesDest = path.join(rootDir, "src", "styles", "tokens", "themes");
|
|
253
|
+
// Remove old theme file
|
|
254
|
+
const oldThemeFile = path.join(themesDest, `${currentTheme}.css`);
|
|
255
|
+
if (fs.existsSync(oldThemeFile)) {
|
|
256
|
+
fs.unlinkSync(oldThemeFile);
|
|
257
|
+
}
|
|
258
|
+
// Copy and normalize new theme
|
|
259
|
+
const newThemeSrc = path.join(themesSrc, `${newTheme}.css`);
|
|
260
|
+
if (fs.existsSync(newThemeSrc)) {
|
|
261
|
+
fs.mkdirSync(themesDest, { recursive: true });
|
|
262
|
+
const rawCss = fs.readFileSync(newThemeSrc, "utf-8");
|
|
263
|
+
const normalizedCss = normalizeThemeCss(rawCss, newTheme);
|
|
264
|
+
fs.writeFileSync(path.join(themesDest, `${newTheme}.css`), normalizedCss);
|
|
265
|
+
}
|
|
266
|
+
// Regenerate index.css
|
|
267
|
+
const font = componentsJson.font ?? { body: "outfit", heading: "outfit" };
|
|
268
|
+
const radius = componentsJson.radius ?? 0.5;
|
|
269
|
+
const cssPath = path.join(rootDir, "src", "index.css");
|
|
270
|
+
fs.writeFileSync(cssPath, getLocalTailwindCssTemplate(newTheme, font.body, font.heading, radius));
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// Local mode: just regenerate index.css with new import
|
|
274
|
+
const font = componentsJson.font ?? { body: "outfit", heading: "outfit" };
|
|
275
|
+
const radius = componentsJson.radius ?? 0.5;
|
|
276
|
+
const cssPath = path.join(rootDir, "src", "index.css");
|
|
277
|
+
fs.writeFileSync(cssPath, getLegacyTailwindCssTemplate(newTheme, font.body, font.heading, radius));
|
|
278
|
+
}
|
|
279
|
+
// Update components.json
|
|
280
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
281
|
+
componentsJson.theme = newTheme;
|
|
282
|
+
const componentsJsonPath = path.join(rootDir, "components.json");
|
|
283
|
+
fs.writeFileSync(componentsJsonPath, JSON.stringify(componentsJson, null, 2) + "\n");
|
|
284
|
+
spinner.succeed(`Theme switched to "${newTheme}"`);
|
|
285
|
+
console.log(chalk.green("\nUpdated files:"));
|
|
286
|
+
console.log(chalk.dim(" - components.json"));
|
|
287
|
+
console.log(chalk.dim(" - src/index.css"));
|
|
288
|
+
if (componentsJson.registrySource) {
|
|
289
|
+
console.log(chalk.dim(` - src/styles/tokens/themes/${newTheme}.css`));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
spinner.fail("Failed to switch theme.");
|
|
294
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
295
|
+
console.error(chalk.red(`\nError: ${message}`));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async function installAll() {
|
|
299
|
+
const rootDir = process.cwd();
|
|
300
|
+
const componentsJson = readComponentsJson(rootDir);
|
|
301
|
+
if (!componentsJson) {
|
|
302
|
+
console.log(chalk.red("No components.json found. Run `inai-ui init` first to initialize your project."));
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
const registryDir = resolveRegistryDir(rootDir);
|
|
306
|
+
const registryPath = path.join(registryDir, "registry.json");
|
|
307
|
+
const registry = readRegistryJson(registryPath);
|
|
308
|
+
if (!registry) {
|
|
309
|
+
console.log(chalk.red("Registry not found. Ensure your project is initialized correctly."));
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
312
|
+
const allItems = [
|
|
313
|
+
...registry.components,
|
|
314
|
+
...registry.blocks,
|
|
315
|
+
...registry.templates,
|
|
316
|
+
];
|
|
317
|
+
console.log(chalk.bold(`\nInstalling all ${allItems.length} components, blocks, and templates...\n`));
|
|
318
|
+
const installed = componentsJson.installedComponents ?? [];
|
|
319
|
+
const installedNames = new Set(installed.map((c) => c.name));
|
|
320
|
+
const allNpmDeps = new Set();
|
|
321
|
+
let addedCount = 0;
|
|
322
|
+
let updatedCount = 0;
|
|
323
|
+
for (const item of allItems) {
|
|
324
|
+
const isInstalled = installedNames.has(item.name);
|
|
325
|
+
const action = isInstalled ? "Updating" : "Adding";
|
|
326
|
+
const prefix = item.type === "block" ? "block/" : item.type === "template" ? "template/" : "";
|
|
327
|
+
const spinner = ora(`${action} "${prefix}${item.name}"...`).start();
|
|
328
|
+
try {
|
|
329
|
+
const spec = prefix ? `${prefix}${item.name}` : item.name;
|
|
330
|
+
const result = await runAdd(spec, rootDir);
|
|
331
|
+
if (!result.added) {
|
|
332
|
+
spinner.fail(result.message);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (isInstalled) {
|
|
336
|
+
spinner.succeed(`Updated "${prefix}${item.name}"`);
|
|
337
|
+
updatedCount++;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
spinner.succeed(`Added "${prefix}${item.name}"`);
|
|
341
|
+
addedCount++;
|
|
342
|
+
}
|
|
343
|
+
for (const dep of result.npmDeps) {
|
|
344
|
+
allNpmDeps.add(dep);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
spinner.fail(`Failed to process "${prefix}${item.name}"`);
|
|
349
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
350
|
+
console.error(chalk.red(` Error: ${message}`));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Summary
|
|
354
|
+
console.log(chalk.bold("\nSummary:"));
|
|
355
|
+
if (addedCount > 0) {
|
|
356
|
+
console.log(chalk.green(` ${addedCount} component${addedCount > 1 ? "s" : ""} added`));
|
|
357
|
+
}
|
|
358
|
+
if (updatedCount > 0) {
|
|
359
|
+
console.log(chalk.blue(` ${updatedCount} component${updatedCount > 1 ? "s" : ""} updated`));
|
|
360
|
+
}
|
|
361
|
+
if (allNpmDeps.size > 0) {
|
|
362
|
+
console.log(chalk.yellow("\nInstall required npm dependencies:"));
|
|
363
|
+
console.log(chalk.cyan(` pnpm add ${[...allNpmDeps].join(" ")}`));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
193
366
|
async function interactiveAdd() {
|
|
194
367
|
const rootDir = process.cwd();
|
|
195
368
|
const componentsJson = readComponentsJson(rootDir);
|
|
@@ -204,6 +377,26 @@ async function interactiveAdd() {
|
|
|
204
377
|
console.log(chalk.red("Registry not found. Ensure your project is initialized correctly."));
|
|
205
378
|
process.exit(1);
|
|
206
379
|
}
|
|
380
|
+
// First: ask what the user wants to do
|
|
381
|
+
console.log(chalk.bold("\nInAI UI - Interactive Menu\n"));
|
|
382
|
+
const actionResponse = await prompts({
|
|
383
|
+
type: "select",
|
|
384
|
+
name: "action",
|
|
385
|
+
message: "What would you like to do?",
|
|
386
|
+
choices: [
|
|
387
|
+
{ title: "Add components", value: "components", description: "Browse and install components, blocks, or templates" },
|
|
388
|
+
{ title: "Change theme", value: "theme", description: `Current: ${componentsJson.theme ?? "monday"}` },
|
|
389
|
+
],
|
|
390
|
+
});
|
|
391
|
+
if (!actionResponse.action) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
// Theme change flow
|
|
395
|
+
if (actionResponse.action === "theme") {
|
|
396
|
+
await changeTheme(rootDir, registryDir);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
// Component picker flow
|
|
207
400
|
const allItems = [
|
|
208
401
|
...registry.components,
|
|
209
402
|
...registry.blocks,
|
|
@@ -227,8 +420,7 @@ async function interactiveAdd() {
|
|
|
227
420
|
selected: false,
|
|
228
421
|
};
|
|
229
422
|
});
|
|
230
|
-
console.log(chalk.
|
|
231
|
-
console.log(chalk.dim("Select components to add or update. Already installed components will be updated.\n"));
|
|
423
|
+
console.log(chalk.dim("\nSelect components to add or update. Already installed components will be updated.\n"));
|
|
232
424
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
233
425
|
const response = await prompts({
|
|
234
426
|
type: "multiselect",
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -259,6 +259,13 @@ export declare function buildComponentsJson(config: InitConfig, repoUrl?: string
|
|
|
259
259
|
export declare function getCnTemplate(): string;
|
|
260
260
|
export declare function getLocalTailwindCssTemplate(theme: Theme, fontBody: FontPreset, fontHeading: FontPreset, radius: number): string;
|
|
261
261
|
export declare function getLegacyTailwindCssTemplate(theme: Theme, fontBody: FontPreset, fontHeading: FontPreset, radius: number): string;
|
|
262
|
+
/**
|
|
263
|
+
* Strip the `[data-theme="<name>"]` selector from theme CSS so it applies
|
|
264
|
+
* directly on `:root` / `.dark`. This is used when copying a single theme
|
|
265
|
+
* for a project — the theme becomes the default without needing a
|
|
266
|
+
* `data-theme` attribute on the HTML element.
|
|
267
|
+
*/
|
|
268
|
+
export declare function normalizeThemeCss(css: string, theme: string): string;
|
|
262
269
|
export declare function runInit(config: InitConfig, targetDir: string, repoUrl?: string): Promise<{
|
|
263
270
|
success: boolean;
|
|
264
271
|
filesCreated: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,gBAAgB,yMAeZ,CAAC;AACX,KAAK,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DR,CAAC;AACX,KAAK,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAUxD,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;IACrB,WAAW,EAAE,UAAU,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU,CAAC;QACjB,OAAO,EAAE,UAAU,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAgBD,wBAAsB,gBAAgB,CACpC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA8F5B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,cAAc,CAkChB;AAED,wBAAgB,aAAa,IAAI,MAAM,CAQtC;AAOD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAa/H;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAahI;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -264,6 +264,24 @@ export function getLegacyTailwindCssTemplate(theme, fontBody, fontHeading, radiu
|
|
|
264
264
|
}
|
|
265
265
|
`;
|
|
266
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Strip the `[data-theme="<name>"]` selector from theme CSS so it applies
|
|
269
|
+
* directly on `:root` / `.dark`. This is used when copying a single theme
|
|
270
|
+
* for a project — the theme becomes the default without needing a
|
|
271
|
+
* `data-theme` attribute on the HTML element.
|
|
272
|
+
*/
|
|
273
|
+
export function normalizeThemeCss(css, theme) {
|
|
274
|
+
// Replace `:root[data-theme="<name>"],\n[data-theme="<name>"]` → `:root`
|
|
275
|
+
const rootSelector = new RegExp(`:root\\[data-theme="${theme}"\\],?\\s*\\n?\\[data-theme="${theme}"\\]`, "g");
|
|
276
|
+
let normalized = css.replace(rootSelector, ":root");
|
|
277
|
+
// Replace `.dark[data-theme="<name>"],\n[data-theme="<name>"].dark` → `.dark`
|
|
278
|
+
const darkSelector = new RegExp(`\\.dark\\[data-theme="${theme}"\\],?\\s*\\n?\\[data-theme="${theme}"\\]\\.dark`, "g");
|
|
279
|
+
normalized = normalized.replace(darkSelector, ".dark");
|
|
280
|
+
// Catch any remaining standalone `[data-theme="<name>"]` selectors
|
|
281
|
+
const standaloneSelector = new RegExp(`\\[data-theme="${theme}"\\]`, "g");
|
|
282
|
+
normalized = normalized.replace(standaloneSelector, "");
|
|
283
|
+
return normalized;
|
|
284
|
+
}
|
|
267
285
|
function copyDirRecursive(src, dest) {
|
|
268
286
|
const copied = [];
|
|
269
287
|
if (!fs.existsSync(src))
|
|
@@ -297,7 +315,7 @@ function copyTokensToProject(registryDir, targetDir, theme) {
|
|
|
297
315
|
copied.push(`src/styles/tokens/${file}`);
|
|
298
316
|
}
|
|
299
317
|
}
|
|
300
|
-
// Copy selected theme
|
|
318
|
+
// Copy selected theme (normalized so it applies without data-theme attribute)
|
|
301
319
|
const themesSrc = path.join(tokensSrc, "themes");
|
|
302
320
|
const themesDest = path.join(tokensDest, "themes");
|
|
303
321
|
if (fs.existsSync(themesSrc)) {
|
|
@@ -305,7 +323,9 @@ function copyTokensToProject(registryDir, targetDir, theme) {
|
|
|
305
323
|
const themeFile = `${theme}.css`;
|
|
306
324
|
const themeSrc = path.join(themesSrc, themeFile);
|
|
307
325
|
if (fs.existsSync(themeSrc)) {
|
|
308
|
-
fs.
|
|
326
|
+
const rawCss = fs.readFileSync(themeSrc, "utf-8");
|
|
327
|
+
const normalizedCss = normalizeThemeCss(rawCss, theme);
|
|
328
|
+
fs.writeFileSync(path.join(themesDest, themeFile), normalizedCss);
|
|
309
329
|
copied.push(`src/styles/tokens/themes/${themeFile}`);
|
|
310
330
|
}
|
|
311
331
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAO7E;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAM1E;AAED,wBAAgB,iBAAiB,CAC/B,mBAAmB,EAAE,kBAAkB,EAAE,EACzC,eAAe,EAAE,MAAM,GACtB,MAAM,CAuBR;AAOD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBhE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAcnD"}
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAO7E;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAM1E;AAED,wBAAgB,iBAAiB,CAC/B,mBAAmB,EAAE,kBAAkB,EAAE,EACzC,eAAe,EAAE,MAAM,GACtB,MAAM,CAuBR;AAOD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBhE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAcnD"}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ const program = new Command();
|
|
|
12
12
|
program
|
|
13
13
|
.name("inai-ui")
|
|
14
14
|
.description("CLI for InAI UI component library")
|
|
15
|
-
.version("0.1.
|
|
15
|
+
.version("0.1.6");
|
|
16
16
|
program
|
|
17
17
|
.command("init [repo-url]")
|
|
18
18
|
.description("Initialize InAI UI in your project. Optionally pass a Git repo URL to fetch components remotely.")
|
|
@@ -20,7 +20,8 @@ program
|
|
|
20
20
|
program
|
|
21
21
|
.command("add [component]")
|
|
22
22
|
.description("Add a component to your project. Without arguments, opens an interactive picker to select multiple components.")
|
|
23
|
-
.
|
|
23
|
+
.option("-a, --all", "Install all available components, blocks, and templates")
|
|
24
|
+
.action((component, options) => addCommand(component, options));
|
|
24
25
|
program
|
|
25
26
|
.command("sync")
|
|
26
27
|
.description("Update the local registry cache from the remote repository")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inai-react-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "CLI for InAI UI component library — install components from a private registry into your React project",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"chalk": "^5.6.2",
|
|
36
36
|
"commander": "^14.0.3",
|
|
37
|
-
"fast-glob": "^3.3.3",
|
|
38
37
|
"ora": "^9.3.0",
|
|
39
38
|
"prompts": "^2.4.2"
|
|
40
39
|
},
|