7onic 0.1.10 → 0.1.12

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.
Files changed (3) hide show
  1. package/dist/index.js +233 -59
  2. package/llms.txt +1 -1
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -155,8 +155,8 @@ var require_picocolors = __commonJS({
155
155
  });
156
156
 
157
157
  // cli/src/commands/init.ts
158
- var import_node_fs4 = __toESM(require("node:fs"));
159
- var import_node_path4 = __toESM(require("node:path"));
158
+ var import_node_fs5 = __toESM(require("node:fs"));
159
+ var import_node_path5 = __toESM(require("node:path"));
160
160
 
161
161
  // node_modules/@clack/core/dist/index.mjs
162
162
  var import_node_util = require("node:util");
@@ -1227,6 +1227,127 @@ var logger = {
1227
1227
  }
1228
1228
  };
1229
1229
 
1230
+ // cli/src/utils/vite-template-cleanup.ts
1231
+ var import_node_fs4 = __toESM(require("node:fs"));
1232
+ var import_node_path4 = __toESM(require("node:path"));
1233
+ var VITE_INDEX_CSS_PATTERNS = [
1234
+ {
1235
+ name: ":root (font/color/bg defaults)",
1236
+ pattern: /:root\s*\{[^}]*font-family:\s*system-ui,\s*Avenir,\s*Helvetica,\s*Arial,\s*sans-serif;[^}]*color-scheme:\s*light dark;[^}]*background-color:\s*#242424;[^}]*\}\s*/m
1237
+ },
1238
+ {
1239
+ name: "a (link colors)",
1240
+ pattern: /a\s*\{\s*font-weight:\s*500;\s*color:\s*#646cff;\s*text-decoration:\s*inherit;\s*\}\s*/m
1241
+ },
1242
+ {
1243
+ name: "a:hover",
1244
+ pattern: /a:hover\s*\{\s*color:\s*#535bf2;\s*\}\s*/m
1245
+ },
1246
+ {
1247
+ name: "body (flex centering)",
1248
+ pattern: /body\s*\{\s*margin:\s*0;\s*display:\s*flex;\s*place-items:\s*center;\s*min-width:\s*320px;\s*min-height:\s*100vh;\s*\}\s*/m
1249
+ },
1250
+ {
1251
+ name: "h1 (huge size)",
1252
+ pattern: /h1\s*\{\s*font-size:\s*3\.2em;\s*line-height:\s*1\.1;\s*\}\s*/m
1253
+ },
1254
+ {
1255
+ name: "button (default styles)",
1256
+ pattern: /button\s*\{\s*border-radius:\s*8px;\s*border:\s*1px solid transparent;\s*padding:\s*0\.6em 1\.2em;[^}]*background-color:\s*#1a1a1a;[^}]*\}\s*/m
1257
+ },
1258
+ {
1259
+ name: "button:hover",
1260
+ pattern: /button:hover\s*\{\s*border-color:\s*#646cff;\s*\}\s*/m
1261
+ },
1262
+ {
1263
+ name: "button:focus",
1264
+ pattern: /button:focus,\s*button:focus-visible\s*\{\s*outline:\s*4px auto -webkit-focus-ring-color;\s*\}\s*/m
1265
+ },
1266
+ {
1267
+ name: "@media light mode overrides",
1268
+ pattern: /@media\s*\(prefers-color-scheme:\s*light\)\s*\{\s*:root\s*\{\s*color:\s*#213547;\s*background-color:\s*#ffffff;\s*\}[^@]*?button\s*\{\s*background-color:\s*#f9f9f9;\s*\}\s*\}\s*/m
1269
+ }
1270
+ ];
1271
+ var VITE_APP_CSS_PATTERNS = [
1272
+ {
1273
+ name: "#root (max-width + text-align:center)",
1274
+ pattern: /#root\s*\{\s*max-width:\s*1280px;\s*margin:\s*0 auto;\s*padding:\s*2rem;\s*text-align:\s*center;\s*\}\s*/m
1275
+ },
1276
+ {
1277
+ name: ".logo (spin animation set)",
1278
+ pattern: /\.logo\s*\{[^}]*height:\s*6em;[^}]*padding:\s*1\.5em;[^}]*will-change:\s*filter;[^}]*\}\s*/m
1279
+ },
1280
+ {
1281
+ name: ".logo:hover",
1282
+ pattern: /\.logo:hover\s*\{\s*filter:\s*drop-shadow\(0 0 2em #646cffaa\);\s*\}\s*/m
1283
+ },
1284
+ {
1285
+ name: ".logo.react:hover",
1286
+ pattern: /\.logo\.react:hover\s*\{\s*filter:\s*drop-shadow\(0 0 2em #61dafbaa\);\s*\}\s*/m
1287
+ },
1288
+ {
1289
+ name: "@keyframes logo-spin",
1290
+ pattern: /@keyframes\s+logo-spin\s*\{\s*from\s*\{\s*transform:\s*rotate\(0deg\);\s*\}\s*to\s*\{\s*transform:\s*rotate\(360deg\);\s*\}\s*\}\s*/m
1291
+ },
1292
+ {
1293
+ name: "@media logo-spin animation",
1294
+ pattern: /@media\s*\(prefers-reduced-motion:\s*no-preference\)\s*\{\s*a:nth-of-type\(2\)\s*\.logo\s*\{\s*animation:\s*logo-spin[^}]*\}\s*\}\s*/m
1295
+ },
1296
+ {
1297
+ name: ".card",
1298
+ pattern: /\.card\s*\{\s*padding:\s*2em;\s*\}\s*/m
1299
+ },
1300
+ {
1301
+ name: ".read-the-docs",
1302
+ pattern: /\.read-the-docs\s*\{\s*color:\s*#888;\s*\}\s*/m
1303
+ }
1304
+ ];
1305
+ function scanFile(fullPath, relPath, patterns) {
1306
+ if (!import_node_fs4.default.existsSync(fullPath)) return null;
1307
+ const originalContent = import_node_fs4.default.readFileSync(fullPath, "utf-8");
1308
+ let cleanedContent = originalContent;
1309
+ const matches = [];
1310
+ for (const { name, pattern } of patterns) {
1311
+ const match = cleanedContent.match(pattern);
1312
+ if (match && match.index !== void 0) {
1313
+ const linesBefore = cleanedContent.slice(0, match.index).split("\n").length;
1314
+ const linesInMatch = match[0].split("\n").length;
1315
+ matches.push({
1316
+ file: relPath,
1317
+ name,
1318
+ startLine: linesBefore,
1319
+ endLine: linesBefore + linesInMatch - 1,
1320
+ preview: match[0].split("\n")[0].trim().slice(0, 60)
1321
+ });
1322
+ cleanedContent = cleanedContent.slice(0, match.index) + cleanedContent.slice(match.index + match[0].length);
1323
+ }
1324
+ }
1325
+ if (matches.length === 0) return null;
1326
+ cleanedContent = cleanedContent.replace(/\n{3,}/g, "\n\n").replace(/^\s+\n/gm, "\n").trimStart();
1327
+ return {
1328
+ file: relPath,
1329
+ fullPath,
1330
+ originalContent,
1331
+ cleanedContent,
1332
+ matches
1333
+ };
1334
+ }
1335
+ function scanViteTemplate(projectRoot) {
1336
+ const results = [];
1337
+ const indexCssPath = import_node_path4.default.join(projectRoot, "src/index.css");
1338
+ const indexResult = scanFile(indexCssPath, "src/index.css", VITE_INDEX_CSS_PATTERNS);
1339
+ if (indexResult) results.push(indexResult);
1340
+ const appCssPath = import_node_path4.default.join(projectRoot, "src/App.css");
1341
+ const appResult = scanFile(appCssPath, "src/App.css", VITE_APP_CSS_PATTERNS);
1342
+ if (appResult) results.push(appResult);
1343
+ return results;
1344
+ }
1345
+ function applyCleanup(result) {
1346
+ const backupPath = result.fullPath + ".bak";
1347
+ import_node_fs4.default.writeFileSync(backupPath, result.originalContent, "utf-8");
1348
+ import_node_fs4.default.writeFileSync(result.fullPath, result.cleanedContent, "utf-8");
1349
+ }
1350
+
1230
1351
  // cli/src/commands/init.ts
1231
1352
  var CSS_CANDIDATES = [
1232
1353
  "src/app/globals.css",
@@ -1281,7 +1402,7 @@ async function init(args) {
1281
1402
  process.exit(0);
1282
1403
  }
1283
1404
  }
1284
- const hasTsConfig = import_node_fs4.default.existsSync(import_node_path4.default.join(projectRoot, "tsconfig.json"));
1405
+ const hasTsConfig = import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, "tsconfig.json"));
1285
1406
  if (!hasTsConfig) {
1286
1407
  pt("tsconfig.json not found. 7onic requires TypeScript.");
1287
1408
  process.exit(1);
@@ -1292,7 +1413,7 @@ async function init(args) {
1292
1413
  const TSCONFIG_CANDIDATES = ["tsconfig.json", "tsconfig.app.json"];
1293
1414
  for (const tc of TSCONFIG_CANDIDATES) {
1294
1415
  try {
1295
- const raw = import_node_fs4.default.readFileSync(import_node_path4.default.join(projectRoot, tc), "utf-8");
1416
+ const raw = import_node_fs5.default.readFileSync(import_node_path5.default.join(projectRoot, tc), "utf-8");
1296
1417
  if (raw.includes('"@/')) {
1297
1418
  hasPathAlias = true;
1298
1419
  break;
@@ -1300,12 +1421,12 @@ async function init(args) {
1300
1421
  } catch {
1301
1422
  }
1302
1423
  }
1303
- const viteConfigPath = import_node_fs4.default.existsSync(import_node_path4.default.join(projectRoot, "vite.config.ts")) ? import_node_path4.default.join(projectRoot, "vite.config.ts") : import_node_fs4.default.existsSync(import_node_path4.default.join(projectRoot, "vite.config.js")) ? import_node_path4.default.join(projectRoot, "vite.config.js") : null;
1304
- const isViteProject = import_node_fs4.default.existsSync(import_node_path4.default.join(projectRoot, "tsconfig.app.json")) && viteConfigPath !== null;
1424
+ const viteConfigPath = import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, "vite.config.ts")) ? import_node_path5.default.join(projectRoot, "vite.config.ts") : import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, "vite.config.js")) ? import_node_path5.default.join(projectRoot, "vite.config.js") : null;
1425
+ const isViteProject = import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, "tsconfig.app.json")) && viteConfigPath !== null;
1305
1426
  let needsTypesNode = false;
1306
1427
  if (!hasPathAlias) {
1307
1428
  if (isViteProject) {
1308
- const tscPatch = patchTsconfigApp(import_node_path4.default.join(projectRoot, "tsconfig.app.json"));
1429
+ const tscPatch = patchTsconfigApp(import_node_path5.default.join(projectRoot, "tsconfig.app.json"));
1309
1430
  const vitePatch = patchViteConfig(viteConfigPath);
1310
1431
  if (vitePatch) needsTypesNode = true;
1311
1432
  if (tscPatch || vitePatch) {
@@ -1322,7 +1443,7 @@ async function init(args) {
1322
1443
  }
1323
1444
  }
1324
1445
  try {
1325
- const pkgJson = JSON.parse(import_node_fs4.default.readFileSync(import_node_path4.default.join(projectRoot, "package.json"), "utf-8"));
1446
+ const pkgJson = JSON.parse(import_node_fs5.default.readFileSync(import_node_path5.default.join(projectRoot, "package.json"), "utf-8"));
1326
1447
  const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
1327
1448
  if (allDeps["@7onic-ui/react"]) {
1328
1449
  O2.info(
@@ -1331,7 +1452,7 @@ async function init(args) {
1331
1452
  }
1332
1453
  } catch {
1333
1454
  }
1334
- const cssDefault = CSS_CANDIDATES.find((c2) => import_node_fs4.default.existsSync(import_node_path4.default.join(projectRoot, c2))) || "src/app/globals.css";
1455
+ const cssDefault = CSS_CANDIDATES.find((c2) => import_node_fs5.default.existsSync(import_node_path5.default.join(projectRoot, c2))) || "src/app/globals.css";
1335
1456
  let config;
1336
1457
  if (flagYes) {
1337
1458
  const resolvedVersion = forcedTailwindVersion ?? tw.version;
@@ -1392,41 +1513,74 @@ async function init(args) {
1392
1513
  logger.error(String(err));
1393
1514
  process.exit(1);
1394
1515
  }
1395
- const cssFullPath = import_node_path4.default.join(projectRoot, config.cssPath);
1396
- if (!import_node_fs4.default.existsSync(cssFullPath)) {
1397
- const cssDir = import_node_path4.default.dirname(cssFullPath);
1398
- if (!import_node_fs4.default.existsSync(cssDir)) {
1399
- import_node_fs4.default.mkdirSync(cssDir, { recursive: true });
1516
+ const cssFullPath = import_node_path5.default.join(projectRoot, config.cssPath);
1517
+ if (!import_node_fs5.default.existsSync(cssFullPath)) {
1518
+ const cssDir = import_node_path5.default.dirname(cssFullPath);
1519
+ if (!import_node_fs5.default.existsSync(cssDir)) {
1520
+ import_node_fs5.default.mkdirSync(cssDir, { recursive: true });
1400
1521
  }
1401
1522
  const cssImports = tailwindVersion === 3 ? CSS_V3_IMPORTS : CSS_V4_IMPORTS;
1402
- import_node_fs4.default.writeFileSync(cssFullPath, cssImports, "utf-8");
1523
+ import_node_fs5.default.writeFileSync(cssFullPath, cssImports, "utf-8");
1403
1524
  O2.success(`Created ${config.cssPath} with token imports`);
1404
1525
  } else {
1405
- const cssContent = import_node_fs4.default.readFileSync(cssFullPath, "utf-8");
1526
+ const cssContent = import_node_fs5.default.readFileSync(cssFullPath, "utf-8");
1406
1527
  if (!cssContent.includes("@7onic-ui/tokens")) {
1407
1528
  if (tailwindVersion === 4) {
1408
1529
  const twMatch = cssContent.match(/@import\s+["']tailwindcss["'].*\n/);
1409
1530
  if (twMatch) {
1410
1531
  const insertAt = twMatch.index + twMatch[0].length;
1411
1532
  const updated = cssContent.slice(0, insertAt) + CSS_V4_TOKEN_ONLY + cssContent.slice(insertAt);
1412
- import_node_fs4.default.writeFileSync(cssFullPath, updated, "utf-8");
1533
+ import_node_fs5.default.writeFileSync(cssFullPath, updated, "utf-8");
1413
1534
  } else {
1414
- import_node_fs4.default.writeFileSync(cssFullPath, CSS_V4_IMPORTS + "\n" + cssContent, "utf-8");
1535
+ import_node_fs5.default.writeFileSync(cssFullPath, CSS_V4_IMPORTS + "\n" + cssContent, "utf-8");
1415
1536
  }
1416
1537
  } else {
1417
1538
  const hasTailwindDirectives = /@tailwind\s+(base|components|utilities)/.test(cssContent);
1418
1539
  const v3Imports = hasTailwindDirectives ? CSS_V3_TOKEN_ONLY : CSS_V3_IMPORTS;
1419
- import_node_fs4.default.writeFileSync(cssFullPath, v3Imports + "\n" + cssContent, "utf-8");
1540
+ import_node_fs5.default.writeFileSync(cssFullPath, v3Imports + "\n" + cssContent, "utf-8");
1420
1541
  }
1421
1542
  O2.success(`Added token imports to ${config.cssPath}`);
1422
1543
  } else {
1423
1544
  O2.info(`Token imports already present in ${config.cssPath}`);
1424
1545
  }
1425
1546
  }
1547
+ if (isViteProject) {
1548
+ const scanResults = scanViteTemplate(projectRoot);
1549
+ if (scanResults.length > 0) {
1550
+ const totalMatches = scanResults.reduce((sum, r) => sum + r.matches.length, 0);
1551
+ const fileList = scanResults.map((r) => {
1552
+ const blockLines = r.matches.map((m) => ` \u2022 ${m.name} (L${m.startLine}\u2013${m.endLine})`).join("\n");
1553
+ return ` ${import_picocolors2.default.bold(r.file)}
1554
+ ${blockLines}`;
1555
+ }).join("\n");
1556
+ wt(
1557
+ `Detected ${totalMatches} Vite template block${totalMatches === 1 ? "" : "s"} that override 7onic utilities:
1558
+
1559
+ ` + fileList + "\n\n" + import_picocolors2.default.dim(" These blocks are from `npm create vite` boilerplate.\n") + import_picocolors2.default.dim(" A .bak backup will be created before changes."),
1560
+ "Vite Template Cleanup"
1561
+ );
1562
+ const approve = flagYes ? true : await ot2({
1563
+ message: "Remove Vite template boilerplate?",
1564
+ initialValue: true
1565
+ });
1566
+ if (q(approve)) {
1567
+ pt("Init cancelled.");
1568
+ process.exit(0);
1569
+ }
1570
+ if (approve) {
1571
+ for (const result of scanResults) {
1572
+ applyCleanup(result);
1573
+ O2.success(`Cleaned ${result.file} (${result.matches.length} block${result.matches.length === 1 ? "" : "s"}) \u2014 backup at ${result.file}.bak`);
1574
+ }
1575
+ } else {
1576
+ O2.info("Kept Vite template blocks. You may see style conflicts.");
1577
+ }
1578
+ }
1579
+ }
1426
1580
  if (tailwindVersion === 3 && tw.configPath) {
1427
- const configFullPath = import_node_path4.default.join(projectRoot, tw.configPath);
1428
- if (import_node_fs4.default.existsSync(configFullPath)) {
1429
- const configContent = import_node_fs4.default.readFileSync(configFullPath, "utf-8");
1581
+ const configFullPath = import_node_path5.default.join(projectRoot, tw.configPath);
1582
+ if (import_node_fs5.default.existsSync(configFullPath)) {
1583
+ const configContent = import_node_fs5.default.readFileSync(configFullPath, "utf-8");
1430
1584
  if (!configContent.includes("@7onic-ui/tokens/tailwind/v3-preset")) {
1431
1585
  wt(
1432
1586
  `Add the 7onic preset to your ${tw.configPath}:
@@ -1445,18 +1599,18 @@ async function init(args) {
1445
1599
  const utilsPath = resolveAliasPath(projectRoot, config.utilsAlias);
1446
1600
  if (utilsPath) {
1447
1601
  const utilsFullPath = utilsPath + ".ts";
1448
- if (!import_node_fs4.default.existsSync(utilsFullPath)) {
1449
- const utilsDir = import_node_path4.default.dirname(utilsFullPath);
1450
- if (!import_node_fs4.default.existsSync(utilsDir)) {
1451
- import_node_fs4.default.mkdirSync(utilsDir, { recursive: true });
1602
+ if (!import_node_fs5.default.existsSync(utilsFullPath)) {
1603
+ const utilsDir = import_node_path5.default.dirname(utilsFullPath);
1604
+ if (!import_node_fs5.default.existsSync(utilsDir)) {
1605
+ import_node_fs5.default.mkdirSync(utilsDir, { recursive: true });
1452
1606
  }
1453
- import_node_fs4.default.writeFileSync(utilsFullPath, CN_UTIL, "utf-8");
1454
- O2.success(`Created ${import_node_path4.default.relative(projectRoot, utilsFullPath)}`);
1607
+ import_node_fs5.default.writeFileSync(utilsFullPath, CN_UTIL, "utf-8");
1608
+ O2.success(`Created ${import_node_path5.default.relative(projectRoot, utilsFullPath)}`);
1455
1609
  } else {
1456
- const utilsContent = import_node_fs4.default.readFileSync(utilsFullPath, "utf-8");
1610
+ const utilsContent = import_node_fs5.default.readFileSync(utilsFullPath, "utf-8");
1457
1611
  if (!utilsContent.includes("tailwind-merge")) {
1458
1612
  O2.warn(
1459
- `${import_node_path4.default.relative(projectRoot, utilsFullPath)} exists but does not import tailwind-merge.
1613
+ `${import_node_path5.default.relative(projectRoot, utilsFullPath)} exists but does not import tailwind-merge.
1460
1614
  7onic components require cn() with tailwind-merge.`
1461
1615
  );
1462
1616
  } else {
@@ -1482,14 +1636,14 @@ async function init(args) {
1482
1636
  }
1483
1637
  function patchTsconfigApp(tsconfigPath) {
1484
1638
  try {
1485
- const raw = import_node_fs4.default.readFileSync(tsconfigPath, "utf-8");
1639
+ const raw = import_node_fs5.default.readFileSync(tsconfigPath, "utf-8");
1486
1640
  const clean = raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/,(\s*[}\]])/g, "$1");
1487
1641
  const tc = JSON.parse(clean);
1488
1642
  if (!tc.compilerOptions) tc.compilerOptions = {};
1489
1643
  const existingPaths = tc.compilerOptions.paths ?? {};
1490
1644
  if (existingPaths["@/*"]) return false;
1491
1645
  tc.compilerOptions.paths = { "@/*": ["./src/*"], ...existingPaths };
1492
- import_node_fs4.default.writeFileSync(tsconfigPath, JSON.stringify(tc, null, 2), "utf-8");
1646
+ import_node_fs5.default.writeFileSync(tsconfigPath, JSON.stringify(tc, null, 2), "utf-8");
1493
1647
  return true;
1494
1648
  } catch {
1495
1649
  return false;
@@ -1497,7 +1651,7 @@ function patchTsconfigApp(tsconfigPath) {
1497
1651
  }
1498
1652
  function patchViteConfig(viteConfigPath) {
1499
1653
  try {
1500
- let content = import_node_fs4.default.readFileSync(viteConfigPath, "utf-8");
1654
+ let content = import_node_fs5.default.readFileSync(viteConfigPath, "utf-8");
1501
1655
  if (content.includes("'@'") || content.includes('"@"') || content.includes("'@/*'") || content.includes('"@/*"') || content.includes("resolve:")) return false;
1502
1656
  if (!content.includes("import path from 'path'") && !content.includes('import path from "path"')) {
1503
1657
  const importMatches = [...content.matchAll(/^import .+$/gm)];
@@ -1516,7 +1670,7 @@ function patchViteConfig(viteConfigPath) {
1516
1670
  alias: { '@': path.resolve(__dirname, './src') },
1517
1671
  },`;
1518
1672
  content = content.slice(0, lastClose) + resolveBlock + content.slice(lastClose);
1519
- import_node_fs4.default.writeFileSync(viteConfigPath, content, "utf-8");
1673
+ import_node_fs5.default.writeFileSync(viteConfigPath, content, "utf-8");
1520
1674
  return true;
1521
1675
  } catch {
1522
1676
  return false;
@@ -1526,17 +1680,17 @@ function resolveAliasPath(projectRoot, alias) {
1526
1680
  if (!alias.startsWith("@/")) return null;
1527
1681
  const relative = alias.slice(2);
1528
1682
  for (const srcDir of ["src", "app", "."]) {
1529
- const candidate = import_node_path4.default.join(projectRoot, srcDir, relative);
1530
- if (import_node_fs4.default.existsSync(import_node_path4.default.dirname(candidate)) || srcDir === "src") {
1531
- return import_node_path4.default.join(projectRoot, srcDir, relative);
1683
+ const candidate = import_node_path5.default.join(projectRoot, srcDir, relative);
1684
+ if (import_node_fs5.default.existsSync(import_node_path5.default.dirname(candidate)) || srcDir === "src") {
1685
+ return import_node_path5.default.join(projectRoot, srcDir, relative);
1532
1686
  }
1533
1687
  }
1534
- return import_node_path4.default.join(projectRoot, "src", relative);
1688
+ return import_node_path5.default.join(projectRoot, "src", relative);
1535
1689
  }
1536
1690
 
1537
1691
  // cli/src/commands/add.ts
1538
- var import_node_fs5 = __toESM(require("node:fs"));
1539
- var import_node_path5 = __toESM(require("node:path"));
1692
+ var import_node_fs6 = __toESM(require("node:fs"));
1693
+ var import_node_path6 = __toESM(require("node:path"));
1540
1694
  var import_picocolors3 = __toESM(require_picocolors());
1541
1695
 
1542
1696
  // cli/src/utils/rewrite-imports.ts
@@ -5092,7 +5246,7 @@ const bubbleRadiusSymMap: Record<ChatMessageRadius, string> = {
5092
5246
 
5093
5247
  function getBubbleColors(color: ChatMessageColor, variant: ChatMessageVariant): string {
5094
5248
  if (variant === 'flat') {
5095
- return color === 'muted' ? 'bg-background-muted' : ''
5249
+ return color === 'muted' ? 'bg-background-muted text-foreground' : 'text-foreground'
5096
5250
  }
5097
5251
  switch (color) {
5098
5252
  case 'default': return 'bg-background-paper border border-border text-foreground'
@@ -13868,8 +14022,8 @@ async function add(args) {
13868
14022
  for (const name of allComponents) {
13869
14023
  const item = registry[name];
13870
14024
  for (const file of item.files) {
13871
- const filePath = import_node_path5.default.join(componentsDir, file.path);
13872
- toAdd.push({ name, fileName: file.path, content: file.content, filePath, exists: import_node_fs5.default.existsSync(filePath) });
14025
+ const filePath = import_node_path6.default.join(componentsDir, file.path);
14026
+ toAdd.push({ name, fileName: file.path, content: file.content, filePath, exists: import_node_fs6.default.existsSync(filePath) });
13873
14027
  }
13874
14028
  }
13875
14029
  const newFiles = toAdd.filter((f) => !f.exists || flagOverwrite);
@@ -13884,8 +14038,8 @@ async function add(args) {
13884
14038
  allNpmDeps.add(dep);
13885
14039
  }
13886
14040
  }
13887
- const pkgJsonPath = import_node_path5.default.join(projectRoot, "package.json");
13888
- const pkgJson = JSON.parse(import_node_fs5.default.readFileSync(pkgJsonPath, "utf-8"));
14041
+ const pkgJsonPath = import_node_path6.default.join(projectRoot, "package.json");
14042
+ const pkgJson = JSON.parse(import_node_fs6.default.readFileSync(pkgJsonPath, "utf-8"));
13889
14043
  const installedDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
13890
14044
  const depsToInstall = [...allNpmDeps].filter((d3) => !installedDeps[d3]);
13891
14045
  if (!flagYes) {
@@ -13914,24 +14068,24 @@ async function add(args) {
13914
14068
  process.exit(0);
13915
14069
  }
13916
14070
  }
13917
- if (!import_node_fs5.default.existsSync(componentsDir)) {
13918
- import_node_fs5.default.mkdirSync(componentsDir, { recursive: true });
14071
+ if (!import_node_fs6.default.existsSync(componentsDir)) {
14072
+ import_node_fs6.default.mkdirSync(componentsDir, { recursive: true });
13919
14073
  }
13920
14074
  let addedCount = 0;
13921
14075
  for (const entry of toAdd) {
13922
14076
  if (entry.exists && !flagOverwrite) continue;
13923
14077
  const content = rewriteImports(entry.content, config.aliases.utils);
13924
- import_node_fs5.default.writeFileSync(entry.filePath, content, "utf-8");
14078
+ import_node_fs6.default.writeFileSync(entry.filePath, content, "utf-8");
13925
14079
  addedCount++;
13926
14080
  logger.success(`${entry.exists ? "Overwrote" : "Added"} ${entry.fileName}`);
13927
14081
  }
13928
14082
  if (config.tailwind.version === 4 && addedCount > 0) {
13929
14083
  try {
13930
- const cssFullPath = import_node_path5.default.join(projectRoot, config.tailwind.css);
13931
- if (import_node_fs5.default.existsSync(cssFullPath)) {
13932
- const cssContent = import_node_fs5.default.readFileSync(cssFullPath, "utf-8");
13933
- const cssDir = import_node_path5.default.dirname(cssFullPath);
13934
- const relRaw = import_node_path5.default.relative(cssDir, componentsDir).replace(/\\/g, "/");
14084
+ const cssFullPath = import_node_path6.default.join(projectRoot, config.tailwind.css);
14085
+ if (import_node_fs6.default.existsSync(cssFullPath)) {
14086
+ const cssContent = import_node_fs6.default.readFileSync(cssFullPath, "utf-8");
14087
+ const cssDir = import_node_path6.default.dirname(cssFullPath);
14088
+ const relRaw = import_node_path6.default.relative(cssDir, componentsDir).replace(/\\/g, "/");
13935
14089
  const relSource = relRaw.startsWith(".") ? relRaw : `./${relRaw}`;
13936
14090
  const sourcePattern = new RegExp(`@source\\s+["']${relSource.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}["']`);
13937
14091
  if (!sourcePattern.test(cssContent)) {
@@ -13942,7 +14096,7 @@ async function add(args) {
13942
14096
  const insertAt = lineEnd !== -1 ? lineEnd + 1 : cssContent.length;
13943
14097
  const updated = cssContent.slice(0, insertAt) + `@source "${relSource}";
13944
14098
  ` + cssContent.slice(insertAt);
13945
- import_node_fs5.default.writeFileSync(cssFullPath, updated, "utf-8");
14099
+ import_node_fs6.default.writeFileSync(cssFullPath, updated, "utf-8");
13946
14100
  O2.success(`Added @source "${relSource}" to ${config.tailwind.css}`);
13947
14101
  } else {
13948
14102
  O2.warn(
@@ -13975,6 +14129,7 @@ async function add(args) {
13975
14129
  }
13976
14130
  const addedNames = [...new Set(newFiles.map((f) => f.name))];
13977
14131
  showSetupHints(addedNames);
14132
+ showCompanionHints(addedNames);
13978
14133
  if (skippedFiles.length > 0) {
13979
14134
  logger.info(`${skippedFiles.length} file(s) skipped (already exist)`);
13980
14135
  }
@@ -14004,14 +14159,14 @@ function resolveDependencies(names) {
14004
14159
  }
14005
14160
  function resolveAliasToDir(projectRoot, alias) {
14006
14161
  if (!alias.startsWith("@/")) {
14007
- return import_node_path5.default.join(projectRoot, alias);
14162
+ return import_node_path6.default.join(projectRoot, alias);
14008
14163
  }
14009
14164
  const relative = alias.slice(2);
14010
14165
  for (const srcDir of ["src", "app", "."]) {
14011
- const candidate = import_node_path5.default.join(projectRoot, srcDir, relative);
14012
- if (import_node_fs5.default.existsSync(candidate)) return candidate;
14166
+ const candidate = import_node_path6.default.join(projectRoot, srcDir, relative);
14167
+ if (import_node_fs6.default.existsSync(candidate)) return candidate;
14013
14168
  }
14014
- return import_node_path5.default.join(projectRoot, "src", relative);
14169
+ return import_node_path6.default.join(projectRoot, "src", relative);
14015
14170
  }
14016
14171
  function findSimilar(input, candidates) {
14017
14172
  let best = null;
@@ -14071,10 +14226,29 @@ function showSetupHints(names) {
14071
14226
  );
14072
14227
  }
14073
14228
  }
14229
+ var COMPANION_HINTS = {
14230
+ "toggle": ["toggle-group"],
14231
+ "toggle-group": ["toggle"]
14232
+ };
14233
+ function showCompanionHints(names) {
14234
+ const added = new Set(names);
14235
+ const suggested = /* @__PURE__ */ new Set();
14236
+ for (const name of names) {
14237
+ for (const companion of COMPANION_HINTS[name] || []) {
14238
+ if (added.has(companion)) continue;
14239
+ suggested.add(companion);
14240
+ }
14241
+ }
14242
+ for (const name of suggested) {
14243
+ logger.info(
14244
+ `${import_picocolors3.default.dim("Tip:")} also using ${import_picocolors3.default.cyan(name)}? Run: ${import_picocolors3.default.green(`npx 7onic add ${name}`)}`
14245
+ );
14246
+ }
14247
+ }
14074
14248
 
14075
14249
  // cli/src/index.ts
14076
14250
  var import_picocolors4 = __toESM(require_picocolors());
14077
- var VERSION = "0.1.10";
14251
+ var VERSION = "0.1.12";
14078
14252
  var HELP = `
14079
14253
  ${import_picocolors4.default.bold("7onic")} \u2014 Add 7onic design system components to your project
14080
14254
 
package/llms.txt CHANGED
@@ -25,7 +25,7 @@ npx 7onic init --tailwind v3 --yes # Explicit v3, skip prompts
25
25
  **What it does:**
26
26
  1. Detects Tailwind version (v3: config file exists, v4: no config) — or uses `--tailwind` flag
27
27
  2. Detects package manager (npm/pnpm/yarn/bun)
28
- 3. **Vite projects**: auto-configures `@/` path alias — patches `tsconfig.app.json` (JSONC-safe) and `vite.config.ts` (adds `import path` + `resolve.alias`), installs `@types/node`
28
+ 3. **Vite projects**: auto-configures `@/` path alias — patches `tsconfig.app.json` (JSONC-safe) and `vite.config.ts` (adds `import path` + `resolve.alias`), installs `@types/node`; **removes `create vite` boilerplate CSS blocks** from `src/index.css` + `src/App.css` (unlayered rules like `:root { font-family: system-ui }`, `button { color: #1a1a1a }` that override 7onic tokens) — prompts user, creates `.bak` backup
29
29
  4. Installs: `@7onic-ui/tokens`, `lucide-react`, `clsx`, `tailwind-merge`, `class-variance-authority`
30
30
  5. Creates/updates CSS file with token imports (v4: auto-injects `@import "tailwindcss"` if missing)
31
31
  6. Creates `cn()` utility at configured path
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "7onic",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "CLI for adding 7onic design system components to your project",
5
5
  "bin": {
6
6
  "7onic": "./dist/index.js"