@nqlib/nqui 0.1.2 → 0.1.3
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/README.md +40 -2
- package/dist/styles.css +468 -21
- package/package.json +5 -1
- package/scripts/build-styles.js +0 -10
- package/scripts/examples/nextjs-layout.tsx +2 -0
- package/scripts/examples.js +76 -0
- package/scripts/framework.js +68 -0
- package/scripts/getPackageRoot.js +26 -0
- package/scripts/help.js +34 -0
- package/scripts/init-css.js +88 -569
- package/scripts/pipeline/emit.js +21 -0
- package/scripts/pipeline/extract.js +118 -0
- package/scripts/pipeline/index.js +90 -0
- package/scripts/pipeline/tokens.js +25 -0
- package/scripts/pipeline/transform.js +51 -0
- package/scripts/postcss.config.mjs +10 -0
- package/scripts/setup-helper.js +72 -0
- package/scripts/wizard.js +57 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { getPackageRoot } from './getPackageRoot.js';
|
|
4
|
+
import { findMainCssFile } from './framework.js';
|
|
5
|
+
import { askQuestion } from './wizard.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Copy Next.js example files to user's project
|
|
9
|
+
*/
|
|
10
|
+
export async function copyNextJsExamples(framework, { force }) {
|
|
11
|
+
if (framework !== 'nextjs') {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const root = getPackageRoot();
|
|
16
|
+
const examplesDir = join(root, 'scripts', 'examples');
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
|
|
19
|
+
// Determine app directory (src/app or app)
|
|
20
|
+
const appDir = existsSync(join(cwd, 'src', 'app'))
|
|
21
|
+
? join(cwd, 'src', 'app')
|
|
22
|
+
: join(cwd, 'app');
|
|
23
|
+
|
|
24
|
+
const examples = [
|
|
25
|
+
{ src: 'nextjs-page.tsx', dest: join(appDir, 'page.tsx'), name: 'page.tsx' },
|
|
26
|
+
{ src: 'nextjs-layout.tsx', dest: join(appDir, 'layout.tsx'), name: 'layout.tsx' },
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const copied = [];
|
|
30
|
+
const existing = [];
|
|
31
|
+
|
|
32
|
+
// Check which files exist
|
|
33
|
+
for (const { dest, name } of examples) {
|
|
34
|
+
if (existsSync(dest)) {
|
|
35
|
+
existing.push({ dest, name });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Ask about overwriting if files exist and force is not set
|
|
40
|
+
let shouldOverwrite = force;
|
|
41
|
+
if (existing.length > 0 && !force) {
|
|
42
|
+
const fileList = existing.map(e => e.name).join(' and ');
|
|
43
|
+
const answer = await askQuestion(
|
|
44
|
+
`\n⚠️ ${fileList} already exist(s). Overwrite? (y/n): `
|
|
45
|
+
);
|
|
46
|
+
shouldOverwrite = answer === 'y';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (const { src, dest, name } of examples) {
|
|
50
|
+
const srcPath = join(examplesDir, src);
|
|
51
|
+
|
|
52
|
+
if (!existsSync(srcPath)) {
|
|
53
|
+
console.warn(`⚠️ Example file not found: ${srcPath}`);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (existsSync(dest) && !shouldOverwrite) {
|
|
58
|
+
console.log(`⏭️ Skipped: ${dest} (already exists)`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const content = readFileSync(srcPath, 'utf8');
|
|
63
|
+
writeFileSync(dest, content, 'utf8');
|
|
64
|
+
copied.push(dest);
|
|
65
|
+
console.log(`✅ ${existsSync(dest) && shouldOverwrite ? 'Overwritten' : 'Created'}: ${dest}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (copied.length > 0) {
|
|
69
|
+
console.log(`\n📝 Required dependencies for example files:`);
|
|
70
|
+
console.log(` npm install @nqlib/nqui tw-animate-css next-themes\n`);
|
|
71
|
+
console.log(` Make sure your globals.css includes the setup from nqui/nqui-setup.css\n`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return copied;
|
|
75
|
+
}
|
|
76
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Detect the framework type of the current project
|
|
6
|
+
*/
|
|
7
|
+
export function detectFramework() {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
|
|
10
|
+
if (
|
|
11
|
+
existsSync(join(cwd, 'next.config.js')) ||
|
|
12
|
+
existsSync(join(cwd, 'next.config.ts')) ||
|
|
13
|
+
existsSync(join(cwd, 'app')) ||
|
|
14
|
+
existsSync(join(cwd, 'src', 'app'))
|
|
15
|
+
) {
|
|
16
|
+
return 'nextjs';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
existsSync(join(cwd, 'vite.config.js')) ||
|
|
21
|
+
existsSync(join(cwd, 'vite.config.ts'))
|
|
22
|
+
) {
|
|
23
|
+
return 'vite';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (existsSync(join(cwd, 'remix.config.js'))) {
|
|
27
|
+
return 'remix';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (existsSync(join(cwd, 'src', 'index.css'))) {
|
|
31
|
+
return 'create-react-app';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return 'generic';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Find the main CSS file for a framework
|
|
39
|
+
*/
|
|
40
|
+
export function findMainCssFile(framework) {
|
|
41
|
+
const cwd = process.cwd();
|
|
42
|
+
|
|
43
|
+
switch (framework) {
|
|
44
|
+
case 'nextjs':
|
|
45
|
+
// Check src/app first, then app
|
|
46
|
+
if (existsSync(join(cwd, 'src', 'app', 'globals.css'))) {
|
|
47
|
+
return 'src/app/globals.css';
|
|
48
|
+
}
|
|
49
|
+
if (existsSync(join(cwd, 'app', 'globals.css'))) {
|
|
50
|
+
return 'app/globals.css';
|
|
51
|
+
}
|
|
52
|
+
return 'app/globals.css'; // default
|
|
53
|
+
case 'vite':
|
|
54
|
+
case 'create-react-app':
|
|
55
|
+
if (existsSync(join(cwd, 'src', 'index.css'))) {
|
|
56
|
+
return 'src/index.css';
|
|
57
|
+
}
|
|
58
|
+
return 'src/index.css'; // default
|
|
59
|
+
case 'remix':
|
|
60
|
+
if (existsSync(join(cwd, 'app', 'root.css'))) {
|
|
61
|
+
return 'app/root.css';
|
|
62
|
+
}
|
|
63
|
+
return 'app/root.css'; // default
|
|
64
|
+
default:
|
|
65
|
+
return 'index.css';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Robust package root detection that works with npx
|
|
7
|
+
* Uses fileURLToPath for Windows compatibility
|
|
8
|
+
*/
|
|
9
|
+
export function getPackageRoot() {
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
let dir = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
while (dir !== '/' && dir !== '') {
|
|
14
|
+
const pkgPath = join(dir, 'package.json');
|
|
15
|
+
if (existsSync(pkgPath)) {
|
|
16
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
17
|
+
if (pkg.name === '@nqlib/nqui') return dir;
|
|
18
|
+
}
|
|
19
|
+
const parentDir = dirname(dir);
|
|
20
|
+
if (parentDir === dir) break; // Reached root
|
|
21
|
+
dir = parentDir;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
throw new Error('Could not locate @nqlib/nqui package root');
|
|
25
|
+
}
|
|
26
|
+
|
package/scripts/help.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { getPackageRoot } from './getPackageRoot.js';
|
|
4
|
+
|
|
5
|
+
export function printHelp() {
|
|
6
|
+
const root = getPackageRoot();
|
|
7
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
8
|
+
|
|
9
|
+
console.log(`
|
|
10
|
+
${pkg.name} v${pkg.version}
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
npx nqui init-css [output.css] [options]
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--js Generate JS token file
|
|
17
|
+
--tokens-only Extract only CSS variables
|
|
18
|
+
--setup Generate nqui-setup.css helper
|
|
19
|
+
--local-copy Generate local CSS copy instead of importing from library
|
|
20
|
+
--wizard Interactive installer
|
|
21
|
+
--force Overwrite existing files
|
|
22
|
+
--dry-run Preview output only
|
|
23
|
+
--help, -h Show help
|
|
24
|
+
--version, -v Show version
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
npx nqui init-css
|
|
28
|
+
npx nqui init-css nqui/index.css
|
|
29
|
+
npx nqui init-css --local-copy nqui/nqui.css
|
|
30
|
+
npx nqui init-css --tokens-only --js
|
|
31
|
+
npx nqui init-css --wizard
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
|