create-ui0 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/dist/index.js
CHANGED
|
@@ -8,12 +8,16 @@ import prompts from 'prompts';
|
|
|
8
8
|
* Usage: npm create ui0 [dir]
|
|
9
9
|
*/
|
|
10
10
|
const templateDir = fileURLToPath(new URL('../template', import.meta.url));
|
|
11
|
+
const templateNuxtDir = fileURLToPath(new URL('../template-nuxt', import.meta.url));
|
|
11
12
|
const componentTemplateDir = fileURLToPath(new URL('../template-component', import.meta.url));
|
|
12
13
|
const toKebab = (s) => s
|
|
13
14
|
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
14
15
|
.replace(/[\s_]+/g, '-')
|
|
15
16
|
.toLowerCase();
|
|
16
|
-
const toPascal = (s) => s
|
|
17
|
+
const toPascal = (s) => s
|
|
18
|
+
.split(/[-\s_]+/)
|
|
19
|
+
.map((w) => w[0].toUpperCase() + w.slice(1))
|
|
20
|
+
.join('');
|
|
17
21
|
const toCamel = (s) => {
|
|
18
22
|
const p = toPascal(s);
|
|
19
23
|
return p[0].toLowerCase() + p.slice(1);
|
|
@@ -81,7 +85,12 @@ const runComponent = async () => {
|
|
|
81
85
|
message: 'Target directory',
|
|
82
86
|
initial: path.join('src', 'components', kebab)
|
|
83
87
|
}, { onCancel });
|
|
84
|
-
const { spec } = await prompts({
|
|
88
|
+
const { spec } = await prompts({
|
|
89
|
+
type: 'confirm',
|
|
90
|
+
name: 'spec',
|
|
91
|
+
message: 'Include a vitest spec (adds vitest + @vue/test-utils to devDependencies)?',
|
|
92
|
+
initial: false
|
|
93
|
+
}, { onCancel });
|
|
85
94
|
const dir = path.resolve(process.cwd(), target);
|
|
86
95
|
if (existsSync(dir)) {
|
|
87
96
|
console.error(`${target} already exists`);
|
|
@@ -125,42 +134,67 @@ const run = async () => {
|
|
|
125
134
|
const target = path.resolve(process.cwd(), argDir ?? dir);
|
|
126
135
|
const name = path.basename(target);
|
|
127
136
|
if (existsSync(target)) {
|
|
128
|
-
const { overwrite } = await prompts({
|
|
137
|
+
const { overwrite } = await prompts({
|
|
138
|
+
type: 'confirm',
|
|
139
|
+
name: 'overwrite',
|
|
140
|
+
message: `${name} exists - continue and fill missing files?`,
|
|
141
|
+
initial: false
|
|
142
|
+
}, { onCancel });
|
|
129
143
|
if (!overwrite)
|
|
130
144
|
process.exit(0);
|
|
131
145
|
}
|
|
146
|
+
const { host } = (await prompts({
|
|
147
|
+
type: 'select',
|
|
148
|
+
name: 'host',
|
|
149
|
+
message: 'App host',
|
|
150
|
+
choices: [
|
|
151
|
+
{ title: 'Vite (SPA)', value: 'vite' },
|
|
152
|
+
{ title: 'Nuxt (SSR, @ui0/nuxt)', value: 'nuxt' }
|
|
153
|
+
],
|
|
154
|
+
initial: 0
|
|
155
|
+
}, { onCancel }));
|
|
132
156
|
const { features } = (await prompts({
|
|
133
157
|
type: 'multiselect',
|
|
134
158
|
name: 'features',
|
|
135
|
-
message: 'Packages to include',
|
|
159
|
+
message: host === 'nuxt' ? 'Demo sections to include' : 'Packages to include',
|
|
136
160
|
choices: FEATURES.map((f) => ({ title: f.title, value: f.id, selected: f.id !== 'icon' })),
|
|
137
161
|
instructions: false
|
|
138
162
|
}, { onCancel }));
|
|
163
|
+
// the nuxt flavour lives in its own template; @ui0/nuxt already carries
|
|
164
|
+
// every runtime package, so for nuxt the features only drive demo sections
|
|
165
|
+
const sourceDir = host === 'nuxt' ? templateNuxtDir : templateDir;
|
|
139
166
|
mkdirSync(target, { recursive: true });
|
|
140
|
-
cpSync(
|
|
167
|
+
cpSync(sourceDir, target, { recursive: true });
|
|
141
168
|
rmSync(path.join(target, 'package.json.tpl'));
|
|
142
169
|
const picked = FEATURES.filter((f) => features.includes(f.id));
|
|
143
|
-
// package.json from the template manifest + chosen deps
|
|
144
|
-
|
|
170
|
+
// package.json from the template manifest + chosen deps (vite hosts only;
|
|
171
|
+
// the nuxt manifest already depends on @ui0/nuxt, which bundles the rest)
|
|
172
|
+
const manifest = JSON.parse(readFileSync(path.join(sourceDir, 'package.json.tpl'), 'utf8'));
|
|
145
173
|
manifest.name = name;
|
|
146
|
-
|
|
174
|
+
if (host !== 'nuxt')
|
|
175
|
+
Object.assign(manifest.dependencies, ...picked.map((f) => f.deps));
|
|
147
176
|
writeFileSync(path.join(target, 'package.json'), JSON.stringify(manifest, null, 2) + '\n');
|
|
148
|
-
// App.vue
|
|
149
|
-
|
|
177
|
+
// app entry: src/App.vue (vite) or app/app.vue (nuxt) - inject the demo
|
|
178
|
+
// sections of the picked features; the nuxt module auto-registers the
|
|
179
|
+
// components, so no imports are added there
|
|
180
|
+
const appVue = path.join(target, host === 'nuxt' ? path.join('app', 'app.vue') : path.join('src', 'App.vue'));
|
|
150
181
|
let app = readFileSync(appVue, 'utf8');
|
|
151
182
|
app = app
|
|
152
|
-
.replace('/* FEATURE_IMPORTS */', picked.map((f) => f.importLine).join('\n'))
|
|
183
|
+
.replace('/* FEATURE_IMPORTS */', host === 'nuxt' ? '' : picked.map((f) => f.importLine).join('\n'))
|
|
153
184
|
.replace('/* FEATURE_SECTIONS */', picked.map((f) => f.section).join('\n\n'));
|
|
154
185
|
writeFileSync(appVue, app);
|
|
155
|
-
// the icon pack registers itself as a vue plugin
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
main =
|
|
160
|
-
|
|
161
|
-
|
|
186
|
+
// the icon pack registers itself as a vue plugin (vite hosts only - the
|
|
187
|
+
// nuxt module wires the icon framework and the pack itself)
|
|
188
|
+
if (host !== 'nuxt') {
|
|
189
|
+
const mainTs = path.join(target, 'src', 'main.ts');
|
|
190
|
+
let main = readFileSync(mainTs, 'utf8');
|
|
191
|
+
if (features.includes('icon')) {
|
|
192
|
+
main = main
|
|
193
|
+
.replace("import { createUi0 } from '@ui0/core'", "import Icons from '@ui0/icons'\nimport { createUi0 } from '@ui0/core'")
|
|
194
|
+
.replace('app.use(ui0)', 'app.use(ui0)\napp.use(Icons)');
|
|
195
|
+
}
|
|
196
|
+
writeFileSync(mainTs, main);
|
|
162
197
|
}
|
|
163
|
-
writeFileSync(mainTs, main);
|
|
164
198
|
console.log(`\nScaffolded ${name}:\n`);
|
|
165
199
|
console.log(` cd ${path.relative(process.cwd(), target)}`);
|
|
166
200
|
console.log(' npm install');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ui0",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Scaffold a ui0 (Vue + @ui0) app - npm create ui0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"template",
|
|
12
|
+
"template-nuxt",
|
|
12
13
|
"template-component"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ThemeProvider preset="app">
|
|
3
|
+
<main :class="$style.page">
|
|
4
|
+
<h1>ui0 app</h1>
|
|
5
|
+
|
|
6
|
+
/* FEATURE_SECTIONS */
|
|
7
|
+
</main>
|
|
8
|
+
</ThemeProvider>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
// ThemeProvider / Flex / Button / Icon are auto-registered by @ui0/nuxt
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<style module lang="scss">
|
|
16
|
+
.page {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: 24px;
|
|
20
|
+
padding: 32px;
|
|
21
|
+
font-family: system-ui, sans-serif;
|
|
22
|
+
|
|
23
|
+
h1 {
|
|
24
|
+
font-size: 20px;
|
|
25
|
+
}
|
|
26
|
+
h2 {
|
|
27
|
+
font-size: 14px;
|
|
28
|
+
opacity: 0.7;
|
|
29
|
+
margin-bottom: 8px;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
.box {
|
|
33
|
+
padding: 12px 16px;
|
|
34
|
+
border: 1px solid rgba(127, 127, 127, 0.4);
|
|
35
|
+
border-radius: 6px;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ui0-app",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "nuxt dev",
|
|
8
|
+
"build": "nuxt build",
|
|
9
|
+
"preview": "nuxt preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@ui0/nuxt": "^0.1.0",
|
|
13
|
+
"nuxt": "^4.6.4",
|
|
14
|
+
"vue": "^3.5.45"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@ui0/types": "^0.1.2",
|
|
18
|
+
"sass-embedded": "^1.80.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Ui0CoreConfig } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
const config: Ui0CoreConfig = {
|
|
4
|
+
theme: {
|
|
5
|
+
default: 'app',
|
|
6
|
+
contracts: {
|
|
7
|
+
display: {}
|
|
8
|
+
},
|
|
9
|
+
presets: {
|
|
10
|
+
app: {
|
|
11
|
+
default: {
|
|
12
|
+
color: {
|
|
13
|
+
brand: ['rgb(86 59 177)', 4],
|
|
14
|
+
foreground: '#111',
|
|
15
|
+
background: '#fff'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default config
|