@srcroot/ui 0.0.28 → 0.0.32
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 +377 -574
- package/package.json +2 -2
- package/src/registry/analytics/google-analytics.tsx +36 -0
- package/src/registry/analytics/google-tag-manager.tsx +62 -0
- package/src/registry/analytics/meta-pixel.tsx +44 -0
- package/src/registry/analytics/microsoft-clarity.tsx +31 -0
- package/src/registry/analytics/tiktok-pixel.tsx +34 -0
- package/src/registry/lib/utils.ts +6 -0
- package/src/registry/themes/gradients.css +236 -0
- package/{registry/themes → src/registry/themes/v3}/gray.css +45 -1
- package/{registry/themes → src/registry/themes/v3}/neutral.css +45 -1
- package/{registry/themes → src/registry/themes/v3}/slate.css +45 -1
- package/{registry/themes → src/registry/themes/v3}/stone.css +45 -1
- package/{registry/themes → src/registry/themes/v3}/zinc.css +45 -1
- package/src/registry/themes/v4/gray.css +183 -0
- package/src/registry/themes/v4/neutral.css +183 -0
- package/src/registry/themes/v4/slate.css +183 -0
- package/src/registry/themes/v4/stone.css +183 -0
- package/src/registry/themes/v4/zinc.css +183 -0
- package/{registry → src/registry/ui}/carousel.tsx +82 -38
- package/src/registry/ui/chatbot.tsx +96 -0
- package/registry/design-tokens.css +0 -217
- package/registry/themes/index.css +0 -19
- /package/{registry → src/registry/ui}/accordion.tsx +0 -0
- /package/{registry → src/registry/ui}/alert-dialog.tsx +0 -0
- /package/{registry → src/registry/ui}/alert.tsx +0 -0
- /package/{registry → src/registry/ui}/aspect-ratio.tsx +0 -0
- /package/{registry → src/registry/ui}/avatar.tsx +0 -0
- /package/{registry → src/registry/ui}/badge.tsx +0 -0
- /package/{registry → src/registry/ui}/breadcrumb.tsx +0 -0
- /package/{registry → src/registry/ui}/button-group.tsx +0 -0
- /package/{registry → src/registry/ui}/button.tsx +0 -0
- /package/{registry → src/registry/ui}/calendar.tsx +0 -0
- /package/{registry → src/registry/ui}/card.tsx +0 -0
- /package/{registry → src/registry/ui}/checkbox.tsx +0 -0
- /package/{registry → src/registry/ui}/collapsible.tsx +0 -0
- /package/{registry → src/registry/ui}/combobox.tsx +0 -0
- /package/{registry → src/registry/ui}/command.tsx +0 -0
- /package/{registry → src/registry/ui}/container.tsx +0 -0
- /package/{registry → src/registry/ui}/context-menu.tsx +0 -0
- /package/{registry → src/registry/ui}/date-picker.tsx +0 -0
- /package/{registry → src/registry/ui}/dialog.tsx +0 -0
- /package/{registry → src/registry/ui}/drawer.tsx +0 -0
- /package/{registry → src/registry/ui}/dropdown-menu.tsx +0 -0
- /package/{registry → src/registry/ui}/file-upload.tsx +0 -0
- /package/{registry → src/registry/ui}/hover-card.tsx +0 -0
- /package/{registry → src/registry/ui}/image.tsx +0 -0
- /package/{registry → src/registry/ui}/input.tsx +0 -0
- /package/{registry → src/registry/ui}/kbd.tsx +0 -0
- /package/{registry → src/registry/ui}/label.tsx +0 -0
- /package/{registry → src/registry/ui}/loading-spinner.tsx +0 -0
- /package/{registry → src/registry/ui}/menubar.tsx +0 -0
- /package/{registry → src/registry/ui}/native-select.tsx +0 -0
- /package/{registry → src/registry/ui}/otp-input.tsx +0 -0
- /package/{registry → src/registry/ui}/pagination.tsx +0 -0
- /package/{registry → src/registry/ui}/popover.tsx +0 -0
- /package/{registry → src/registry/ui}/progress.tsx +0 -0
- /package/{registry → src/registry/ui}/radio.tsx +0 -0
- /package/{registry → src/registry/ui}/resizable.tsx +0 -0
- /package/{registry → src/registry/ui}/scroll-area.tsx +0 -0
- /package/{registry → src/registry/ui}/search.tsx +0 -0
- /package/{registry → src/registry/ui}/select.tsx +0 -0
- /package/{registry → src/registry/ui}/separator.tsx +0 -0
- /package/{registry → src/registry/ui}/sheet.tsx +0 -0
- /package/{registry → src/registry/ui}/sidebar.tsx +0 -0
- /package/{registry → src/registry/ui}/skeleton.tsx +0 -0
- /package/{registry → src/registry/ui}/slider.tsx +0 -0
- /package/{registry → src/registry/ui}/star-rating.tsx +0 -0
- /package/{registry → src/registry/ui}/switch.tsx +0 -0
- /package/{registry → src/registry/ui}/table.tsx +0 -0
- /package/{registry → src/registry/ui}/tabs.tsx +0 -0
- /package/{registry → src/registry/ui}/text.tsx +0 -0
- /package/{registry → src/registry/ui}/textarea.tsx +0 -0
- /package/{registry → src/registry/ui}/toast.tsx +0 -0
- /package/{registry → src/registry/ui}/toggle-group.tsx +0 -0
- /package/{registry → src/registry/ui}/toggle.tsx +0 -0
- /package/{registry → src/registry/ui}/tooltip.tsx +0 -0
package/dist/index.js
CHANGED
|
@@ -2,425 +2,74 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
+
import chalk4 from "chalk";
|
|
5
6
|
|
|
6
|
-
// src/cli/
|
|
7
|
-
import
|
|
8
|
-
import
|
|
7
|
+
// src/cli/services/project-initializer.ts
|
|
8
|
+
import fs2 from "fs-extra";
|
|
9
|
+
import path2 from "path";
|
|
9
10
|
import chalk from "chalk";
|
|
10
11
|
import ora from "ora";
|
|
11
12
|
import prompts from "prompts";
|
|
13
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
14
|
+
|
|
15
|
+
// src/cli/services/theme-service.ts
|
|
16
|
+
import fs from "fs-extra";
|
|
17
|
+
import path from "path";
|
|
12
18
|
import { fileURLToPath } from "url";
|
|
13
19
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
secondary: "210 40% 96.1%",
|
|
35
|
-
"secondary-foreground": "222.2 47.4% 11.2%",
|
|
36
|
-
muted: "210 40% 96.1%",
|
|
37
|
-
"muted-foreground": "215.4 16.3% 46.9%",
|
|
38
|
-
accent: "210 40% 96.1%",
|
|
39
|
-
"accent-foreground": "222.2 47.4% 11.2%",
|
|
40
|
-
destructive: "0 84.2% 60.2%",
|
|
41
|
-
"destructive-foreground": "210 40% 98%",
|
|
42
|
-
border: "214.3 31.8% 91.4%",
|
|
43
|
-
input: "214.3 31.8% 91.4%",
|
|
44
|
-
ring: "222.2 84% 4.9%"
|
|
45
|
-
},
|
|
46
|
-
dark: {
|
|
47
|
-
background: "222.2 84% 4.9%",
|
|
48
|
-
foreground: "210 40% 98%",
|
|
49
|
-
card: "222.2 84% 4.9%",
|
|
50
|
-
"card-foreground": "210 40% 98%",
|
|
51
|
-
popover: "222.2 84% 4.9%",
|
|
52
|
-
"popover-foreground": "210 40% 98%",
|
|
53
|
-
primary: "210 40% 98%",
|
|
54
|
-
"primary-foreground": "222.2 47.4% 11.2%",
|
|
55
|
-
secondary: "217.2 32.6% 17.5%",
|
|
56
|
-
"secondary-foreground": "210 40% 98%",
|
|
57
|
-
muted: "217.2 32.6% 17.5%",
|
|
58
|
-
"muted-foreground": "215 20.2% 65.1%",
|
|
59
|
-
accent: "217.2 32.6% 17.5%",
|
|
60
|
-
"accent-foreground": "210 40% 98%",
|
|
61
|
-
destructive: "0 62.8% 30.6%",
|
|
62
|
-
"destructive-foreground": "210 40% 98%",
|
|
63
|
-
border: "217.2 32.6% 17.5%",
|
|
64
|
-
input: "217.2 32.6% 17.5%",
|
|
65
|
-
ring: "212.7 26.8% 83.9%"
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
neutral: {
|
|
69
|
-
name: "Neutral",
|
|
70
|
-
description: "Pure gray, no undertones",
|
|
71
|
-
light: {
|
|
72
|
-
background: "0 0% 100%",
|
|
73
|
-
foreground: "0 0% 3.9%",
|
|
74
|
-
card: "0 0% 100%",
|
|
75
|
-
"card-foreground": "0 0% 3.9%",
|
|
76
|
-
popover: "0 0% 100%",
|
|
77
|
-
"popover-foreground": "0 0% 3.9%",
|
|
78
|
-
primary: "0 0% 9%",
|
|
79
|
-
"primary-foreground": "0 0% 98%",
|
|
80
|
-
secondary: "0 0% 96.1%",
|
|
81
|
-
"secondary-foreground": "0 0% 9%",
|
|
82
|
-
muted: "0 0% 96.1%",
|
|
83
|
-
"muted-foreground": "0 0% 45.1%",
|
|
84
|
-
accent: "0 0% 96.1%",
|
|
85
|
-
"accent-foreground": "0 0% 9%",
|
|
86
|
-
destructive: "0 84.2% 60.2%",
|
|
87
|
-
"destructive-foreground": "0 0% 98%",
|
|
88
|
-
border: "0 0% 89.8%",
|
|
89
|
-
input: "0 0% 89.8%",
|
|
90
|
-
ring: "0 0% 3.9%"
|
|
91
|
-
},
|
|
92
|
-
dark: {
|
|
93
|
-
background: "0 0% 3.9%",
|
|
94
|
-
foreground: "0 0% 98%",
|
|
95
|
-
card: "0 0% 3.9%",
|
|
96
|
-
"card-foreground": "0 0% 98%",
|
|
97
|
-
popover: "0 0% 3.9%",
|
|
98
|
-
"popover-foreground": "0 0% 98%",
|
|
99
|
-
primary: "0 0% 98%",
|
|
100
|
-
"primary-foreground": "0 0% 9%",
|
|
101
|
-
secondary: "0 0% 14.9%",
|
|
102
|
-
"secondary-foreground": "0 0% 98%",
|
|
103
|
-
muted: "0 0% 14.9%",
|
|
104
|
-
"muted-foreground": "0 0% 63.9%",
|
|
105
|
-
accent: "0 0% 14.9%",
|
|
106
|
-
"accent-foreground": "0 0% 98%",
|
|
107
|
-
destructive: "0 62.8% 30.6%",
|
|
108
|
-
"destructive-foreground": "0 0% 98%",
|
|
109
|
-
border: "0 0% 14.9%",
|
|
110
|
-
input: "0 0% 14.9%",
|
|
111
|
-
ring: "0 0% 83.1%"
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
stone: {
|
|
115
|
-
name: "Stone",
|
|
116
|
-
description: "Warm gray with brown undertones",
|
|
117
|
-
light: {
|
|
118
|
-
background: "0 0% 100%",
|
|
119
|
-
foreground: "24 9.8% 10%",
|
|
120
|
-
card: "0 0% 100%",
|
|
121
|
-
"card-foreground": "24 9.8% 10%",
|
|
122
|
-
popover: "0 0% 100%",
|
|
123
|
-
"popover-foreground": "24 9.8% 10%",
|
|
124
|
-
primary: "24 9.8% 10%",
|
|
125
|
-
"primary-foreground": "60 9.1% 97.8%",
|
|
126
|
-
secondary: "60 4.8% 95.9%",
|
|
127
|
-
"secondary-foreground": "24 9.8% 10%",
|
|
128
|
-
muted: "60 4.8% 95.9%",
|
|
129
|
-
"muted-foreground": "25 5.3% 44.7%",
|
|
130
|
-
accent: "60 4.8% 95.9%",
|
|
131
|
-
"accent-foreground": "24 9.8% 10%",
|
|
132
|
-
destructive: "0 84.2% 60.2%",
|
|
133
|
-
"destructive-foreground": "60 9.1% 97.8%",
|
|
134
|
-
border: "20 5.9% 90%",
|
|
135
|
-
input: "20 5.9% 90%",
|
|
136
|
-
ring: "24 9.8% 10%"
|
|
137
|
-
},
|
|
138
|
-
dark: {
|
|
139
|
-
background: "24 9.8% 10%",
|
|
140
|
-
foreground: "60 9.1% 97.8%",
|
|
141
|
-
card: "24 9.8% 10%",
|
|
142
|
-
"card-foreground": "60 9.1% 97.8%",
|
|
143
|
-
popover: "24 9.8% 10%",
|
|
144
|
-
"popover-foreground": "60 9.1% 97.8%",
|
|
145
|
-
primary: "60 9.1% 97.8%",
|
|
146
|
-
"primary-foreground": "24 9.8% 10%",
|
|
147
|
-
secondary: "12 6.5% 15.1%",
|
|
148
|
-
"secondary-foreground": "60 9.1% 97.8%",
|
|
149
|
-
muted: "12 6.5% 15.1%",
|
|
150
|
-
"muted-foreground": "24 5.4% 63.9%",
|
|
151
|
-
accent: "12 6.5% 15.1%",
|
|
152
|
-
"accent-foreground": "60 9.1% 97.8%",
|
|
153
|
-
destructive: "0 62.8% 30.6%",
|
|
154
|
-
"destructive-foreground": "60 9.1% 97.8%",
|
|
155
|
-
border: "12 6.5% 15.1%",
|
|
156
|
-
input: "12 6.5% 15.1%",
|
|
157
|
-
ring: "24 5.7% 82.9%"
|
|
20
|
+
var THEME_METADATA = {
|
|
21
|
+
slate: { name: "Slate", description: "Cool gray with strong blue undertones (default)" },
|
|
22
|
+
neutral: { name: "Neutral", description: "Pure gray, no undertones" },
|
|
23
|
+
stone: { name: "Stone", description: "Warm gray with brown undertones" },
|
|
24
|
+
zinc: { name: "Zinc", description: "Cool gray with subtle blue undertones" },
|
|
25
|
+
gray: { name: "Gray", description: "True neutral gray" }
|
|
26
|
+
};
|
|
27
|
+
var ThemeService = class {
|
|
28
|
+
registryThemesPath;
|
|
29
|
+
constructor() {
|
|
30
|
+
this.registryThemesPath = path.resolve(__dirname, "..", "src", "registry", "themes");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get list of available themes from registry/themes/v3/*.css (v3 as primary source)
|
|
34
|
+
*/
|
|
35
|
+
getAvailableThemes() {
|
|
36
|
+
const themes = [];
|
|
37
|
+
const v3Path = path.join(this.registryThemesPath, "v3");
|
|
38
|
+
if (!fs.existsSync(v3Path)) {
|
|
39
|
+
return themes;
|
|
158
40
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
"secondary-foreground": "240 5.9% 10%",
|
|
174
|
-
muted: "240 4.8% 95.9%",
|
|
175
|
-
"muted-foreground": "240 3.8% 46.1%",
|
|
176
|
-
accent: "240 4.8% 95.9%",
|
|
177
|
-
"accent-foreground": "240 5.9% 10%",
|
|
178
|
-
destructive: "0 84.2% 60.2%",
|
|
179
|
-
"destructive-foreground": "0 0% 98%",
|
|
180
|
-
border: "240 5.9% 90%",
|
|
181
|
-
input: "240 5.9% 90%",
|
|
182
|
-
ring: "240 10% 3.9%"
|
|
183
|
-
},
|
|
184
|
-
dark: {
|
|
185
|
-
background: "240 10% 3.9%",
|
|
186
|
-
foreground: "0 0% 98%",
|
|
187
|
-
card: "240 10% 3.9%",
|
|
188
|
-
"card-foreground": "0 0% 98%",
|
|
189
|
-
popover: "240 10% 3.9%",
|
|
190
|
-
"popover-foreground": "0 0% 98%",
|
|
191
|
-
primary: "0 0% 98%",
|
|
192
|
-
"primary-foreground": "240 5.9% 10%",
|
|
193
|
-
secondary: "240 3.7% 15.9%",
|
|
194
|
-
"secondary-foreground": "0 0% 98%",
|
|
195
|
-
muted: "240 3.7% 15.9%",
|
|
196
|
-
"muted-foreground": "240 5% 64.9%",
|
|
197
|
-
accent: "240 3.7% 15.9%",
|
|
198
|
-
"accent-foreground": "0 0% 98%",
|
|
199
|
-
destructive: "0 62.8% 30.6%",
|
|
200
|
-
"destructive-foreground": "0 0% 98%",
|
|
201
|
-
border: "240 3.7% 15.9%",
|
|
202
|
-
input: "240 3.7% 15.9%",
|
|
203
|
-
ring: "240 4.9% 83.9%"
|
|
41
|
+
const files = fs.readdirSync(v3Path);
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
if (file.endsWith(".css")) {
|
|
44
|
+
const themeName = file.replace(".css", "");
|
|
45
|
+
const metadata = THEME_METADATA[themeName] || {
|
|
46
|
+
name: themeName.charAt(0).toUpperCase() + themeName.slice(1),
|
|
47
|
+
description: `${themeName} theme`
|
|
48
|
+
};
|
|
49
|
+
themes.push({
|
|
50
|
+
name: metadata.name,
|
|
51
|
+
description: metadata.description,
|
|
52
|
+
file
|
|
53
|
+
});
|
|
54
|
+
}
|
|
204
55
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
"popover-foreground": "224 71.4% 4.1%",
|
|
216
|
-
primary: "220.9 39.3% 11%",
|
|
217
|
-
"primary-foreground": "210 20% 98%",
|
|
218
|
-
secondary: "220 14.3% 95.9%",
|
|
219
|
-
"secondary-foreground": "220.9 39.3% 11%",
|
|
220
|
-
muted: "220 14.3% 95.9%",
|
|
221
|
-
"muted-foreground": "220 8.9% 46.1%",
|
|
222
|
-
accent: "220 14.3% 95.9%",
|
|
223
|
-
"accent-foreground": "220.9 39.3% 11%",
|
|
224
|
-
destructive: "0 84.2% 60.2%",
|
|
225
|
-
"destructive-foreground": "210 20% 98%",
|
|
226
|
-
border: "220 13% 91%",
|
|
227
|
-
input: "220 13% 91%",
|
|
228
|
-
ring: "224 71.4% 4.1%"
|
|
229
|
-
},
|
|
230
|
-
dark: {
|
|
231
|
-
background: "224 71.4% 4.1%",
|
|
232
|
-
foreground: "210 20% 98%",
|
|
233
|
-
card: "224 71.4% 4.1%",
|
|
234
|
-
"card-foreground": "210 20% 98%",
|
|
235
|
-
popover: "224 71.4% 4.1%",
|
|
236
|
-
"popover-foreground": "210 20% 98%",
|
|
237
|
-
primary: "210 20% 98%",
|
|
238
|
-
"primary-foreground": "220.9 39.3% 11%",
|
|
239
|
-
secondary: "215 27.9% 16.9%",
|
|
240
|
-
"secondary-foreground": "210 20% 98%",
|
|
241
|
-
muted: "215 27.9% 16.9%",
|
|
242
|
-
"muted-foreground": "217.9 10.6% 64.9%",
|
|
243
|
-
accent: "215 27.9% 16.9%",
|
|
244
|
-
"accent-foreground": "210 20% 98%",
|
|
245
|
-
destructive: "0 62.8% 30.6%",
|
|
246
|
-
"destructive-foreground": "210 20% 98%",
|
|
247
|
-
border: "215 27.9% 16.9%",
|
|
248
|
-
input: "215 27.9% 16.9%",
|
|
249
|
-
ring: "216 12.2% 83.9%"
|
|
56
|
+
return themes;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the complete CSS content for a theme from the appropriate v3 or v4 folder
|
|
60
|
+
*/
|
|
61
|
+
async getThemeCss(themeName, isTailwind4) {
|
|
62
|
+
const versionFolder = isTailwind4 ? "v4" : "v3";
|
|
63
|
+
const themeFilePath = path.join(this.registryThemesPath, versionFolder, `${themeName}.css`);
|
|
64
|
+
if (!fs.existsSync(themeFilePath)) {
|
|
65
|
+
throw new Error(`Theme file not found: ${themeFilePath}`);
|
|
250
66
|
}
|
|
67
|
+
const content = await fs.readFile(themeFilePath, "utf-8");
|
|
68
|
+
return content;
|
|
251
69
|
}
|
|
252
70
|
};
|
|
253
|
-
function generateCssVariablesV3(themeName) {
|
|
254
|
-
const theme = THEMES[themeName];
|
|
255
|
-
if (!theme) return "";
|
|
256
|
-
const lightVars = Object.entries(theme.light).map(([key, value]) => ` --${key}: ${value};`).join("\n");
|
|
257
|
-
const darkVars = Object.entries(theme.dark).map(([key, value]) => ` --${key}: ${value};`).join("\n");
|
|
258
|
-
return `@tailwind base;
|
|
259
|
-
@tailwind components;
|
|
260
|
-
@tailwind utilities;
|
|
261
|
-
|
|
262
|
-
@layer base {
|
|
263
|
-
:root {
|
|
264
|
-
${lightVars}
|
|
265
|
-
--radius: 0.5rem;
|
|
266
|
-
--sidebar-width: 16rem;
|
|
267
|
-
--sidebar-width-mobile: 18rem;
|
|
268
|
-
--sidebar-width-collapsed: 3rem;
|
|
269
|
-
--sidebar-width-icon: 3rem;
|
|
270
|
-
--header-height: 3.5rem;
|
|
271
|
-
--sidebar-background: 0 0% 98%;
|
|
272
|
-
--sidebar-foreground: 240 5.3% 26.1%;
|
|
273
|
-
--sidebar-primary: 240 5.9% 10%;
|
|
274
|
-
--sidebar-primary-foreground: 0 0% 98%;
|
|
275
|
-
--sidebar-accent: 240 4.8% 95.9%;
|
|
276
|
-
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
277
|
-
--sidebar-border: 220 13% 91%;
|
|
278
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
.dark {
|
|
282
|
-
${darkVars}
|
|
283
|
-
--sidebar-background: 240 5.9% 10%;
|
|
284
|
-
--sidebar-foreground: 240 4.8% 95.9%;
|
|
285
|
-
--sidebar-primary: 224.3 76.3% 48%;
|
|
286
|
-
--sidebar-primary-foreground: 0 0% 100%;
|
|
287
|
-
--sidebar-accent: 240 3.7% 15.9%;
|
|
288
|
-
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
289
|
-
--sidebar-border: 240 3.7% 15.9%;
|
|
290
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
@layer base {
|
|
295
|
-
* {
|
|
296
|
-
@apply border-border;
|
|
297
|
-
}
|
|
298
|
-
body {
|
|
299
|
-
@apply bg-background text-foreground;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
@layer utilities {
|
|
304
|
-
@keyframes accordion-down {
|
|
305
|
-
from { height: 0; }
|
|
306
|
-
to { height: var(--radix-accordion-content-height); }
|
|
307
|
-
}
|
|
308
|
-
@keyframes accordion-up {
|
|
309
|
-
from { height: var(--radix-accordion-content-height); }
|
|
310
|
-
to { height: 0; }
|
|
311
|
-
}
|
|
312
|
-
.animate-accordion-down {
|
|
313
|
-
animation: accordion-down 0.2s ease-out;
|
|
314
|
-
}
|
|
315
|
-
.animate-accordion-up {
|
|
316
|
-
animation: accordion-up 0.2s ease-out;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
`;
|
|
320
|
-
}
|
|
321
|
-
function generateCssVariablesV4(themeName) {
|
|
322
|
-
const theme = THEMES[themeName];
|
|
323
|
-
if (!theme) return "";
|
|
324
|
-
const lightVars = Object.entries(theme.light).map(([key, value]) => ` --${key}: ${value};`).join("\n");
|
|
325
|
-
const darkVars = Object.entries(theme.dark).map(([key, value]) => ` --${key}: ${value};`).join("\n");
|
|
326
|
-
const lightVarsHsl = Object.entries(theme.light).map(([key, value]) => ` --${key}: hsl(${value});`).join("\n");
|
|
327
|
-
const darkVarsHsl = Object.entries(theme.dark).map(([key, value]) => ` --${key}: hsl(${value});`).join("\n");
|
|
328
|
-
return `@import "tailwindcss";
|
|
329
|
-
|
|
330
|
-
:root {
|
|
331
|
-
${lightVarsHsl}
|
|
332
|
-
--radius: 0.5rem;
|
|
333
|
-
--sidebar-width: 16rem;
|
|
334
|
-
--sidebar-width-mobile: 18rem;
|
|
335
|
-
--sidebar-width-collapsed: 3rem;
|
|
336
|
-
--sidebar-width-icon: 3rem;
|
|
337
|
-
--header-height: 3.5rem;
|
|
338
|
-
--sidebar-background: 0 0% 98%;
|
|
339
|
-
--sidebar-foreground: 240 5.3% 26.1%;
|
|
340
|
-
--sidebar-primary: 240 5.9% 10%;
|
|
341
|
-
--sidebar-primary-foreground: 0 0% 98%;
|
|
342
|
-
--sidebar-accent: 240 4.8% 95.9%;
|
|
343
|
-
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
344
|
-
--sidebar-border: 220 13% 91%;
|
|
345
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
@theme inline {
|
|
349
|
-
--color-border: var(--border);
|
|
350
|
-
--color-input: var(--input);
|
|
351
|
-
--color-ring: var(--ring);
|
|
352
|
-
--color-background: var(--background);
|
|
353
|
-
--color-foreground: var(--foreground);
|
|
354
|
-
|
|
355
|
-
--color-primary: var(--primary);
|
|
356
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
357
|
-
|
|
358
|
-
--color-secondary: var(--secondary);
|
|
359
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
360
|
-
|
|
361
|
-
--color-destructive: var(--destructive);
|
|
362
|
-
--color-destructive-foreground: var(--destructive-foreground);
|
|
363
|
-
|
|
364
|
-
--color-muted: var(--muted);
|
|
365
|
-
--color-muted-foreground: var(--muted-foreground);
|
|
366
|
-
|
|
367
|
-
--color-accent: var(--accent);
|
|
368
|
-
--color-accent-foreground: var(--accent-foreground);
|
|
369
|
-
|
|
370
|
-
--color-popover: var(--popover);
|
|
371
|
-
--color-popover-foreground: var(--popover-foreground);
|
|
372
|
-
|
|
373
|
-
--color-card: var(--card);
|
|
374
|
-
--color-card-foreground: var(--card-foreground);
|
|
375
|
-
|
|
376
|
-
--color-sidebar: var(--sidebar-background);
|
|
377
|
-
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
378
|
-
--color-sidebar-primary: var(--sidebar-primary);
|
|
379
|
-
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
380
|
-
--color-sidebar-accent: var(--sidebar-accent);
|
|
381
|
-
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
382
|
-
--color-sidebar-border: var(--sidebar-border);
|
|
383
|
-
--color-sidebar-ring: var(--sidebar-ring);
|
|
384
|
-
|
|
385
|
-
--radius-lg: var(--radius);
|
|
386
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
387
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
388
|
-
|
|
389
|
-
/* Accordion Animations */
|
|
390
|
-
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
391
|
-
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
392
|
-
|
|
393
|
-
@keyframes accordion-down {
|
|
394
|
-
from { height: 0; }
|
|
395
|
-
to { height: var(--radix-accordion-content-height); }
|
|
396
|
-
}
|
|
397
|
-
@keyframes accordion-up {
|
|
398
|
-
from { height: var(--radix-accordion-content-height); }
|
|
399
|
-
to { height: 0; }
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
@media (prefers-color-scheme: dark) {
|
|
404
|
-
:root {
|
|
405
|
-
${darkVarsHsl}
|
|
406
|
-
--sidebar-background: 240 5.9% 10%;
|
|
407
|
-
--sidebar-foreground: 240 4.8% 95.9%;
|
|
408
|
-
--sidebar-primary: 224.3 76.3% 48%;
|
|
409
|
-
--sidebar-primary-foreground: 0 0% 100%;
|
|
410
|
-
--sidebar-accent: 240 3.7% 15.9%;
|
|
411
|
-
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
412
|
-
--sidebar-border: 240 3.7% 15.9%;
|
|
413
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
71
|
|
|
417
|
-
|
|
418
|
-
background: var(--background);
|
|
419
|
-
color: var(--foreground);
|
|
420
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
421
|
-
}
|
|
422
|
-
`;
|
|
423
|
-
}
|
|
72
|
+
// src/cli/utils/templates.ts
|
|
424
73
|
var TAILWIND_CONFIG = `import type { Config } from "tailwindcss"
|
|
425
74
|
|
|
426
75
|
const config: Config = {
|
|
@@ -493,473 +142,584 @@ const config: Config = {
|
|
|
493
142
|
|
|
494
143
|
export default config
|
|
495
144
|
`;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
507
|
-
console.log(chalk.red("Error: No package.json found. Please run this in a project directory."));
|
|
508
|
-
process.exit(1);
|
|
145
|
+
|
|
146
|
+
// src/cli/services/project-initializer.ts
|
|
147
|
+
var __dirname3 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
148
|
+
var ProjectInitializer = class {
|
|
149
|
+
options;
|
|
150
|
+
config = {};
|
|
151
|
+
themeService;
|
|
152
|
+
constructor(options) {
|
|
153
|
+
this.options = options;
|
|
154
|
+
this.themeService = new ThemeService();
|
|
509
155
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
156
|
+
async run() {
|
|
157
|
+
console.log(chalk.cyan("\n\u{1F680} Initializing @srcroot/ui...\n"));
|
|
158
|
+
await this.validateEnvironment();
|
|
159
|
+
await this.detectConfiguration();
|
|
160
|
+
await this.promptUser();
|
|
161
|
+
await this.scaffold();
|
|
162
|
+
this.printSuccess();
|
|
163
|
+
}
|
|
164
|
+
async validateEnvironment() {
|
|
165
|
+
const cwd = path2.resolve(this.options.cwd);
|
|
166
|
+
const packageJsonPath = path2.join(cwd, "package.json");
|
|
167
|
+
if (!fs2.existsSync(packageJsonPath)) {
|
|
168
|
+
console.log(chalk.red("Error: No package.json found. Please run this in a project directory."));
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const pkg = await fs2.readJson(packageJsonPath);
|
|
172
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
173
|
+
if (!allDeps["react"]) {
|
|
174
|
+
console.log(chalk.red("Error: React not found in dependencies. Please initialize this in a React project."));
|
|
175
|
+
process.exit(1);
|
|
530
176
|
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
177
|
+
}
|
|
178
|
+
async detectConfiguration() {
|
|
179
|
+
const cwd = path2.resolve(this.options.cwd);
|
|
180
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
181
|
+
const isYarn = userAgent.includes("yarn");
|
|
182
|
+
const isPnpm = userAgent.includes("pnpm");
|
|
183
|
+
const isBun = userAgent.includes("bun");
|
|
184
|
+
const packageManager = isPnpm ? "pnpm" : isYarn ? "yarn" : isBun ? "bun" : "npm";
|
|
185
|
+
const installCmd = isPnpm ? "add" : isYarn ? "add" : isBun ? "add" : "install";
|
|
186
|
+
const pkg = await fs2.readJson(path2.join(cwd, "package.json"));
|
|
187
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
188
|
+
const tailwindVersion = allDeps["tailwindcss"] || "";
|
|
189
|
+
const isTailwind4 = tailwindVersion.includes("^4") || tailwindVersion.startsWith("4") || allDeps["@tailwindcss/postcss"];
|
|
190
|
+
const hasSrc = fs2.existsSync(path2.join(cwd, "src"));
|
|
191
|
+
const srcPath = hasSrc ? path2.join(cwd, "src") : cwd;
|
|
192
|
+
const appPath = path2.join(srcPath, "app");
|
|
193
|
+
const pagesPath = path2.join(srcPath, "pages");
|
|
194
|
+
const hasAppDir = fs2.existsSync(appPath);
|
|
195
|
+
const hasPagesDir = fs2.existsSync(pagesPath);
|
|
196
|
+
const libDir = path2.join(srcPath, "lib");
|
|
197
|
+
const componentsDir = path2.join(srcPath, "components", "ui");
|
|
198
|
+
let globalsPath = "";
|
|
199
|
+
if (hasAppDir) {
|
|
200
|
+
if (fs2.existsSync(path2.join(appPath, "globals.css"))) globalsPath = path2.join(appPath, "globals.css");
|
|
201
|
+
else if (fs2.existsSync(path2.join(appPath, "global.css"))) globalsPath = path2.join(appPath, "global.css");
|
|
202
|
+
else globalsPath = path2.join(appPath, "globals.css");
|
|
203
|
+
} else if (hasPagesDir) {
|
|
204
|
+
const stylesPath = path2.join(srcPath, "styles");
|
|
205
|
+
if (fs2.existsSync(path2.join(stylesPath, "globals.css"))) globalsPath = path2.join(stylesPath, "globals.css");
|
|
206
|
+
else if (fs2.existsSync(path2.join(stylesPath, "global.css"))) globalsPath = path2.join(stylesPath, "global.css");
|
|
207
|
+
else globalsPath = path2.join(stylesPath, "globals.css");
|
|
537
208
|
} else {
|
|
538
|
-
globalsPath =
|
|
209
|
+
globalsPath = path2.join(srcPath, "globals.css");
|
|
539
210
|
}
|
|
540
|
-
|
|
541
|
-
|
|
211
|
+
this.config = {
|
|
212
|
+
cwd,
|
|
213
|
+
packageManager,
|
|
214
|
+
installCmd,
|
|
215
|
+
isTailwind4,
|
|
216
|
+
hasSrc,
|
|
217
|
+
srcPath,
|
|
218
|
+
appPath,
|
|
219
|
+
pagesPath,
|
|
220
|
+
hasAppDir,
|
|
221
|
+
hasPagesDir,
|
|
222
|
+
libDir,
|
|
223
|
+
componentsDir,
|
|
224
|
+
globalsPath
|
|
225
|
+
};
|
|
542
226
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
227
|
+
async promptUser() {
|
|
228
|
+
let selectedTheme = this.options.theme || "slate";
|
|
229
|
+
if (!this.options.yes && !this.options.theme) {
|
|
230
|
+
const availableThemes = this.themeService.getAvailableThemes();
|
|
231
|
+
if (availableThemes.length === 0) {
|
|
232
|
+
console.log(chalk.yellow("Warning: No themes found in registry. Using default."));
|
|
233
|
+
this.config.selectedTheme = selectedTheme;
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const themeChoices = availableThemes.map((theme) => ({
|
|
237
|
+
title: `${theme.name} - ${chalk.dim(theme.description)}`,
|
|
238
|
+
value: theme.file.replace(".css", "")
|
|
239
|
+
}));
|
|
240
|
+
const themeResponse = await prompts({
|
|
241
|
+
type: "select",
|
|
242
|
+
name: "theme",
|
|
243
|
+
message: "Which color theme would you like to use?",
|
|
244
|
+
choices: themeChoices,
|
|
245
|
+
initial: 0
|
|
246
|
+
});
|
|
247
|
+
if (themeResponse.theme) {
|
|
248
|
+
selectedTheme = themeResponse.theme;
|
|
249
|
+
}
|
|
559
250
|
}
|
|
251
|
+
this.config.selectedTheme = selectedTheme;
|
|
560
252
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
253
|
+
async scaffold() {
|
|
254
|
+
const spinner = ora("Creating project structure...").start();
|
|
255
|
+
const cfg = this.config;
|
|
256
|
+
try {
|
|
257
|
+
await fs2.ensureDir(cfg.libDir);
|
|
258
|
+
await fs2.ensureDir(cfg.componentsDir);
|
|
259
|
+
const utilsPath = path2.join(cfg.libDir, "utils.ts");
|
|
260
|
+
const registryUtilsPath = path2.resolve(__dirname3, "..", "src", "registry", "lib", "utils.ts");
|
|
261
|
+
let utilsContent = "";
|
|
262
|
+
if (fs2.existsSync(registryUtilsPath)) {
|
|
263
|
+
utilsContent = await fs2.readFile(registryUtilsPath, "utf-8");
|
|
264
|
+
} else {
|
|
265
|
+
utilsContent = `import { type ClassValue, clsx } from "clsx"
|
|
266
|
+
import { twMerge } from "tailwind-merge"
|
|
267
|
+
|
|
268
|
+
export function cn(...inputs: ClassValue[]) {
|
|
269
|
+
return twMerge(clsx(inputs))
|
|
270
|
+
}
|
|
271
|
+
`;
|
|
272
|
+
spinner.warn(`Could not find registry/utils.ts, using fallback content.`);
|
|
273
|
+
}
|
|
274
|
+
await fs2.writeFile(utilsPath, utilsContent);
|
|
275
|
+
spinner.succeed(`Created ${chalk.cyan(path2.relative(cfg.cwd, utilsPath))}`);
|
|
276
|
+
spinner.start(`Setting up ${chalk.cyan(cfg.selectedTheme)} theme...`);
|
|
277
|
+
const stylesDir = path2.dirname(cfg.globalsPath);
|
|
278
|
+
await fs2.ensureDir(stylesDir);
|
|
279
|
+
try {
|
|
280
|
+
const cssContent = await this.themeService.getThemeCss(cfg.selectedTheme, cfg.isTailwind4);
|
|
281
|
+
await fs2.writeFile(cfg.globalsPath, cssContent);
|
|
282
|
+
spinner.succeed(`Updated ${chalk.cyan(path2.relative(cfg.cwd, cfg.globalsPath))} with ${chalk.cyan(cfg.selectedTheme)} theme (${cfg.isTailwind4 ? "Tailwind 4" : "Tailwind 3"})`);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
spinner.fail(`Failed to load theme: ${cfg.selectedTheme}`);
|
|
285
|
+
console.error(error);
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
if (!cfg.isTailwind4) {
|
|
289
|
+
spinner.start("Setting up Tailwind config...");
|
|
290
|
+
const tailwindConfigPath = path2.join(cfg.cwd, "tailwind.config.ts");
|
|
291
|
+
await fs2.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
|
|
292
|
+
spinner.succeed(`Created ${chalk.cyan("tailwind.config.ts")}`);
|
|
293
|
+
} else {
|
|
294
|
+
spinner.info(`Tailwind 4 detected - skipping ${chalk.cyan("tailwind.config.ts")}`);
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
spinner.fail("Failed to initialize project");
|
|
298
|
+
console.error(error);
|
|
299
|
+
process.exit(1);
|
|
581
300
|
}
|
|
301
|
+
}
|
|
302
|
+
printSuccess() {
|
|
303
|
+
const cfg = this.config;
|
|
582
304
|
console.log(chalk.green("\n\u2705 Project initialized successfully!\n"));
|
|
583
|
-
console.log(`Theme: ${chalk.cyan(
|
|
584
|
-
console.log(`Tailwind: ${chalk.cyan(isTailwind4 ? "v4" : "v3")}`);
|
|
305
|
+
console.log(`Theme: ${chalk.cyan(cfg.selectedTheme)}`);
|
|
306
|
+
console.log(`Tailwind: ${chalk.cyan(cfg.isTailwind4 ? "v4" : "v3")}`);
|
|
585
307
|
const requiredDeps = [
|
|
586
308
|
"clsx",
|
|
587
309
|
"tailwind-merge",
|
|
588
310
|
"class-variance-authority",
|
|
589
311
|
"react-icons"
|
|
590
312
|
];
|
|
591
|
-
if (!isTailwind4) {
|
|
313
|
+
if (!cfg.isTailwind4) {
|
|
592
314
|
requiredDeps.push("tailwindcss-animate");
|
|
593
315
|
}
|
|
594
316
|
console.log(chalk.cyan("\n\u{1F4E6} Required dependencies:"));
|
|
595
|
-
console.log(chalk.dim(` ${packageManager} ${installCmd} ${requiredDeps.join(" ")}`));
|
|
317
|
+
console.log(chalk.dim(` ${cfg.packageManager} ${cfg.installCmd} ${requiredDeps.join(" ")}`));
|
|
596
318
|
console.log("\n\u2728 Next steps:");
|
|
597
319
|
console.log(chalk.dim(" 1. Install dependencies (command above)"));
|
|
598
320
|
console.log(chalk.dim(" 2. npx @srcroot/ui add button"));
|
|
599
321
|
console.log(chalk.dim(" 3. npx @srcroot/ui add --all"));
|
|
600
322
|
console.log();
|
|
601
|
-
} catch (error) {
|
|
602
|
-
spinner.fail("Failed to initialize project");
|
|
603
|
-
console.error(error);
|
|
604
|
-
process.exit(1);
|
|
605
323
|
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/cli/commands/init.ts
|
|
327
|
+
async function init(options) {
|
|
328
|
+
const initializer = new ProjectInitializer(options);
|
|
329
|
+
await initializer.run();
|
|
606
330
|
}
|
|
607
331
|
|
|
608
332
|
// src/cli/commands/add.ts
|
|
609
|
-
import
|
|
610
|
-
import
|
|
333
|
+
import fs3 from "fs-extra";
|
|
334
|
+
import path3 from "path";
|
|
611
335
|
import chalk2 from "chalk";
|
|
612
336
|
import ora2 from "ora";
|
|
613
337
|
import prompts2 from "prompts";
|
|
614
|
-
import { fileURLToPath as
|
|
338
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
615
339
|
|
|
616
340
|
// src/cli/registry.ts
|
|
617
341
|
var REGISTRY = {
|
|
618
342
|
// Core
|
|
619
343
|
button: {
|
|
620
|
-
file: "button.tsx",
|
|
344
|
+
file: "ui/button.tsx",
|
|
621
345
|
description: "Polymorphic button with variants",
|
|
622
346
|
category: "Core",
|
|
623
347
|
dependencies: []
|
|
624
348
|
},
|
|
625
349
|
badge: {
|
|
626
|
-
file: "badge.tsx",
|
|
350
|
+
file: "ui/badge.tsx",
|
|
627
351
|
description: "Status indicator",
|
|
628
352
|
category: "Core",
|
|
629
353
|
dependencies: []
|
|
630
354
|
},
|
|
631
355
|
avatar: {
|
|
632
|
-
file: "avatar.tsx",
|
|
356
|
+
file: "ui/avatar.tsx",
|
|
633
357
|
description: "User avatar with fallback",
|
|
634
358
|
category: "Core",
|
|
635
359
|
dependencies: []
|
|
636
360
|
},
|
|
637
361
|
separator: {
|
|
638
|
-
file: "separator.tsx",
|
|
362
|
+
file: "ui/separator.tsx",
|
|
639
363
|
description: "Visual divider",
|
|
640
364
|
category: "Core",
|
|
641
365
|
dependencies: []
|
|
642
366
|
},
|
|
643
367
|
// Typography
|
|
644
368
|
text: {
|
|
645
|
-
file: "text.tsx",
|
|
369
|
+
file: "ui/text.tsx",
|
|
646
370
|
description: "Polymorphic typography",
|
|
647
371
|
category: "Typography",
|
|
648
372
|
dependencies: []
|
|
649
373
|
},
|
|
650
374
|
label: {
|
|
651
|
-
file: "label.tsx",
|
|
375
|
+
file: "ui/label.tsx",
|
|
652
376
|
description: "Form label",
|
|
653
377
|
category: "Typography",
|
|
654
378
|
dependencies: []
|
|
655
379
|
},
|
|
656
380
|
// Forms
|
|
657
381
|
input: {
|
|
658
|
-
file: "input.tsx",
|
|
382
|
+
file: "ui/input.tsx",
|
|
659
383
|
description: "Text input field",
|
|
660
384
|
category: "Forms",
|
|
661
385
|
dependencies: []
|
|
662
386
|
},
|
|
663
387
|
textarea: {
|
|
664
|
-
file: "textarea.tsx",
|
|
388
|
+
file: "ui/textarea.tsx",
|
|
665
389
|
description: "Multi-line text input",
|
|
666
390
|
category: "Forms",
|
|
667
391
|
dependencies: []
|
|
668
392
|
},
|
|
669
393
|
checkbox: {
|
|
670
|
-
file: "checkbox.tsx",
|
|
394
|
+
file: "ui/checkbox.tsx",
|
|
671
395
|
description: "Checkbox input",
|
|
672
396
|
category: "Forms",
|
|
673
397
|
dependencies: []
|
|
674
398
|
},
|
|
675
399
|
radio: {
|
|
676
|
-
file: "radio.tsx",
|
|
400
|
+
file: "ui/radio.tsx",
|
|
677
401
|
description: "Radio button group",
|
|
678
402
|
category: "Forms",
|
|
679
403
|
dependencies: []
|
|
680
404
|
},
|
|
681
405
|
switch: {
|
|
682
|
-
file: "switch.tsx",
|
|
406
|
+
file: "ui/switch.tsx",
|
|
683
407
|
description: "Toggle switch",
|
|
684
408
|
category: "Forms",
|
|
685
409
|
dependencies: []
|
|
686
410
|
},
|
|
687
411
|
slider: {
|
|
688
|
-
file: "slider.tsx",
|
|
412
|
+
file: "ui/slider.tsx",
|
|
689
413
|
description: "Range slider",
|
|
690
414
|
category: "Forms",
|
|
691
415
|
dependencies: []
|
|
692
416
|
},
|
|
693
417
|
select: {
|
|
694
|
-
file: "select.tsx",
|
|
418
|
+
file: "ui/select.tsx",
|
|
695
419
|
description: "Custom select dropdown",
|
|
696
420
|
category: "Forms",
|
|
697
421
|
dependencies: []
|
|
698
422
|
},
|
|
699
423
|
// Layout
|
|
700
424
|
card: {
|
|
701
|
-
file: "card.tsx",
|
|
425
|
+
file: "ui/card.tsx",
|
|
702
426
|
description: "Card container",
|
|
703
427
|
category: "Layout",
|
|
704
428
|
dependencies: []
|
|
705
429
|
},
|
|
706
430
|
container: {
|
|
707
|
-
file: "container.tsx",
|
|
431
|
+
file: "ui/container.tsx",
|
|
708
432
|
description: "Max-width container",
|
|
709
433
|
category: "Layout",
|
|
710
434
|
dependencies: []
|
|
711
435
|
},
|
|
712
436
|
"aspect-ratio": {
|
|
713
|
-
file: "aspect-ratio.tsx",
|
|
437
|
+
file: "ui/aspect-ratio.tsx",
|
|
714
438
|
description: "Maintain aspect ratio",
|
|
715
439
|
category: "Layout",
|
|
716
440
|
dependencies: []
|
|
717
441
|
},
|
|
718
442
|
// Data Display
|
|
719
443
|
accordion: {
|
|
720
|
-
file: "accordion.tsx",
|
|
444
|
+
file: "ui/accordion.tsx",
|
|
721
445
|
description: "Expandable sections",
|
|
722
446
|
category: "Data Display",
|
|
723
447
|
dependencies: []
|
|
724
448
|
},
|
|
725
449
|
tabs: {
|
|
726
|
-
file: "tabs.tsx",
|
|
450
|
+
file: "ui/tabs.tsx",
|
|
727
451
|
description: "Tab navigation",
|
|
728
452
|
category: "Data Display",
|
|
729
453
|
dependencies: []
|
|
730
454
|
},
|
|
731
455
|
table: {
|
|
732
|
-
file: "table.tsx",
|
|
456
|
+
file: "ui/table.tsx",
|
|
733
457
|
description: "Data table",
|
|
734
458
|
category: "Data Display",
|
|
735
459
|
dependencies: []
|
|
736
460
|
},
|
|
737
461
|
progress: {
|
|
738
|
-
file: "progress.tsx",
|
|
462
|
+
file: "ui/progress.tsx",
|
|
739
463
|
description: "Progress indicator",
|
|
740
464
|
category: "Data Display",
|
|
741
465
|
dependencies: []
|
|
742
466
|
},
|
|
743
467
|
skeleton: {
|
|
744
|
-
file: "skeleton.tsx",
|
|
468
|
+
file: "ui/skeleton.tsx",
|
|
745
469
|
description: "Loading placeholder",
|
|
746
470
|
category: "Data Display",
|
|
747
471
|
dependencies: []
|
|
748
472
|
},
|
|
749
473
|
// Overlay / Feedback
|
|
750
474
|
dialog: {
|
|
751
|
-
file: "dialog.tsx",
|
|
475
|
+
file: "ui/dialog.tsx",
|
|
752
476
|
description: "Modal dialog",
|
|
753
477
|
category: "Overlay / Feedback",
|
|
754
478
|
dependencies: []
|
|
755
479
|
},
|
|
756
480
|
"alert-dialog": {
|
|
757
|
-
file: "alert-dialog.tsx",
|
|
481
|
+
file: "ui/alert-dialog.tsx",
|
|
758
482
|
description: "Confirmation dialog",
|
|
759
483
|
category: "Overlay / Feedback",
|
|
760
484
|
dependencies: ["dialog"]
|
|
761
485
|
},
|
|
762
486
|
sheet: {
|
|
763
|
-
file: "sheet.tsx",
|
|
487
|
+
file: "ui/sheet.tsx",
|
|
764
488
|
description: "Slide-in panel",
|
|
765
489
|
category: "Overlay / Feedback",
|
|
766
490
|
dependencies: []
|
|
767
491
|
},
|
|
768
492
|
popover: {
|
|
769
|
-
file: "popover.tsx",
|
|
493
|
+
file: "ui/popover.tsx",
|
|
770
494
|
description: "Floating content",
|
|
771
495
|
category: "Overlay / Feedback",
|
|
772
496
|
dependencies: []
|
|
773
497
|
},
|
|
774
498
|
tooltip: {
|
|
775
|
-
file: "tooltip.tsx",
|
|
499
|
+
file: "ui/tooltip.tsx",
|
|
776
500
|
description: "Hover tooltip",
|
|
777
501
|
category: "Overlay / Feedback",
|
|
778
502
|
dependencies: []
|
|
779
503
|
},
|
|
780
504
|
"dropdown-menu": {
|
|
781
|
-
file: "dropdown-menu.tsx",
|
|
505
|
+
file: "ui/dropdown-menu.tsx",
|
|
782
506
|
description: "Action dropdown",
|
|
783
507
|
category: "Overlay / Feedback",
|
|
784
508
|
dependencies: []
|
|
785
509
|
},
|
|
786
510
|
toast: {
|
|
787
|
-
file: "toast.tsx",
|
|
511
|
+
file: "ui/toast.tsx",
|
|
788
512
|
description: "Notification toast",
|
|
789
513
|
category: "Overlay / Feedback",
|
|
790
514
|
dependencies: []
|
|
791
515
|
},
|
|
792
516
|
alert: {
|
|
793
|
-
file: "alert.tsx",
|
|
517
|
+
file: "ui/alert.tsx",
|
|
794
518
|
description: "Inline alert",
|
|
795
519
|
category: "Overlay / Feedback",
|
|
796
520
|
dependencies: []
|
|
797
521
|
},
|
|
798
522
|
// Navigation
|
|
799
523
|
breadcrumb: {
|
|
800
|
-
file: "breadcrumb.tsx",
|
|
524
|
+
file: "ui/breadcrumb.tsx",
|
|
801
525
|
description: "Breadcrumb navigation",
|
|
802
526
|
category: "Navigation",
|
|
803
527
|
dependencies: []
|
|
804
528
|
},
|
|
805
529
|
pagination: {
|
|
806
|
-
file: "pagination.tsx",
|
|
530
|
+
file: "ui/pagination.tsx",
|
|
807
531
|
description: "Page navigation",
|
|
808
532
|
category: "Navigation",
|
|
809
533
|
dependencies: ["button"]
|
|
810
534
|
},
|
|
811
535
|
// New Components
|
|
812
536
|
"loading-spinner": {
|
|
813
|
-
file: "loading-spinner.tsx",
|
|
537
|
+
file: "ui/loading-spinner.tsx",
|
|
814
538
|
description: "Loading spinner with variants",
|
|
815
539
|
category: "Feedback",
|
|
816
540
|
dependencies: []
|
|
817
541
|
},
|
|
818
542
|
image: {
|
|
819
|
-
file: "image.tsx",
|
|
543
|
+
file: "ui/image.tsx",
|
|
820
544
|
description: "Enhanced image with loading",
|
|
821
545
|
category: "Data Display",
|
|
822
546
|
dependencies: []
|
|
823
547
|
},
|
|
824
548
|
"button-group": {
|
|
825
|
-
file: "button-group.tsx",
|
|
549
|
+
file: "ui/button-group.tsx",
|
|
826
550
|
description: "Group buttons together",
|
|
827
551
|
category: "Core",
|
|
828
552
|
dependencies: ["button"]
|
|
829
553
|
},
|
|
830
554
|
"otp-input": {
|
|
831
|
-
file: "otp-input.tsx",
|
|
555
|
+
file: "ui/otp-input.tsx",
|
|
832
556
|
description: "OTP verification input",
|
|
833
557
|
category: "Forms",
|
|
834
558
|
dependencies: []
|
|
835
559
|
},
|
|
836
560
|
search: {
|
|
837
|
-
file: "search.tsx",
|
|
561
|
+
file: "ui/search.tsx",
|
|
838
562
|
description: "Search input with debounce",
|
|
839
563
|
category: "Forms",
|
|
840
564
|
dependencies: []
|
|
841
565
|
},
|
|
842
566
|
"star-rating": {
|
|
843
|
-
file: "star-rating.tsx",
|
|
567
|
+
file: "ui/star-rating.tsx",
|
|
844
568
|
description: "Star rating input",
|
|
845
569
|
category: "Feedback",
|
|
846
570
|
dependencies: []
|
|
847
571
|
},
|
|
848
572
|
collapsible: {
|
|
849
|
-
file: "collapsible.tsx",
|
|
573
|
+
file: "ui/collapsible.tsx",
|
|
850
574
|
description: "Expandable section",
|
|
851
575
|
category: "Data Display",
|
|
852
576
|
dependencies: []
|
|
853
577
|
},
|
|
854
578
|
carousel: {
|
|
855
|
-
file: "carousel.tsx",
|
|
579
|
+
file: "ui/carousel.tsx",
|
|
856
580
|
description: "Image/content slider",
|
|
857
581
|
category: "Data Display",
|
|
858
582
|
dependencies: []
|
|
859
583
|
},
|
|
860
584
|
calendar: {
|
|
861
|
-
file: "calendar.tsx",
|
|
585
|
+
file: "ui/calendar.tsx",
|
|
862
586
|
description: "Date picker",
|
|
863
587
|
category: "Forms",
|
|
864
588
|
dependencies: []
|
|
865
589
|
},
|
|
866
590
|
sidebar: {
|
|
867
|
-
file: "sidebar.tsx",
|
|
591
|
+
file: "ui/sidebar.tsx",
|
|
868
592
|
description: "Responsive sidebar with mobile drawer",
|
|
869
593
|
category: "Layout",
|
|
870
594
|
dependencies: ["sheet", "button"]
|
|
871
595
|
},
|
|
872
596
|
// Added Components
|
|
873
597
|
combobox: {
|
|
874
|
-
file: "combobox.tsx",
|
|
598
|
+
file: "ui/combobox.tsx",
|
|
875
599
|
description: "Searchable select with autocomplete",
|
|
876
600
|
category: "Forms",
|
|
877
601
|
dependencies: ["popover"]
|
|
878
602
|
},
|
|
879
603
|
command: {
|
|
880
|
-
file: "command.tsx",
|
|
604
|
+
file: "ui/command.tsx",
|
|
881
605
|
description: "Command palette / search menu",
|
|
882
606
|
category: "Navigation",
|
|
883
607
|
dependencies: []
|
|
884
608
|
},
|
|
885
609
|
"context-menu": {
|
|
886
|
-
file: "context-menu.tsx",
|
|
610
|
+
file: "ui/context-menu.tsx",
|
|
887
611
|
description: "Right-click context menu",
|
|
888
612
|
category: "Overlay / Feedback",
|
|
889
613
|
dependencies: []
|
|
890
614
|
},
|
|
891
615
|
"date-picker": {
|
|
892
|
-
file: "date-picker.tsx",
|
|
616
|
+
file: "ui/date-picker.tsx",
|
|
893
617
|
description: "Date picker with calendar",
|
|
894
618
|
category: "Forms",
|
|
895
619
|
dependencies: ["calendar", "popover", "button"]
|
|
896
620
|
},
|
|
897
621
|
drawer: {
|
|
898
|
-
file: "drawer.tsx",
|
|
622
|
+
file: "ui/drawer.tsx",
|
|
899
623
|
description: "Bottom/top sheet drawer",
|
|
900
624
|
category: "Overlay / Feedback",
|
|
901
625
|
dependencies: []
|
|
902
626
|
},
|
|
903
627
|
"file-upload": {
|
|
904
|
-
file: "file-upload.tsx",
|
|
628
|
+
file: "ui/file-upload.tsx",
|
|
905
629
|
description: "Drag-and-drop file upload",
|
|
906
630
|
category: "Forms",
|
|
907
631
|
dependencies: []
|
|
908
632
|
},
|
|
909
633
|
"hover-card": {
|
|
910
|
-
file: "hover-card.tsx",
|
|
634
|
+
file: "ui/hover-card.tsx",
|
|
911
635
|
description: "Hover-triggered popover",
|
|
912
636
|
category: "Overlay / Feedback",
|
|
913
637
|
dependencies: []
|
|
914
638
|
},
|
|
915
639
|
kbd: {
|
|
916
|
-
file: "kbd.tsx",
|
|
640
|
+
file: "ui/kbd.tsx",
|
|
917
641
|
description: "Keyboard shortcut display",
|
|
918
642
|
category: "Typography",
|
|
919
643
|
dependencies: []
|
|
920
644
|
},
|
|
921
645
|
menubar: {
|
|
922
|
-
file: "menubar.tsx",
|
|
646
|
+
file: "ui/menubar.tsx",
|
|
923
647
|
description: "Horizontal menu with dropdowns",
|
|
924
648
|
category: "Navigation",
|
|
925
649
|
dependencies: []
|
|
926
650
|
},
|
|
927
651
|
"native-select": {
|
|
928
|
-
file: "native-select.tsx",
|
|
652
|
+
file: "ui/native-select.tsx",
|
|
929
653
|
description: "Styled browser-native select",
|
|
930
654
|
category: "Forms",
|
|
931
655
|
dependencies: []
|
|
932
656
|
},
|
|
933
657
|
resizable: {
|
|
934
|
-
file: "resizable.tsx",
|
|
658
|
+
file: "ui/resizable.tsx",
|
|
935
659
|
description: "Resizable panel layout",
|
|
936
660
|
category: "Layout",
|
|
937
661
|
dependencies: []
|
|
938
662
|
},
|
|
939
663
|
"scroll-area": {
|
|
940
|
-
file: "scroll-area.tsx",
|
|
664
|
+
file: "ui/scroll-area.tsx",
|
|
941
665
|
description: "Custom scrollbar container",
|
|
942
666
|
category: "Layout",
|
|
943
667
|
dependencies: []
|
|
944
668
|
},
|
|
945
669
|
toggle: {
|
|
946
|
-
file: "toggle.tsx",
|
|
670
|
+
file: "ui/toggle.tsx",
|
|
947
671
|
description: "Toggle button",
|
|
948
672
|
category: "Forms",
|
|
949
673
|
dependencies: []
|
|
950
674
|
},
|
|
951
675
|
"toggle-group": {
|
|
952
|
-
file: "toggle-group.tsx",
|
|
676
|
+
file: "ui/toggle-group.tsx",
|
|
953
677
|
description: "Grouped toggle buttons",
|
|
954
678
|
category: "Forms",
|
|
955
679
|
dependencies: ["toggle"]
|
|
680
|
+
},
|
|
681
|
+
"google-analytics": {
|
|
682
|
+
file: "analytics/google-analytics.tsx",
|
|
683
|
+
description: "Google Analytics 4 tracking",
|
|
684
|
+
category: "Analytics",
|
|
685
|
+
dependencies: []
|
|
686
|
+
},
|
|
687
|
+
"google-tag-manager": {
|
|
688
|
+
file: "analytics/google-tag-manager.tsx",
|
|
689
|
+
description: "Google Tag Manager integration",
|
|
690
|
+
category: "Analytics",
|
|
691
|
+
dependencies: []
|
|
692
|
+
},
|
|
693
|
+
"meta-pixel": {
|
|
694
|
+
file: "analytics/meta-pixel.tsx",
|
|
695
|
+
description: "Meta (Facebook) Pixel tracking",
|
|
696
|
+
category: "Analytics",
|
|
697
|
+
dependencies: []
|
|
698
|
+
},
|
|
699
|
+
"microsoft-clarity": {
|
|
700
|
+
file: "analytics/microsoft-clarity.tsx",
|
|
701
|
+
description: "Microsoft Clarity heatmap tracking",
|
|
702
|
+
category: "Analytics",
|
|
703
|
+
dependencies: []
|
|
704
|
+
},
|
|
705
|
+
"tiktok-pixel": {
|
|
706
|
+
file: "analytics/tiktok-pixel.tsx",
|
|
707
|
+
description: "TikTok Pixel tracking",
|
|
708
|
+
category: "Analytics",
|
|
709
|
+
dependencies: []
|
|
710
|
+
},
|
|
711
|
+
chatbot: {
|
|
712
|
+
file: "ui/chatbot.tsx",
|
|
713
|
+
description: "AI chat interface",
|
|
714
|
+
category: "Data Display",
|
|
715
|
+
dependencies: ["button", "input", "scroll-area", "avatar"]
|
|
956
716
|
}
|
|
957
717
|
};
|
|
958
718
|
|
|
959
719
|
// src/cli/commands/add.ts
|
|
960
|
-
var
|
|
720
|
+
var __dirname4 = path3.dirname(fileURLToPath3(import.meta.url));
|
|
961
721
|
async function add(components, options) {
|
|
962
|
-
const cwd =
|
|
722
|
+
const cwd = path3.resolve(options.cwd);
|
|
963
723
|
if (options.all) {
|
|
964
724
|
components = Object.keys(REGISTRY);
|
|
965
725
|
}
|
|
@@ -1022,40 +782,41 @@ async function add(components, options) {
|
|
|
1022
782
|
}
|
|
1023
783
|
console.log();
|
|
1024
784
|
const spinner = ora2("Adding components...").start();
|
|
1025
|
-
const hasSrc =
|
|
1026
|
-
const srcPath = hasSrc ?
|
|
1027
|
-
const componentsDir =
|
|
785
|
+
const hasSrc = fs3.existsSync(path3.join(cwd, "src"));
|
|
786
|
+
const srcPath = hasSrc ? path3.join(cwd, "src") : cwd;
|
|
787
|
+
const componentsDir = path3.join(srcPath, "components", "ui");
|
|
1028
788
|
try {
|
|
1029
|
-
await
|
|
789
|
+
await fs3.ensureDir(componentsDir);
|
|
1030
790
|
for (const name of componentsToAdd) {
|
|
1031
791
|
const comp = REGISTRY[name];
|
|
1032
|
-
const
|
|
1033
|
-
|
|
792
|
+
const fileName = path3.basename(comp.file);
|
|
793
|
+
const targetPath = path3.join(componentsDir, fileName);
|
|
794
|
+
if (fs3.existsSync(targetPath) && !options.overwrite) {
|
|
1034
795
|
spinner.stop();
|
|
1035
796
|
const { overwrite } = await prompts2({
|
|
1036
797
|
type: "confirm",
|
|
1037
798
|
name: "overwrite",
|
|
1038
|
-
message: `${chalk2.cyan(
|
|
799
|
+
message: `${chalk2.cyan(fileName)} already exists. Overwrite?`,
|
|
1039
800
|
initial: false
|
|
1040
801
|
});
|
|
1041
802
|
if (!overwrite) {
|
|
1042
|
-
spinner.info(`Skipped ${chalk2.cyan(
|
|
803
|
+
spinner.info(`Skipped ${chalk2.cyan(fileName)}`);
|
|
1043
804
|
spinner.start("Adding components...");
|
|
1044
805
|
continue;
|
|
1045
806
|
}
|
|
1046
807
|
spinner.start("Adding components...");
|
|
1047
808
|
}
|
|
1048
|
-
const registryPath =
|
|
1049
|
-
if (!
|
|
809
|
+
const registryPath = path3.resolve(__dirname4, "..", "src", "registry", comp.file);
|
|
810
|
+
if (!fs3.existsSync(registryPath)) {
|
|
1050
811
|
spinner.warn(`Registry file not found for ${name}: ${registryPath}`);
|
|
1051
812
|
continue;
|
|
1052
813
|
}
|
|
1053
|
-
const content = await
|
|
1054
|
-
await
|
|
814
|
+
const content = await fs3.readFile(registryPath, "utf-8");
|
|
815
|
+
await fs3.writeFile(targetPath, content);
|
|
1055
816
|
if (componentsToAdd.length > 10) {
|
|
1056
|
-
spinner.text = `Adding ${chalk2.cyan(
|
|
817
|
+
spinner.text = `Adding ${chalk2.cyan(fileName)}...`;
|
|
1057
818
|
} else {
|
|
1058
|
-
spinner.succeed(`Added ${chalk2.cyan(
|
|
819
|
+
spinner.succeed(`Added ${chalk2.cyan(fileName)}`);
|
|
1059
820
|
}
|
|
1060
821
|
}
|
|
1061
822
|
if (componentsToAdd.length > 10) {
|
|
@@ -1080,7 +841,8 @@ async function list() {
|
|
|
1080
841
|
"Layout": [],
|
|
1081
842
|
"Data Display": [],
|
|
1082
843
|
"Overlay / Feedback": [],
|
|
1083
|
-
"Navigation": []
|
|
844
|
+
"Navigation": [],
|
|
845
|
+
"Analytics": []
|
|
1084
846
|
};
|
|
1085
847
|
for (const [name, comp] of Object.entries(REGISTRY)) {
|
|
1086
848
|
if (categories[comp.category]) {
|
|
@@ -1099,10 +861,51 @@ async function list() {
|
|
|
1099
861
|
console.log(chalk3.dim("Usage: npx @srcroot/ui add <component>\n"));
|
|
1100
862
|
}
|
|
1101
863
|
|
|
864
|
+
// src/cli/utils/get-package-info.ts
|
|
865
|
+
import path4 from "path";
|
|
866
|
+
import fs4 from "fs-extra";
|
|
867
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
868
|
+
function getPackageInfo() {
|
|
869
|
+
const __filename2 = fileURLToPath4(import.meta.url);
|
|
870
|
+
const __dirname5 = path4.dirname(__filename2);
|
|
871
|
+
const pathsToCheck = [
|
|
872
|
+
path4.resolve(__dirname5, "..", "package.json"),
|
|
873
|
+
path4.resolve(__dirname5, "..", "..", "..", "package.json")
|
|
874
|
+
];
|
|
875
|
+
for (const pkgPath of pathsToCheck) {
|
|
876
|
+
if (fs4.existsSync(pkgPath)) {
|
|
877
|
+
return fs4.readJSONSync(pkgPath);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return { version: "0.0.0" };
|
|
881
|
+
}
|
|
882
|
+
|
|
1102
883
|
// src/cli/index.ts
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
program.
|
|
1108
|
-
|
|
884
|
+
process.on("SIGINT", () => process.exit(0));
|
|
885
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
886
|
+
async function main() {
|
|
887
|
+
const packageInfo = getPackageInfo();
|
|
888
|
+
const program = new Command().name("@srcroot/ui").description("Add polymorphic, accessible UI components to your project").version(
|
|
889
|
+
packageInfo.version || "0.0.1",
|
|
890
|
+
"-v, --version",
|
|
891
|
+
"display the version number"
|
|
892
|
+
);
|
|
893
|
+
program.command("init").description("Initialize your project with @srcroot/ui").option("-y, --yes", "Skip confirmation prompts", false).option("-t, --theme <theme>", "Color theme (slate, neutral, stone, zinc, gray)").option("--cwd <path>", "Working directory", process.cwd()).action(init);
|
|
894
|
+
program.command("add").description("Add components to your project").argument("[components...]", "Components to add").option("-y, --yes", "Skip confirmation prompts", false).option("-o, --overwrite", "Overwrite existing files", false).option("-a, --all", "Add all available components", false).option("--cwd <path>", "Working directory", process.cwd()).action(add);
|
|
895
|
+
program.command("list").description("List all available components").action(list);
|
|
896
|
+
if (process.argv.length < 3) {
|
|
897
|
+
console.log(chalk4.cyan(`
|
|
898
|
+
@srcroot/ui v${packageInfo.version}
|
|
899
|
+
|
|
900
|
+
A UI library with polymorphic, accessible components.
|
|
901
|
+
`));
|
|
902
|
+
program.outputHelp();
|
|
903
|
+
console.log();
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
program.parse();
|
|
907
|
+
}
|
|
908
|
+
main().catch((err) => {
|
|
909
|
+
console.error("Results: ", err);
|
|
910
|
+
process.exit(1);
|
|
911
|
+
});
|