@nqlib/nqui 0.4.3 → 0.4.5
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/INSTALLATION.md +234 -0
- package/README.md +109 -151
- package/dist/button-CJHdCq9I.js +155 -0
- package/dist/button-R304rhsj.cjs +1 -0
- package/dist/calendar.cjs.js +1 -1
- package/dist/calendar.es.js +1 -1
- package/dist/carousel-D1FMVglR.cjs +1 -0
- package/dist/carousel-U7RZhYZj.js +179 -0
- package/dist/carousel.cjs.js +1 -1
- package/dist/carousel.es.js +1 -1
- package/dist/command-palette-DCtLpM3Q.js +694 -0
- package/dist/command-palette-MHc03bBf.cjs +5 -0
- package/dist/command.cjs.js +1 -1
- package/dist/command.es.js +1 -1
- package/dist/components/custom/color-picker.d.ts +1 -1
- package/dist/components/custom/color-picker.d.ts.map +1 -1
- package/dist/components/custom/color-slider.d.ts +4 -10
- package/dist/components/custom/color-slider.d.ts.map +1 -1
- package/dist/components/custom/enhanced-radio-group.d.ts +13 -4
- package/dist/components/custom/enhanced-radio-group.d.ts.map +1 -1
- package/dist/components/custom/enhanced-tabs.d.ts.map +1 -1
- package/dist/components/debug/debug-features.d.ts +29 -0
- package/dist/components/debug/debug-features.d.ts.map +1 -0
- package/dist/components/debug/debug-panel.d.ts.map +1 -1
- package/dist/components/error-boundary.d.ts +20 -0
- package/dist/components/error-boundary.d.ts.map +1 -0
- package/dist/components/index.d.ts +103 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/ui/badge.d.ts +16 -5
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/button.d.ts +38 -4
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/checkbox.d.ts +16 -2
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/combobox.d.ts +2 -1
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/frosted-glass.d.ts.map +1 -1
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/input-group.d.ts.map +1 -1
- package/dist/components/ui/pagination.d.ts +3 -2
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/radio-group.d.ts +3 -1
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/select.d.ts +6 -1
- package/dist/components/ui/select.d.ts.map +1 -1
- package/dist/components/ui/sidebar.d.ts +1 -1
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/slider.d.ts +10 -2
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/sonner.d.ts +18 -2
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/spinner.d.ts +2 -1
- package/dist/components/ui/spinner.d.ts.map +1 -1
- package/dist/components/ui/switch.d.ts +15 -2
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/debug-panel-CNKk-No5.cjs +75 -0
- package/dist/debug-panel-pg39-6xw.js +9011 -0
- package/dist/debug.cjs.js +1 -0
- package/dist/debug.es.js +7 -0
- package/dist/{drawer-CU4lkcz7.js → drawer-DO26uhym.js} +31 -31
- package/dist/drawer-DVarEy65.cjs +1 -0
- package/dist/drawer.cjs.js +1 -1
- package/dist/drawer.es.js +1 -1
- package/dist/{enhanced-calendar-BENbxw7_.js → enhanced-calendar-BGlsSYJd.js} +1 -1
- package/dist/{enhanced-calendar-5PA8CeF7.cjs → enhanced-calendar-C7EQIr6i.cjs} +1 -1
- package/dist/entries/debug.d.ts +14 -0
- package/dist/entries/debug.d.ts.map +1 -0
- package/dist/entries/sonner.d.ts +1 -2
- package/dist/entries/sonner.d.ts.map +1 -1
- package/dist/hooks/use-mobile.d.ts.map +1 -1
- package/dist/hooks/use-scroll-spy.d.ts.map +1 -1
- package/dist/index-CI756mSv.cjs +41 -0
- package/dist/index-CgfzsUO6.js +1069 -0
- package/dist/index.d.ts +2 -98
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/wrap-inline-label-text.d.ts +7 -0
- package/dist/lib/wrap-inline-label-text.d.ts.map +1 -0
- package/dist/nqui.cjs.js +49 -245
- package/dist/nqui.es.js +7402 -16735
- package/dist/sonner-CpmECDBk.js +179 -0
- package/dist/sonner-nE9hIalJ.cjs +48 -0
- package/dist/sonner.cjs.js +1 -1
- package/dist/sonner.es.js +3 -2
- package/dist/styles.css +237 -10
- package/docs/components/README.md +109 -10
- package/docs/components/nqui-badge.md +1 -0
- package/docs/components/nqui-button.md +3 -1
- package/docs/components/nqui-card.md +8 -0
- package/docs/components/nqui-carousel.md +6 -0
- package/docs/components/nqui-checkbox.md +38 -1
- package/docs/components/nqui-color-slider.md +5 -3
- package/docs/components/nqui-combobox.md +58 -37
- package/docs/components/nqui-drawer.md +1 -1
- package/docs/components/nqui-frosted-glass.md +83 -5
- package/docs/components/nqui-radio-group.md +47 -2
- package/docs/components/nqui-scroll-area.md +1 -1
- package/docs/components/nqui-select.md +2 -2
- package/docs/components/nqui-sheet.md +1 -1
- package/docs/components/nqui-slider.md +13 -0
- package/docs/components/nqui-spinner.md +6 -1
- package/docs/components/nqui-switch.md +23 -1
- package/docs/components/nqui-tabs.md +11 -1
- package/docs/components/nqui-toaster.md +5 -1
- package/docs/internal-notes/PUBLISHING.md +46 -4
- package/docs/nqui-skills/SKILL.md +106 -0
- package/docs/nqui-skills/design-system.md +143 -0
- package/docs/nqui-skills/rules/composition.md +183 -0
- package/docs/nqui-skills/rules/forms.md +190 -0
- package/docs/nqui-skills/rules/icons.md +158 -0
- package/docs/nqui-skills/rules/styling.md +192 -0
- package/package.json +23 -12
- package/scripts/build-styles.js +16 -0
- package/scripts/cli.js +1 -0
- package/scripts/download-skills.js +91 -0
- package/scripts/examples/nextjs-layout-sidebar.tsx +100 -0
- package/scripts/examples/nextjs-page-sidebar.tsx +81 -0
- package/scripts/examples/vite-app.tsx +135 -0
- package/scripts/examples/vite-main.tsx +17 -0
- package/scripts/examples.js +92 -6
- package/scripts/generate-docs.js +169 -0
- package/scripts/init-css.js +34 -14
- package/scripts/init-cursor.js +8 -0
- package/scripts/init-debug-css.js +4 -2
- package/scripts/post-install.js +41 -9
- package/scripts/publish-npmjs.js +17 -3
- package/scripts/resolve-target-dir.js +20 -1
- package/scripts/setup-helper.js +13 -1
- package/scripts/verify-build.js +1 -1
- package/scripts/wizard.js +12 -7
- package/dist/button-CYFTFDKe.cjs +0 -1
- package/dist/button-nJvDl3w8.js +0 -44
- package/dist/carousel-DEyyJi49.js +0 -179
- package/dist/carousel-Dhhz8m5V.cjs +0 -1
- package/dist/command-palette-UHk8zZOg.cjs +0 -45
- package/dist/command-palette-d-TrdBsM.js +0 -1778
- package/dist/components/custom/enhanced-badge.d.ts +0 -33
- package/dist/components/custom/enhanced-badge.d.ts.map +0 -1
- package/dist/components/custom/enhanced-button.d.ts +0 -34
- package/dist/components/custom/enhanced-button.d.ts.map +0 -1
- package/dist/components/custom/enhanced-checkbox.d.ts +0 -28
- package/dist/components/custom/enhanced-checkbox.d.ts.map +0 -1
- package/dist/components/custom/enhanced-combobox.d.ts +0 -35
- package/dist/components/custom/enhanced-combobox.d.ts.map +0 -1
- package/dist/components/custom/enhanced-select.d.ts +0 -30
- package/dist/components/custom/enhanced-select.d.ts.map +0 -1
- package/dist/components/custom/enhanced-sonner.d.ts +0 -16
- package/dist/components/custom/enhanced-sonner.d.ts.map +0 -1
- package/dist/drawer-BcIxWRN8.cjs +0 -1
- package/dist/sonner-Co6YpYVs.js +0 -546
- package/dist/sonner-DbQhVp8m.cjs +0 -330
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates downloadable documentation files for nqui.
|
|
3
|
+
*
|
|
4
|
+
* Outputs:
|
|
5
|
+
* - INSTALL.md: Installation instructions
|
|
6
|
+
* - COMPONENTS.md: All component documentation bundled
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/generate-docs.js
|
|
10
|
+
* node scripts/generate-docs.js --install
|
|
11
|
+
* node scripts/generate-docs.js --components
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync, readdirSync, existsSync } from 'fs';
|
|
15
|
+
import { join, dirname } from 'path';
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const DOCS_DIR = join(__dirname, '../docs');
|
|
20
|
+
const OUTPUT_DIR = join(__dirname, '../dist/docs');
|
|
21
|
+
|
|
22
|
+
// Ensure output directory exists
|
|
23
|
+
import { mkdirSync, rmSync } from 'fs';
|
|
24
|
+
|
|
25
|
+
function ensureDir(dir) {
|
|
26
|
+
if (!existsSync(dir)) {
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readDoc(filePath) {
|
|
32
|
+
try {
|
|
33
|
+
return readFileSync(filePath, 'utf-8');
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function generateInstallDoc() {
|
|
40
|
+
const installPath = join(DOCS_DIR, 'internal-notes/INSTALLATION.md');
|
|
41
|
+
let content = readDoc(installPath);
|
|
42
|
+
|
|
43
|
+
if (!content) {
|
|
44
|
+
console.error('Could not find INSTALLATION.md');
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add header
|
|
49
|
+
const header = `# @nqlib/nqui Installation Guide
|
|
50
|
+
|
|
51
|
+
> Generated for LLM consumption. Use this file to understand how to install and set up nqui.
|
|
52
|
+
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
return header + content;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function generateComponentsDoc() {
|
|
59
|
+
// Read the main README for shared conventions
|
|
60
|
+
const readmePath = join(DOCS_DIR, 'components/README.md');
|
|
61
|
+
let readmeContent = readDoc(readmePath);
|
|
62
|
+
|
|
63
|
+
if (!readmeContent) {
|
|
64
|
+
console.error('Could not find README.md');
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Extract sections from README that are useful for implementation
|
|
69
|
+
// (Prerequisites, Shared Conventions, When to Use tables)
|
|
70
|
+
const sectionsToKeep = [
|
|
71
|
+
'# nqui Component Instructions',
|
|
72
|
+
'## Prerequisites',
|
|
73
|
+
'## Shared Conventions',
|
|
74
|
+
'## When to Use',
|
|
75
|
+
'## AI Implementation Checklist'
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
// Build the content
|
|
79
|
+
let content = `# @nqlib/nqui Component Reference
|
|
80
|
+
|
|
81
|
+
> Generated for LLM consumption. Use this file when implementing nqui components.
|
|
82
|
+
|
|
83
|
+
**Import:** \`import { X } from "@nqlib/nqui"\`
|
|
84
|
+
**CSS:** \`@import "@nqlib/nqui/styles"\` (via \`npx @nqlib/nqui init-css\`)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
// Add the main sections from README
|
|
91
|
+
let currentSection = '';
|
|
92
|
+
const lines = readmeContent.split('\n');
|
|
93
|
+
|
|
94
|
+
for (const line of lines) {
|
|
95
|
+
// Track current section
|
|
96
|
+
if (line.startsWith('##')) {
|
|
97
|
+
currentSection = line;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Keep specific sections
|
|
101
|
+
if (sectionsToKeep.some(s => line.includes(s) || currentSection.includes(s.replace('## ', '').replace('# ', '')))) {
|
|
102
|
+
content += line + '\n';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Add component docs
|
|
107
|
+
content += '\n---\n\n## Component Documentation\n\n';
|
|
108
|
+
|
|
109
|
+
const componentsDir = join(DOCS_DIR, 'components');
|
|
110
|
+
const files = readdirSync(componentsDir)
|
|
111
|
+
.filter(f => f.startsWith('nqui-') && f.endsWith('.md'))
|
|
112
|
+
.sort();
|
|
113
|
+
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
const componentPath = join(componentsDir, file);
|
|
116
|
+
const componentContent = readDoc(componentPath);
|
|
117
|
+
|
|
118
|
+
if (componentContent) {
|
|
119
|
+
// Extract the relevant part (without frontmatter if present)
|
|
120
|
+
let docContent = componentContent;
|
|
121
|
+
|
|
122
|
+
// Remove frontmatter
|
|
123
|
+
if (docContent.startsWith('---')) {
|
|
124
|
+
const endOfFm = docContent.indexOf('---', 3);
|
|
125
|
+
if (endOfFm !== -1) {
|
|
126
|
+
docContent = docContent.substring(endOfFm + 3);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Clean up and add
|
|
131
|
+
docContent = docContent.trim();
|
|
132
|
+
content += docContent + '\n\n---\n\n';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return content;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function main() {
|
|
140
|
+
const args = process.argv.slice(2);
|
|
141
|
+
const generateInstall = args.includes('--install') || args.length === 0;
|
|
142
|
+
const generateComponents = args.includes('--components') || args.length === 0;
|
|
143
|
+
|
|
144
|
+
ensureDir(OUTPUT_DIR);
|
|
145
|
+
|
|
146
|
+
console.log('Generating nqui documentation...\n');
|
|
147
|
+
|
|
148
|
+
if (generateInstall) {
|
|
149
|
+
const installDoc = generateInstallDoc();
|
|
150
|
+
if (installDoc) {
|
|
151
|
+
const outputPath = join(OUTPUT_DIR, 'INSTALL.md');
|
|
152
|
+
writeFileSync(outputPath, installDoc);
|
|
153
|
+
console.log(`Generated: ${outputPath}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (generateComponents) {
|
|
158
|
+
const componentsDoc = generateComponentsDoc();
|
|
159
|
+
if (componentsDoc) {
|
|
160
|
+
const outputPath = join(OUTPUT_DIR, 'COMPONENTS.md');
|
|
161
|
+
writeFileSync(outputPath, componentsDoc);
|
|
162
|
+
console.log(`Generated: ${outputPath}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
console.log('\nDone!');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
main();
|
package/scripts/init-css.js
CHANGED
|
@@ -16,12 +16,12 @@ import { runPipeline } from './pipeline/index.js';
|
|
|
16
16
|
import { wizard, askAboutExamples } from './wizard.js';
|
|
17
17
|
import { detectFramework, findMainCssFile } from './framework.js';
|
|
18
18
|
import { generateSetupContent } from './setup-helper.js';
|
|
19
|
-
import { copyNextJsExamples } from './examples.js';
|
|
19
|
+
import { copyNextJsExamples, copyViteExamples } from './examples.js';
|
|
20
20
|
import { emit } from './pipeline/emit.js';
|
|
21
21
|
|
|
22
22
|
// Guard: if first arg is a subcommand, user has old package (main bin was init-css). Redirect.
|
|
23
23
|
const firstArg = process.argv[2];
|
|
24
|
-
const subcommands = ['init-cursor', 'install-peers', 'init-debug', 'init-debug-css', 'setup'];
|
|
24
|
+
const subcommands = ['init-cursor', 'init-skills', 'install-peers', 'init-debug', 'init-debug-css', 'setup'];
|
|
25
25
|
if (subcommands.includes(firstArg)) {
|
|
26
26
|
console.error(`
|
|
27
27
|
❌ Outdated @nqlib/nqui — "npx @nqlib/nqui ${firstArg}" routed to init-css.
|
|
@@ -29,17 +29,17 @@ if (subcommands.includes(firstArg)) {
|
|
|
29
29
|
Fix: npm install @nqlib/nqui@latest
|
|
30
30
|
Then: npx @nqlib/nqui ${firstArg}
|
|
31
31
|
|
|
32
|
-
Or run the binary directly: npm exec nqui-init-
|
|
32
|
+
Or run the binary directly: npm exec nqui-init-skills (for init-skills), etc.
|
|
33
33
|
`);
|
|
34
34
|
process.exit(1);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// Filter out command names from argv
|
|
38
|
-
const commandNames = ['init-css', 'nqui', 'nqui-init-css'];
|
|
37
|
+
// Filter out command names from argv (so they are never used as output path)
|
|
38
|
+
const commandNames = ['init-css', 'init-skills', 'nqui', 'nqui-init-css'];
|
|
39
39
|
const filteredArgs = process.argv.slice(2).filter(arg => !commandNames.includes(arg));
|
|
40
40
|
|
|
41
41
|
const args = minimist(filteredArgs, {
|
|
42
|
-
boolean: ['js', 'tokens-only', 'force', 'dry-run', 'wizard', 'setup', 'help', 'version', 'local-copy'],
|
|
42
|
+
boolean: ['js', 'tokens-only', 'force', 'dry-run', 'wizard', 'setup', 'help', 'version', 'local-copy', 'sidebar'],
|
|
43
43
|
alias: { h: 'help', v: 'version' },
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -55,7 +55,11 @@ if (args.version) {
|
|
|
55
55
|
process.exit(0);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
// Prevent subcommand names or bare filenames from becoming output path (would e.g. create init-skills or root nqui-setup.css)
|
|
59
|
+
const rawOutput = args._[0] || 'nqui/index.css';
|
|
60
|
+
const output = !rawOutput || rawOutput === 'init-skills' || rawOutput === 'init-cursor' || !dirname(rawOutput)
|
|
61
|
+
? 'nqui/index.css'
|
|
62
|
+
: rawOutput;
|
|
59
63
|
|
|
60
64
|
/**
|
|
61
65
|
* Generate index.css that imports from library package
|
|
@@ -101,29 +105,45 @@ function generateIndexCssContent() {
|
|
|
101
105
|
});
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
// Generate setup helper file (always, unless dry-run)
|
|
108
|
+
// Generate setup helper file (always, unless dry-run). Always under nqui/ to avoid writing to project root.
|
|
105
109
|
if (!args['dry-run'] && (args.setup || !args['tokens-only'])) {
|
|
106
110
|
const setupContent = generateSetupContent(framework, output, useLibraryImport);
|
|
107
|
-
const
|
|
111
|
+
const setupDir = dirname(output) || 'nqui';
|
|
112
|
+
const setupPath = resolve(process.cwd(), setupDir, 'nqui-setup.css');
|
|
108
113
|
emit(setupPath, setupContent, { force: args.force, dryRun: false });
|
|
109
114
|
|
|
110
115
|
const mainCssFile = findMainCssFile(framework);
|
|
111
116
|
|
|
112
117
|
console.log(`\n📝 Next steps:`);
|
|
113
|
-
console.log(` 1. Copy the contents of ${
|
|
118
|
+
console.log(` 1. Copy the contents of ${setupDir}/nqui-setup.css`);
|
|
114
119
|
console.log(` 2. Paste them at the VERY TOP of your main CSS file`);
|
|
115
120
|
console.log(` (e.g. ${mainCssFile})\n`);
|
|
116
121
|
}
|
|
117
122
|
|
|
118
|
-
//
|
|
123
|
+
// Copy examples: when --sidebar and --force, auto-enable so nqui:init is non-interactive
|
|
119
124
|
let shouldCopyExamples = wiz.copyExamples;
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
let useSidebar = wiz.sidebarLayout || args.sidebar;
|
|
126
|
+
if (!args.wizard && (framework === 'nextjs' || framework === 'vite')) {
|
|
127
|
+
if (args.sidebar && args.force) {
|
|
128
|
+
shouldCopyExamples = true;
|
|
129
|
+
useSidebar = true;
|
|
130
|
+
} else if (!args['dry-run'] && !shouldCopyExamples) {
|
|
131
|
+
shouldCopyExamples = await askAboutExamples(framework, useSidebar);
|
|
132
|
+
if (shouldCopyExamples) {
|
|
133
|
+
const sidebarAnswer = await askQuestion('\n🎨 Use sidebar layout (recommended for apps)? (y/n): ');
|
|
134
|
+
useSidebar = sidebarAnswer === 'y' || sidebarAnswer === 'yes';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
122
137
|
}
|
|
123
138
|
|
|
124
139
|
// Copy example files if requested
|
|
125
140
|
if (!args['dry-run'] && shouldCopyExamples) {
|
|
126
|
-
|
|
141
|
+
let copied;
|
|
142
|
+
if (framework === 'nextjs') {
|
|
143
|
+
copied = await copyNextJsExamples(framework, { force: args.force, sidebar: useSidebar });
|
|
144
|
+
} else if (framework === 'vite') {
|
|
145
|
+
copied = await copyViteExamples(framework, { force: args.force, sidebar: useSidebar });
|
|
146
|
+
}
|
|
127
147
|
if (copied && copied.length === 0) {
|
|
128
148
|
// Files were skipped (user said no to overwrite)
|
|
129
149
|
console.log('\n⏭️ Example files skipped. Run with --force to overwrite existing files.\n');
|
package/scripts/init-cursor.js
CHANGED
|
@@ -13,6 +13,7 @@ import { fileURLToPath } from 'url';
|
|
|
13
13
|
import { FULL_PEER_LIST } from './peer-deps.js';
|
|
14
14
|
import { buildInstallSkill, buildComponentsSkill } from './skill-templates.js';
|
|
15
15
|
import { resolveTargetDir } from './resolve-target-dir.js';
|
|
16
|
+
import { downloadSkills } from './download-skills.js';
|
|
16
17
|
|
|
17
18
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
19
|
const cwd = process.cwd();
|
|
@@ -153,12 +154,19 @@ function main() {
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
writeCursorRule(targetDir);
|
|
157
|
+
|
|
158
|
+
// Also download nqui-skills to user's .cursor folder
|
|
159
|
+
console.log('\n📚 Downloading nqui-skills...');
|
|
160
|
+
downloadSkills({ force: false });
|
|
161
|
+
|
|
156
162
|
console.log(`
|
|
157
163
|
✅ Cursor rules + skills installed
|
|
158
164
|
|
|
159
165
|
${displayPath}/.cursor/rules/nqui-components.mdc
|
|
160
166
|
${displayPath}/.cursor/skills/nqui-install/
|
|
161
167
|
${displayPath}/.cursor/skills/nqui-components/
|
|
168
|
+
${displayPath}/.cursor/nqui-skills/
|
|
169
|
+
${displayPath}/AGENTS.md
|
|
162
170
|
|
|
163
171
|
Open this folder in Cursor for skills to work. Docs: node_modules/@nqlib/nqui/docs/components/
|
|
164
172
|
`);
|
|
@@ -114,8 +114,10 @@ function main() {
|
|
|
114
114
|
console.log(' 1. Import the CSS in your app entry point:');
|
|
115
115
|
console.log(` import './${finalTargetPath.replace(process.cwd() + '/', '')}'`);
|
|
116
116
|
console.log(' 2. Use DebugPanel in your app:');
|
|
117
|
-
console.log(' import { DebugPanel } from "nqui"');
|
|
118
|
-
console.log('
|
|
117
|
+
console.log(' import { DebugPanel } from "@nqlib/nqui"');
|
|
118
|
+
console.log(' // Or tree-shake debug out of production: import { DebugPanel } from "@nqlib/nqui/debug"');
|
|
119
|
+
console.log(' 3. Add <DebugPanel /> to your root layout (panel is inactive until the user opens it).');
|
|
120
|
+
console.log(' Wrapping in process.env.NODE_ENV or import.meta.env.DEV is optional.');
|
|
119
121
|
console.log('\n✨ Done!');
|
|
120
122
|
}
|
|
121
123
|
|
package/scripts/post-install.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Auto-injects Cursor rules so consumers don't need to remember init-cursor.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { existsSync } from 'fs';
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
11
11
|
import { resolve } from 'path';
|
|
12
12
|
|
|
13
13
|
// Skip in CI to reduce noise
|
|
@@ -36,6 +36,31 @@ function getInstallCmd(pkgs) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
function addNquiInitScript() {
|
|
40
|
+
const cwd = process.cwd();
|
|
41
|
+
const packageJsonPath = resolve(cwd, 'package.json');
|
|
42
|
+
|
|
43
|
+
if (!existsSync(packageJsonPath)) return false;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
47
|
+
|
|
48
|
+
// Check if script already exists
|
|
49
|
+
if (pkg.scripts?.['nqui:init']) {
|
|
50
|
+
return false; // Already exists
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Add the script
|
|
54
|
+
pkg.scripts = pkg.scripts || {};
|
|
55
|
+
pkg.scripts['nqui:init'] = 'npx @nqlib/nqui install-peers && npx @nqlib/nqui init-cursor && npx @nqlib/nqui init-skills && npx @nqlib/nqui init-css --sidebar --force';
|
|
56
|
+
|
|
57
|
+
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
58
|
+
return true;
|
|
59
|
+
} catch (e) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
39
64
|
import { FULL_PEER_LIST } from './peer-deps.js';
|
|
40
65
|
import { writeCursorRule } from './init-cursor.js';
|
|
41
66
|
import { resolveTargetDir } from './resolve-target-dir.js';
|
|
@@ -47,21 +72,28 @@ const installRequired = getInstallCmd(requiredPeers);
|
|
|
47
72
|
const installFull = getInstallCmd(['@nqlib/nqui', ...FULL_PEER_LIST]);
|
|
48
73
|
const installRecommended = getInstallCmd(recommended);
|
|
49
74
|
|
|
75
|
+
// Auto-add nqui:init script to package.json
|
|
76
|
+
const scriptAdded = addNquiInitScript();
|
|
77
|
+
|
|
50
78
|
const msg = `
|
|
51
79
|
╔══════════════════════════════════════════════════════════════════╗
|
|
52
|
-
║ nqui – Next steps
|
|
80
|
+
║ nqui – Next steps ║
|
|
53
81
|
╚══════════════════════════════════════════════════════════════════╝
|
|
54
82
|
|
|
55
|
-
|
|
56
|
-
|
|
83
|
+
${scriptAdded ? '✅ Added "nqui:init" script to package.json\n' : ''}Run the full setup:
|
|
84
|
+
|
|
85
|
+
npm run nqui:init
|
|
57
86
|
|
|
58
|
-
|
|
59
|
-
Full: npx @nqlib/nqui install-peers
|
|
87
|
+
Or step by step:
|
|
60
88
|
|
|
61
|
-
|
|
89
|
+
npx @nqlib/nqui init-css --sidebar # CSS + sidebar layout
|
|
90
|
+
npx @nqlib/nqui install-peers # Install dependencies
|
|
91
|
+
npx @nqlib/nqui init-cursor # Setup Cursor skills
|
|
62
92
|
|
|
63
|
-
|
|
64
|
-
|
|
93
|
+
Manual commands:
|
|
94
|
+
- Install peers: ${installRequired}
|
|
95
|
+
- Full peers: npx @nqlib/nqui install-peers
|
|
96
|
+
- Refresh skills: npx @nqlib/nqui init-skills
|
|
65
97
|
|
|
66
98
|
→ Run "npx nqui-setup" anytime to see this again.
|
|
67
99
|
`;
|
package/scripts/publish-npmjs.js
CHANGED
|
@@ -19,8 +19,19 @@ const npmrcPath = join(rootDir, '.npmrc');
|
|
|
19
19
|
// Read package.json
|
|
20
20
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
21
21
|
|
|
22
|
-
// Save
|
|
22
|
+
// Save originals for restore
|
|
23
23
|
const originalPublishConfig = packageJson.publishConfig;
|
|
24
|
+
const originalDependencies = { ...packageJson.dependencies };
|
|
25
|
+
|
|
26
|
+
// Remove workspace:* deps (npm doesn't support workspace: protocol).
|
|
27
|
+
// nqcode/nqappbuilder are dev/showcase-only and not bundled in the library.
|
|
28
|
+
const workspaceDeps = ['@nqlib/nqcode', '@nqlib/nqappbuilder'];
|
|
29
|
+
for (const name of workspaceDeps) {
|
|
30
|
+
if (packageJson.dependencies?.[name] === 'workspace:*') {
|
|
31
|
+
delete packageJson.dependencies[name];
|
|
32
|
+
console.log(` Removed ${name} (workspace dep)`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
24
35
|
|
|
25
36
|
// Override publishConfig for npmjs.com
|
|
26
37
|
packageJson.publishConfig = {
|
|
@@ -99,14 +110,17 @@ try {
|
|
|
99
110
|
}
|
|
100
111
|
throw error;
|
|
101
112
|
} finally {
|
|
102
|
-
// Restore original publishConfig
|
|
113
|
+
// Restore original publishConfig and dependencies
|
|
103
114
|
if (originalPublishConfig) {
|
|
104
115
|
packageJson.publishConfig = originalPublishConfig;
|
|
105
116
|
} else {
|
|
106
117
|
delete packageJson.publishConfig;
|
|
107
118
|
}
|
|
119
|
+
if (originalDependencies) {
|
|
120
|
+
packageJson.dependencies = originalDependencies;
|
|
121
|
+
}
|
|
108
122
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
109
|
-
console.log('🔄 Restored
|
|
123
|
+
console.log('🔄 Restored package.json');
|
|
110
124
|
|
|
111
125
|
// Restore .npmrc if it existed
|
|
112
126
|
if (npmrcExists && originalNpmrc !== null) {
|
|
@@ -59,11 +59,24 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function isNquiSourceDir(dir) {
|
|
62
|
+
// Must NOT be inside node_modules (that means we're installed as a dep, not dev source)
|
|
63
|
+
if (resolve(dir).includes('node_modules')) return false;
|
|
62
64
|
return existsSync(resolve(dir, 'docs/components/README.md')) &&
|
|
63
65
|
existsSync(resolve(dir, 'package.json')) &&
|
|
64
66
|
readFileSync(resolve(dir, 'package.json'), 'utf8').includes('"name": "@nqlib/nqui"');
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
function findProjectRootFromNodeModules(startDir) {
|
|
70
|
+
let dir = resolve(startDir);
|
|
71
|
+
for (let i = 0; i < 20; i++) {
|
|
72
|
+
if (existsSync(resolve(dir, 'node_modules/@nqlib/nqui'))) return dir;
|
|
73
|
+
const parent = dirname(dir);
|
|
74
|
+
if (parent === dir) break;
|
|
75
|
+
dir = parent;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
/**
|
|
68
81
|
* Returns the directory where .cursor/ should be written.
|
|
69
82
|
* Prefers a dir with node_modules/@nqlib/nqui so docs path resolves.
|
|
@@ -72,7 +85,13 @@ function isNquiSourceDir(dir) {
|
|
|
72
85
|
* @returns {string} Absolute path to target directory
|
|
73
86
|
*/
|
|
74
87
|
export function resolveTargetDir(startDir) {
|
|
75
|
-
|
|
88
|
+
let cwd = resolve(startDir);
|
|
89
|
+
|
|
90
|
+
// 0. Running from node_modules (postinstall as dep) -> use host project root
|
|
91
|
+
if (cwd.includes('node_modules')) {
|
|
92
|
+
const projectRoot = findProjectRootFromNodeModules(cwd);
|
|
93
|
+
if (projectRoot) return projectRoot;
|
|
94
|
+
}
|
|
76
95
|
|
|
77
96
|
// 1. Current dir has nqui in node_modules -> use it
|
|
78
97
|
if (hasNquiInNodeModules(cwd)) return cwd;
|
package/scripts/setup-helper.js
CHANGED
|
@@ -53,6 +53,8 @@ export function generateSetupContent(framework, nquiCssPath, useLibraryImport =
|
|
|
53
53
|
`,
|
|
54
54
|
vite: `
|
|
55
55
|
@import "tw-animate-css";
|
|
56
|
+
|
|
57
|
+
@custom-variant dark (&:is(.dark *));
|
|
56
58
|
`,
|
|
57
59
|
'create-react-app': `
|
|
58
60
|
@import "tw-animate-css";
|
|
@@ -67,6 +69,16 @@ export function generateSetupContent(framework, nquiCssPath, useLibraryImport =
|
|
|
67
69
|
|
|
68
70
|
const finalImport = `\n/* Import nqui design tokens */\n@import "${relativeImport}";\n`;
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
const viteTailwindSources =
|
|
73
|
+
framework === 'vite'
|
|
74
|
+
? `
|
|
75
|
+
/* Tailwind v4: scan app + nqui dist when utilities from the package are missing (see INSTALLATION.md §2c) */
|
|
76
|
+
@source "./**/*.{js,ts,jsx,tsx,mdx}";
|
|
77
|
+
@source "../components/**/*.{js,ts,jsx,tsx,mdx}";
|
|
78
|
+
@source "../node_modules/@nqlib/nqui/dist/**/*.js";
|
|
79
|
+
`
|
|
80
|
+
: '';
|
|
81
|
+
|
|
82
|
+
return base + (extras[framework] || extras.generic) + finalImport + viteTailwindSources;
|
|
71
83
|
}
|
|
72
84
|
|
package/scripts/verify-build.js
CHANGED
|
@@ -284,7 +284,7 @@ function main() {
|
|
|
284
284
|
{ name: '@source inline() directives', pattern: /@source\s+inline\(/g },
|
|
285
285
|
{ name: ':root block', pattern: /:root\s*\{/ },
|
|
286
286
|
{ name: '.dark block', pattern: /\.dark\s*\{/ },
|
|
287
|
-
|
|
287
|
+
// Viewport lock (html, body, #root) was intentionally removed from base styles (see CHANGELOG 0.3.3); use AppLayout for opt-in lock.
|
|
288
288
|
];
|
|
289
289
|
|
|
290
290
|
criticalPatterns.forEach(({ name, pattern }) => {
|
package/scripts/wizard.js
CHANGED
|
@@ -35,23 +35,28 @@ export async function wizard() {
|
|
|
35
35
|
|
|
36
36
|
const framework = detectFramework();
|
|
37
37
|
let copyExamples = false;
|
|
38
|
+
let sidebarLayout = false;
|
|
38
39
|
|
|
39
|
-
if (framework === 'nextjs') {
|
|
40
|
-
copyExamples = (await ask(
|
|
40
|
+
if (framework === 'nextjs' || framework === 'vite') {
|
|
41
|
+
copyExamples = (await ask(`\nCopy ${framework} example files? (y/n): `)) === 'y';
|
|
42
|
+
if (copyExamples) {
|
|
43
|
+
sidebarLayout = (await ask('\nUse sidebar layout (recommended for apps)? (y/n): ')) === 'y';
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
return { tokensOnly, js, copyExamples };
|
|
47
|
+
return { tokensOnly, js, copyExamples, sidebarLayout };
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
47
|
-
* Ask about copying examples (used in default mode
|
|
51
|
+
* Ask about copying examples (used in default mode)
|
|
48
52
|
*/
|
|
49
|
-
export async function askAboutExamples(framework) {
|
|
50
|
-
if (framework !== 'nextjs') {
|
|
53
|
+
export async function askAboutExamples(framework, useSidebar = false) {
|
|
54
|
+
if (framework !== 'nextjs' && framework !== 'vite') {
|
|
51
55
|
return false;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
const
|
|
58
|
+
const layoutType = useSidebar ? 'sidebar' : 'basic';
|
|
59
|
+
const answer = await askQuestion(`\n📦 Copy ${framework} example files (${layoutType} layout)? (y/n): `);
|
|
55
60
|
return answer === 'y' || answer === 'yes';
|
|
56
61
|
}
|
|
57
62
|
|
package/dist/button-CYFTFDKe.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const u=require("react/jsx-runtime"),d=require("react"),l=require("@radix-ui/react-slot"),f=require("class-variance-authority"),g=require("./utils-IjLH3w2e.cjs");function b(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:()=>e[t]})}}return r.default=e,Object.freeze(r)}const v=b(d),o=f.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-7 min-w-7 px-3",sm:"h-6 min-w-6 rounded-[min(var(--radius-md),8px)] px-2 text-xs",lg:"h-8 min-w-8 px-4",icon:"h-7 w-7 p-0"}},defaultVariants:{variant:"default",size:"default"}}),i=v.forwardRef(({className:e,variant:r,size:t,asChild:n=!1,...s},a)=>{const c=n?l.Slot:"button";return u.jsx(c,{className:g.cn(o({variant:r,size:t,className:e})),ref:a,...s})});i.displayName="Button";exports.Button=i;exports.buttonVariants=o;
|
package/dist/button-nJvDl3w8.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
-
import * as a from "react";
|
|
3
|
-
import { Slot as d } from "@radix-ui/react-slot";
|
|
4
|
-
import { cva as c } from "class-variance-authority";
|
|
5
|
-
import { c as u } from "./utils-B6yFEsav.js";
|
|
6
|
-
const f = c(
|
|
7
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
8
|
-
{
|
|
9
|
-
variants: {
|
|
10
|
-
variant: {
|
|
11
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
12
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
13
|
-
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
14
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
16
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
17
|
-
},
|
|
18
|
-
size: {
|
|
19
|
-
default: "h-7 min-w-7 px-3",
|
|
20
|
-
sm: "h-6 min-w-6 rounded-[min(var(--radius-md),8px)] px-2 text-xs",
|
|
21
|
-
lg: "h-8 min-w-8 px-4",
|
|
22
|
-
icon: "h-7 w-7 p-0"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
defaultVariants: {
|
|
26
|
-
variant: "default",
|
|
27
|
-
size: "default"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
), m = a.forwardRef(
|
|
31
|
-
({ className: e, variant: r, size: t, asChild: o = !1, ...n }, i) => /* @__PURE__ */ s(
|
|
32
|
-
o ? d : "button",
|
|
33
|
-
{
|
|
34
|
-
className: u(f({ variant: r, size: t, className: e })),
|
|
35
|
-
ref: i,
|
|
36
|
-
...n
|
|
37
|
-
}
|
|
38
|
-
)
|
|
39
|
-
);
|
|
40
|
-
m.displayName = "Button";
|
|
41
|
-
export {
|
|
42
|
-
m as B,
|
|
43
|
-
f as b
|
|
44
|
-
};
|