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.
- package/dist/index.js +233 -59
- package/llms.txt +1 -1
- 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
|
|
159
|
-
var
|
|
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 =
|
|
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 =
|
|
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 =
|
|
1304
|
-
const isViteProject =
|
|
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(
|
|
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(
|
|
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) =>
|
|
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 =
|
|
1396
|
-
if (!
|
|
1397
|
-
const cssDir =
|
|
1398
|
-
if (!
|
|
1399
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
1533
|
+
import_node_fs5.default.writeFileSync(cssFullPath, updated, "utf-8");
|
|
1413
1534
|
} else {
|
|
1414
|
-
|
|
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
|
-
|
|
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 =
|
|
1428
|
-
if (
|
|
1429
|
-
const configContent =
|
|
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 (!
|
|
1449
|
-
const utilsDir =
|
|
1450
|
-
if (!
|
|
1451
|
-
|
|
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
|
-
|
|
1454
|
-
O2.success(`Created ${
|
|
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 =
|
|
1610
|
+
const utilsContent = import_node_fs5.default.readFileSync(utilsFullPath, "utf-8");
|
|
1457
1611
|
if (!utilsContent.includes("tailwind-merge")) {
|
|
1458
1612
|
O2.warn(
|
|
1459
|
-
`${
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
1530
|
-
if (
|
|
1531
|
-
return
|
|
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
|
|
1688
|
+
return import_node_path5.default.join(projectRoot, "src", relative);
|
|
1535
1689
|
}
|
|
1536
1690
|
|
|
1537
1691
|
// cli/src/commands/add.ts
|
|
1538
|
-
var
|
|
1539
|
-
var
|
|
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 =
|
|
13872
|
-
toAdd.push({ name, fileName: file.path, content: file.content, filePath, exists:
|
|
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 =
|
|
13888
|
-
const pkgJson = JSON.parse(
|
|
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 (!
|
|
13918
|
-
|
|
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
|
-
|
|
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 =
|
|
13931
|
-
if (
|
|
13932
|
-
const cssContent =
|
|
13933
|
-
const cssDir =
|
|
13934
|
-
const relRaw =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
14012
|
-
if (
|
|
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
|
|
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.
|
|
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
|