pni 1.0.0 → 1.0.2
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/app.js +6 -2
- package/dist/template_code/css/tailwind.css.template +214 -0
- package/dist/template_code/nuxt/app.vue.template +25 -0
- package/dist/template_code/nuxt/nuxt.config.ts.template +90 -0
- package/dist/template_code/nuxt/pages/index.vue.template +14 -0
- package/dist/template_code/nuxt/pages/typography/index.vue.template +46 -0
- package/dist/template_code/postcss/postcss.config.js.template +7 -0
- package/dist/template_code/tailwind/tailwind.config.js.template +52 -0
- package/dist/template_code/vite/vite.config.ts.template +82 -0
- package/dist/utils/add-three.js +18 -3
- package/dist/utils/config-generator.d.ts +1 -0
- package/dist/utils/config-generator.js +67 -436
- package/dist/utils/css-variables.d.ts +1 -1
- package/dist/utils/css-variables.js +10 -265
- package/dist/utils/template-loader.d.ts +13 -0
- package/dist/utils/template-loader.js +52 -0
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -4,7 +4,7 @@ import { detectProjectType } from './utils/project-detection.js';
|
|
|
4
4
|
import { createApp } from './utils/app-creation.js';
|
|
5
5
|
import { detectPackageManager, getInstallCommand, getDevInstallCommand, } from './utils/package-manager.js';
|
|
6
6
|
import { getDependencies } from './utils/dependencies.js';
|
|
7
|
-
import { generateConfigFiles } from './utils/config-generator.js';
|
|
7
|
+
import { generateConfigFiles, setupNuxtAppStructure } from './utils/config-generator.js';
|
|
8
8
|
import { generateCSSVariables, updateIndexHtml, createTypographyPage } from './utils/css-variables.js';
|
|
9
9
|
import { setupShadcnNuxt } from './utils/shadcn-setup.js';
|
|
10
10
|
import FeatureSelector from './components/FeatureSelector.js';
|
|
@@ -71,6 +71,10 @@ export default function App({ nuxt = false, vue = false, threejs = false, cssVar
|
|
|
71
71
|
// Generate configuration files
|
|
72
72
|
setStep('configuring');
|
|
73
73
|
await generateConfigFiles(finalProjectType, workingPath, selectedFeatures.threejs, selectedFeatures.cssVars);
|
|
74
|
+
// Set up Nuxt app structure (app.vue, pages/index.vue, Lenis)
|
|
75
|
+
if (finalProjectType === 'nuxt') {
|
|
76
|
+
await setupNuxtAppStructure(workingPath);
|
|
77
|
+
}
|
|
74
78
|
// Generate CSS variables (always enabled - will be overwritten after shadcn-setup)
|
|
75
79
|
if (finalProjectType === 'nuxt') {
|
|
76
80
|
// For Nuxt, first create basic tailwind.css
|
|
@@ -82,7 +86,7 @@ export default function App({ nuxt = false, vue = false, threejs = false, cssVar
|
|
|
82
86
|
await generateCSSVariables(finalProjectType, workingPath, false);
|
|
83
87
|
// Create typography page after CSS variables are set up
|
|
84
88
|
if (selectedFeatures.cssVars) {
|
|
85
|
-
await createTypographyPage(workingPath);
|
|
89
|
+
await createTypographyPage(workingPath, finalProjectType);
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
else {
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
|
|
4
|
+
@font-face {
|
|
5
|
+
font-family: 'Helvetica';
|
|
6
|
+
src: url('~/assets/fonts/Helvetica.ttf') format('truetype');
|
|
7
|
+
font-weight: normal;
|
|
8
|
+
font-style: normal;
|
|
9
|
+
font-display: swap;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@custom-variant dark (&:is(.dark *));
|
|
13
|
+
|
|
14
|
+
@theme inline {
|
|
15
|
+
--spacing: 4rem;
|
|
16
|
+
--font-helvetica: 'Helvetica', sans-serif;
|
|
17
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
18
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
19
|
+
--radius-lg: var(--radius);
|
|
20
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
21
|
+
--color-background: var(--background);
|
|
22
|
+
--color-foreground: var(--foreground);
|
|
23
|
+
--color-card: var(--card);
|
|
24
|
+
--color-card-foreground: var(--card-foreground);
|
|
25
|
+
--color-popover: var(--popover);
|
|
26
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
27
|
+
--color-primary: var(--primary);
|
|
28
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
29
|
+
--color-secondary: var(--secondary);
|
|
30
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
31
|
+
--color-muted: var(--muted);
|
|
32
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
33
|
+
--color-accent: var(--accent);
|
|
34
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
35
|
+
--color-destructive: var(--destructive);
|
|
36
|
+
--color-border: var(--border);
|
|
37
|
+
--color-input: var(--input);
|
|
38
|
+
--color-ring: var(--ring);
|
|
39
|
+
--color-chart-1: var(--chart-1);
|
|
40
|
+
--color-chart-2: var(--chart-2);
|
|
41
|
+
--color-chart-3: var(--chart-3);
|
|
42
|
+
--color-chart-4: var(--chart-4);
|
|
43
|
+
--color-chart-5: var(--chart-5);
|
|
44
|
+
--color-sidebar: var(--sidebar);
|
|
45
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
46
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
47
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
48
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
49
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
50
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
51
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
:root {
|
|
55
|
+
/* osmo scaling system starts here */
|
|
56
|
+
--size-unit: 16; /* body font-size in design - no px */
|
|
57
|
+
--size-container-ideal: 1440; /* screen-size in design - no px */
|
|
58
|
+
--size-container-min: 992px;
|
|
59
|
+
--size-container-max: 1920px;
|
|
60
|
+
--size-container: clamp(var(--size-container-min), 100vw, var(--size-container-max));
|
|
61
|
+
--size-font: calc(var(--size-container) / (var(--size-container-ideal) / var(--size-unit)));
|
|
62
|
+
|
|
63
|
+
/* 1 fluid pixel unit */
|
|
64
|
+
--fluid-px: calc(var(--size-font) / 16);
|
|
65
|
+
/* osmo scaling system ends here */
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
--radius: 0.625rem;
|
|
70
|
+
--background: oklch(1 0 0);
|
|
71
|
+
--foreground: oklch(0.145 0 0);
|
|
72
|
+
--card: oklch(1 0 0);
|
|
73
|
+
--card-foreground: oklch(0.145 0 0);
|
|
74
|
+
--popover: oklch(1 0 0);
|
|
75
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
76
|
+
--primary: oklch(0.205 0 0);
|
|
77
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
78
|
+
--secondary: oklch(0.97 0 0);
|
|
79
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
80
|
+
--muted: oklch(0.97 0 0);
|
|
81
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
82
|
+
--accent: oklch(0.97 0 0);
|
|
83
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
84
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
85
|
+
--border: oklch(0.922 0 0);
|
|
86
|
+
--input: oklch(0.922 0 0);
|
|
87
|
+
--ring: oklch(0.708 0 0);
|
|
88
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
89
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
90
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
91
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
92
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
93
|
+
--sidebar: oklch(0.985 0 0);
|
|
94
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
95
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
96
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
97
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
98
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
99
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
100
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.dark {
|
|
104
|
+
--background: oklch(0.145 0 0);
|
|
105
|
+
--foreground: oklch(0.985 0 0);
|
|
106
|
+
--card: oklch(0.205 0 0);
|
|
107
|
+
--card-foreground: oklch(0.985 0 0);
|
|
108
|
+
--popover: oklch(0.205 0 0);
|
|
109
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
110
|
+
--primary: oklch(0.922 0 0);
|
|
111
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
112
|
+
--secondary: oklch(0.269 0 0);
|
|
113
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
114
|
+
--muted: oklch(0.269 0 0);
|
|
115
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
116
|
+
--accent: oklch(0.269 0 0);
|
|
117
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
118
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
119
|
+
--border: oklch(1 0 0 / 10%);
|
|
120
|
+
--input: oklch(1 0 0 / 15%);
|
|
121
|
+
--ring: oklch(0.556 0 0);
|
|
122
|
+
--chart-1: oklch(0.488 0.243 264.376);
|
|
123
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
124
|
+
--chart-3: oklch(0.769 0.188 70.08);
|
|
125
|
+
--chart-4: oklch(0.627 0.265 303.9);
|
|
126
|
+
--chart-5: oklch(0.645 0.246 16.439);
|
|
127
|
+
--sidebar: oklch(0.205 0 0);
|
|
128
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
129
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
130
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
131
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
132
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
133
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
134
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@layer base {
|
|
138
|
+
* {
|
|
139
|
+
@apply border-border outline-ring/50;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
body {
|
|
143
|
+
@apply bg-background text-foreground;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
html {
|
|
148
|
+
font-size: var(--fluid-px);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
body {
|
|
152
|
+
/* figma design 16px fontsize = 16rem fluid pixel unit */
|
|
153
|
+
font-size: 16rem;
|
|
154
|
+
font-family: var(--font-helvetica);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/* osmo scaling system starts here */
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
.container {
|
|
162
|
+
max-width: var(--size-container);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.container.medium {
|
|
166
|
+
max-width: calc(var(--size-container) * 0.85);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.container.small {
|
|
170
|
+
max-width: calc(var(--size-container) * 0.7);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Tablet */
|
|
174
|
+
@media screen and (max-width: 991px) {
|
|
175
|
+
:root {
|
|
176
|
+
--size-container-ideal: 834;
|
|
177
|
+
/* screen-size in design - no px */
|
|
178
|
+
--size-container-min: 768px;
|
|
179
|
+
--size-container-max: 991px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
body {
|
|
183
|
+
background-color: red;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Mobile Landscape */
|
|
188
|
+
@media screen and (max-width: 767px) {
|
|
189
|
+
:root {
|
|
190
|
+
--size-container-ideal: 550;
|
|
191
|
+
/* screen-size in design - no px */
|
|
192
|
+
--size-container-min: 480px;
|
|
193
|
+
--size-container-max: 767px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
body {
|
|
197
|
+
background-color: blue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Mobile Portrait */
|
|
202
|
+
@media screen and (max-width: 479px) {
|
|
203
|
+
:root {
|
|
204
|
+
--size-container-ideal: 375;
|
|
205
|
+
/* screen-size in design - no px */
|
|
206
|
+
--size-container-min: 320px;
|
|
207
|
+
--size-container-max: 479px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
body {
|
|
211
|
+
background-color: green;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { VueLenis } from 'lenis/vue'
|
|
3
|
+
|
|
4
|
+
const lenisOptions = {
|
|
5
|
+
// Lenis options (optional)
|
|
6
|
+
duration: 1.2,
|
|
7
|
+
easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
|
8
|
+
orientation: 'vertical',
|
|
9
|
+
gestureOrientation: 'vertical',
|
|
10
|
+
smoothWheel: true,
|
|
11
|
+
wheelMultiplier: 1,
|
|
12
|
+
smoothTouch: false,
|
|
13
|
+
touchMultiplier: 2,
|
|
14
|
+
infinite: false,
|
|
15
|
+
}
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<VueLenis root :options="lenisOptions">
|
|
20
|
+
<NuxtLayout>
|
|
21
|
+
<NuxtPage />
|
|
22
|
+
</NuxtLayout>
|
|
23
|
+
</VueLenis>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{{TAILWIND_IMPORT}}// https://nuxt.com/docs/api/configuration/nuxt-config
|
|
2
|
+
export default defineNuxtConfig({
|
|
3
|
+
// 1. Updated to a realistic 2024/2025 date for Nuxt 4 features
|
|
4
|
+
compatibilityDate: '2024-11-01',
|
|
5
|
+
devtools: { enabled: true },
|
|
6
|
+
|
|
7
|
+
{{CSS_IMPORT}} ssr: true,
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// SEO: Centralizing data
|
|
11
|
+
site: {
|
|
12
|
+
name: 'New Setup',
|
|
13
|
+
url: 'https://newsetup.com',
|
|
14
|
+
description: 'A new setup for your project',
|
|
15
|
+
defaultLocale: 'en',
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
// App Config for UI-wide settings
|
|
19
|
+
app: {
|
|
20
|
+
head: {
|
|
21
|
+
charset: 'utf-8',
|
|
22
|
+
viewport: 'width=device-width, initial-scale=1',
|
|
23
|
+
meta: [
|
|
24
|
+
{ name: 'description', content: 'A new setup for your project' },
|
|
25
|
+
{ name: 'author', content: 'New Setup' },
|
|
26
|
+
{ property: 'og:type', content: 'website' },
|
|
27
|
+
{ name: 'msapplication-TileColor', content: '#000000' },
|
|
28
|
+
{ name: 'theme-color', content: '#000000' },
|
|
29
|
+
],
|
|
30
|
+
link: [
|
|
31
|
+
// { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
|
|
32
|
+
// { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon-180x180.png' },
|
|
33
|
+
// { rel: 'manifest', href: '/manifest.webmanifest' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
{{VITE_CONFIG}} nitro: {
|
|
39
|
+
compressPublicAssets: {
|
|
40
|
+
brotli: true,
|
|
41
|
+
gzip: true,
|
|
42
|
+
},
|
|
43
|
+
// Enable crawling for SEO module compatibility
|
|
44
|
+
prerender: {
|
|
45
|
+
// set to true for production
|
|
46
|
+
crawlLinks: false,
|
|
47
|
+
routes: ['/']
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
modules: [{{MODULES}}],
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// Image Optimization
|
|
55
|
+
image: {
|
|
56
|
+
quality: 95,
|
|
57
|
+
format: ['webp'],
|
|
58
|
+
screens: {
|
|
59
|
+
xs: 320,
|
|
60
|
+
sm: 640,
|
|
61
|
+
md: 768,
|
|
62
|
+
lg: 1200,
|
|
63
|
+
xl: 1400,
|
|
64
|
+
xxl: 1800,
|
|
65
|
+
'2xl': 2000,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// UI Framework: Shadcn
|
|
70
|
+
{{SHADCN_CONFIG}} ogImage: {
|
|
71
|
+
defaults: {
|
|
72
|
+
component: 'OgImageTemplate',
|
|
73
|
+
props: {
|
|
74
|
+
title: 'New Setup',
|
|
75
|
+
description: 'A new setup for your project',
|
|
76
|
+
image: 'https://newsetup.com/og-image.png',
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
robots: {
|
|
81
|
+
disallow: ['/api',],
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
sitemap: {
|
|
87
|
+
// sources: ['/api/__sitemap__/urls'] // Fetch from API
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<template>
|
|
5
|
+
<div class="min-h-screen flex items-center justify-center">
|
|
6
|
+
<div class="text-center">
|
|
7
|
+
<h1 class="text-4xl font-bold mb-4">Welcome to Nuxt</h1>
|
|
8
|
+
<p class="text-lg text-muted-foreground">
|
|
9
|
+
Get started by editing <code class="px-2 py-1 bg-muted rounded">app/pages/index.vue</code>
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<template>
|
|
5
|
+
<section class="w-full py-20 px-4 min-h-screen flex items-center justify-center bg-[#DADADA] flex-col gap-16 ">
|
|
6
|
+
<div class="hero-container flex flex-col gap-16 leading-[1.2]">
|
|
7
|
+
<!-- figma design 120px fontsize -->
|
|
8
|
+
<h1 class="md:text-[120rem] text-[72rem]">Heading H1</h1>
|
|
9
|
+
<div class="divider"></div>
|
|
10
|
+
<!-- figma design 80px fontsize -->
|
|
11
|
+
<h2 class="md:text-[80rem] text-[64rem]">Heading H2</h2>
|
|
12
|
+
<div class="divider"></div>
|
|
13
|
+
<h3 class="md:text-[40rem] text-[32rem]">Heading H3</h3>
|
|
14
|
+
<!-- figma design 40px fontsize -->
|
|
15
|
+
<div class="divider"></div>
|
|
16
|
+
<h4 class="md:text-[28rem] text-[24rem]">Heading H4</h4>
|
|
17
|
+
<!-- figma design 28px fontsize -->
|
|
18
|
+
<div class="divider"></div>
|
|
19
|
+
<h5 class="md:text-[20rem] text-[18rem]">Heading H5</h5>
|
|
20
|
+
<!-- figma design 20px fontsize -->
|
|
21
|
+
<div class="divider"></div>
|
|
22
|
+
<!-- figma design 16px fontsize -->
|
|
23
|
+
<p class="text-[16rem] leading-[1.4] max-md:max-w-85.75 w-full font-helvetica">
|
|
24
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum
|
|
25
|
+
tristique. Duis cursus, all links in the website, eros dolor interdum nulla, ut commodo diam libero
|
|
26
|
+
vitae erat. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
|
|
27
|
+
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae
|
|
28
|
+
vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
|
|
29
|
+
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<style scoped>
|
|
36
|
+
.hero-container {
|
|
37
|
+
max-width: calc(1184em / 16);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.divider {
|
|
41
|
+
background-color: #969696;
|
|
42
|
+
height: 1px;
|
|
43
|
+
width: 100%;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
46
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: [
|
|
4
|
+
{{CONTENT_PATHS}}
|
|
5
|
+
],
|
|
6
|
+
theme: {
|
|
7
|
+
extend: {
|
|
8
|
+
colors: {
|
|
9
|
+
background: 'hsl(var(--background))',
|
|
10
|
+
foreground: 'hsl(var(--foreground))',
|
|
11
|
+
card: {
|
|
12
|
+
DEFAULT: 'hsl(var(--card))',
|
|
13
|
+
foreground: 'hsl(var(--card-foreground))',
|
|
14
|
+
},
|
|
15
|
+
popover: {
|
|
16
|
+
DEFAULT: 'hsl(var(--popover))',
|
|
17
|
+
foreground: 'hsl(var(--popover-foreground))',
|
|
18
|
+
},
|
|
19
|
+
primary: {
|
|
20
|
+
DEFAULT: 'hsl(var(--primary))',
|
|
21
|
+
foreground: 'hsl(var(--primary-foreground))',
|
|
22
|
+
},
|
|
23
|
+
secondary: {
|
|
24
|
+
DEFAULT: 'hsl(var(--secondary))',
|
|
25
|
+
foreground: 'hsl(var(--secondary-foreground))',
|
|
26
|
+
},
|
|
27
|
+
muted: {
|
|
28
|
+
DEFAULT: 'hsl(var(--muted))',
|
|
29
|
+
foreground: 'hsl(var(--muted-foreground))',
|
|
30
|
+
},
|
|
31
|
+
accent: {
|
|
32
|
+
DEFAULT: 'hsl(var(--accent))',
|
|
33
|
+
foreground: 'hsl(var(--accent-foreground))',
|
|
34
|
+
},
|
|
35
|
+
destructive: {
|
|
36
|
+
DEFAULT: 'hsl(var(--destructive))',
|
|
37
|
+
foreground: 'hsl(var(--destructive-foreground))',
|
|
38
|
+
},
|
|
39
|
+
border: 'hsl(var(--border))',
|
|
40
|
+
input: 'hsl(var(--input))',
|
|
41
|
+
ring: 'hsl(var(--ring))',
|
|
42
|
+
},
|
|
43
|
+
borderRadius: {
|
|
44
|
+
lg: 'var(--radius)',
|
|
45
|
+
md: 'calc(var(--radius) - 2px)',
|
|
46
|
+
sm: 'calc(var(--radius) - 4px)',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
plugins: [],
|
|
51
|
+
}
|
|
52
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { fileURLToPath, URL } from 'node:url'
|
|
2
|
+
{{TAILWIND_IMPORT}}import { defineConfig } from 'vite'
|
|
3
|
+
import vue from '@vitejs/plugin-vue'
|
|
4
|
+
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
5
|
+
import viteCompression from 'vite-plugin-compression'
|
|
6
|
+
import Sitemap from 'vite-plugin-sitemap'
|
|
7
|
+
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'
|
|
8
|
+
|
|
9
|
+
export default defineConfig(({ mode }) => {
|
|
10
|
+
const isProd = mode === 'production'
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
plugins: [
|
|
14
|
+
vue(),
|
|
15
|
+
{{TAILWIND_PLUGIN}} // 1. Only load DevTools in development
|
|
16
|
+
!isProd && vueDevTools(),
|
|
17
|
+
|
|
18
|
+
ViteImageOptimizer({
|
|
19
|
+
test: /\.(jpe?g|png|gif|tiff|webp|svg|avif)$/i,
|
|
20
|
+
includePublic: true,
|
|
21
|
+
logStats: true,
|
|
22
|
+
png: { quality: 75 },
|
|
23
|
+
jpeg: { quality: 75 },
|
|
24
|
+
jpg: { quality: 75 },
|
|
25
|
+
webp: { lossless: false, quality: 75 },
|
|
26
|
+
avif: { quality: 70 },
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
Sitemap({
|
|
30
|
+
hostname: 'https://newsetup.com', // Don't forget to update this!
|
|
31
|
+
dynamicRoutes: [],
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
// 2. Gzip Compression (Universal Fallback)
|
|
35
|
+
viteCompression({
|
|
36
|
+
algorithm: 'gzip',
|
|
37
|
+
ext: '.gz',
|
|
38
|
+
threshold: 10240,
|
|
39
|
+
deleteOriginFile: false,
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
// 3. Brotli Compression (Modern Performance)
|
|
43
|
+
viteCompression({
|
|
44
|
+
algorithm: 'brotliCompress',
|
|
45
|
+
ext: '.br',
|
|
46
|
+
threshold: 10240,
|
|
47
|
+
deleteOriginFile: false,
|
|
48
|
+
}),
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
resolve: {
|
|
52
|
+
alias: {
|
|
53
|
+
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
build: {
|
|
58
|
+
cssMinify: 'lightningcss', // Ensure 'lightningcss' is in package.json
|
|
59
|
+
// 4. Split Chunks for better Browser Caching
|
|
60
|
+
rollupOptions: {
|
|
61
|
+
output: {
|
|
62
|
+
manualChunks(id) {
|
|
63
|
+
if (id.includes('node_modules')) {
|
|
64
|
+
// Split standard Vue dependencies into their own chunk
|
|
65
|
+
if (id.includes('vue') || id.includes('pinia') || id.includes('vue-router')) {
|
|
66
|
+
return 'vue-vendor';
|
|
67
|
+
}
|
|
68
|
+
{{THREEJS_CHUNK}}
|
|
69
|
+
|
|
70
|
+
return 'vendor';
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
esbuild: {
|
|
78
|
+
drop: isProd ? ['console', 'debugger'] : [],
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
package/dist/utils/add-three.js
CHANGED
|
@@ -98,9 +98,24 @@ export async function addThree(currentDir) {
|
|
|
98
98
|
mkdirSync(composablesTargetDir, { recursive: true });
|
|
99
99
|
}
|
|
100
100
|
// Calculate import path from composables/{directoryName} to three folder
|
|
101
|
-
//
|
|
102
|
-
const
|
|
103
|
-
|
|
101
|
+
// The import path should be @/pages/{directoryName}/three/World.js when run in a pages directory
|
|
102
|
+
const currentPathRelative = relative(projectRoot, currentPath).replace(/\\/g, '/');
|
|
103
|
+
// Check if the current path is in a pages directory
|
|
104
|
+
let importPath;
|
|
105
|
+
if (currentPathRelative.startsWith('pages/')) {
|
|
106
|
+
// If we're in a pages directory (Vue), use @/pages/{directoryName}/three/World.js
|
|
107
|
+
importPath = `@/pages/${directoryName}/three/World.js`;
|
|
108
|
+
}
|
|
109
|
+
else if (currentPathRelative.startsWith('app/pages/')) {
|
|
110
|
+
// If we're in app/pages directory (Nuxt), use @/pages/{directoryName}/three/World.js
|
|
111
|
+
// Note: @/ in Nuxt resolves to project root, so app/pages becomes pages
|
|
112
|
+
importPath = `@/pages/${directoryName}/three/World.js`;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Otherwise, use the relative path from project root
|
|
116
|
+
const threePathRelative = relative(projectRoot, targetDir).replace(/\\/g, '/');
|
|
117
|
+
importPath = `@/${threePathRelative}/World.js`;
|
|
118
|
+
}
|
|
104
119
|
// Determine file extension based on project type
|
|
105
120
|
const fileExtension = projectType === 'vue' ? 'js' : 'ts';
|
|
106
121
|
// Create usethree.{js|ts}
|
|
@@ -3,4 +3,5 @@ export declare function generateNuxtConfig(projectPath: string, threejs: boolean
|
|
|
3
3
|
export declare function generateViteConfig(projectPath: string, threejs: boolean, cssVars?: boolean): Promise<void>;
|
|
4
4
|
export declare function generateTailwindConfig(projectPath: string, projectType: ProjectType): Promise<void>;
|
|
5
5
|
export declare function generatePostCSSConfig(projectPath: string): Promise<void>;
|
|
6
|
+
export declare function setupNuxtAppStructure(projectPath: string): Promise<void>;
|
|
6
7
|
export declare function generateConfigFiles(projectType: ProjectType, projectPath: string, threejs: boolean, cssVars: boolean): Promise<void>;
|