galaxy-design 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +320 -0
- package/dist/bin.js +11 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/add.js +252 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/init-old.js +159 -0
- package/dist/commands/init-old.js.map +1 -0
- package/dist/commands/init.js +266 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cli.js +5 -0
- package/dist/lib/cli.js.map +1 -0
- package/dist/registries/blocks-angular.json +89 -0
- package/dist/registries/blocks-flutter.json +60 -0
- package/dist/registries/blocks-react-native.json +60 -0
- package/dist/registries/blocks-react.json +89 -0
- package/dist/registries/blocks-vue.json +89 -0
- package/dist/registries/registry-angular.json +557 -0
- package/dist/registries/registry-flutter.json +491 -0
- package/dist/registries/registry-flutter.json.old +258 -0
- package/dist/registries/registry-react-native.json +491 -0
- package/dist/registries/registry-react-native.json.old +379 -0
- package/dist/registries/registry-react.json +526 -0
- package/dist/registries/registry-vue.json +586 -0
- package/dist/registry.json +460 -0
- package/dist/schemas/components-schema.json +91 -0
- package/dist/templates/tailwind.config.template +45 -0
- package/dist/templates/utils.ts.template +11 -0
- package/dist/utils/component-copier.js +207 -0
- package/dist/utils/component-copier.js.map +1 -0
- package/dist/utils/components-config.js +58 -0
- package/dist/utils/components-config.js.map +1 -0
- package/dist/utils/config-schema.js +221 -0
- package/dist/utils/config-schema.js.map +1 -0
- package/dist/utils/config.js +88 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/detect.js +86 -0
- package/dist/utils/detect.js.map +1 -0
- package/dist/utils/files.js +52 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/framework-registry.js +133 -0
- package/dist/utils/framework-registry.js.map +1 -0
- package/dist/utils/github-fetcher.js +120 -0
- package/dist/utils/github-fetcher.js.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/package-manager.js +173 -0
- package/dist/utils/package-manager.js.map +1 -0
- package/dist/utils/platform-detector.js +176 -0
- package/dist/utils/platform-detector.js.map +1 -0
- package/dist/utils/registry-loader.js +143 -0
- package/dist/utils/registry-loader.js.map +1 -0
- package/dist/utils/registry.js +92 -0
- package/dist/utils/registry.js.map +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Galaxy UI CLI
|
|
2
|
+
|
|
3
|
+
A modern, framework-agnostic CLI tool for adding beautiful, accessible UI components to your projects. Inspired by shadcn/ui, but supporting React, Vue, and Angular.
|
|
4
|
+
|
|
5
|
+
## š Features
|
|
6
|
+
|
|
7
|
+
- š **Multi-framework support**: React, Vue, and Angular
|
|
8
|
+
- š¦ **41 production-ready components** across 8 categories
|
|
9
|
+
- šØ **Built with Radix UI primitives** (radix-ui for React, radix-vue for Vue, radix-ng for Angular)
|
|
10
|
+
- š **Dark mode support** out of the box
|
|
11
|
+
- š± **Responsive design** with mobile-first approach
|
|
12
|
+
- āæ **Accessibility-focused** (WAI-ARIA compliant)
|
|
13
|
+
- šÆ **TypeScript strict mode** support
|
|
14
|
+
- š
**Tailwind CSS** for styling
|
|
15
|
+
- š **Customizable** - components are copied to your project
|
|
16
|
+
|
|
17
|
+
## š¦ Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Using npx (recommended - no installation needed)
|
|
21
|
+
npx galaxy-design@latest init
|
|
22
|
+
|
|
23
|
+
# Or install globally
|
|
24
|
+
npm install -g galaxy-design
|
|
25
|
+
bun add -g galaxy-design
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## š Quick Start
|
|
29
|
+
|
|
30
|
+
### 1. Initialize Galaxy UI in your project
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx galaxy-design@latest init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This interactive command will:
|
|
37
|
+
|
|
38
|
+
- ā
Detect your framework (React, Vue, or Angular)
|
|
39
|
+
- ā
Detect your package manager (npm, pnpm, yarn, or bun)
|
|
40
|
+
- ā
Install required dependencies (lucide icons, clsx, tailwind-merge, radix primitives)
|
|
41
|
+
- ā
Create component directory structure
|
|
42
|
+
- ā
Setup Tailwind CSS configuration
|
|
43
|
+
- ā
Create utility files (cn helper, etc.)
|
|
44
|
+
|
|
45
|
+
### 2. Add components
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Add single component
|
|
49
|
+
npx galaxy-design@latest add button
|
|
50
|
+
|
|
51
|
+
# Add multiple components
|
|
52
|
+
npx galaxy-design@latest add button input card
|
|
53
|
+
|
|
54
|
+
# Interactive mode (select from list)
|
|
55
|
+
npx galaxy-design@latest add
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## š Available Components (41 total)
|
|
59
|
+
|
|
60
|
+
### šØ Form Components (9)
|
|
61
|
+
|
|
62
|
+
- `button` - Versatile button with variants and sizes
|
|
63
|
+
- `input` - Text input with label and validation states
|
|
64
|
+
- `checkbox` - Checkbox with indeterminate state
|
|
65
|
+
- `radio-group` - Radio button groups
|
|
66
|
+
- `select` - Dropdown select with search
|
|
67
|
+
- `slider` - Range slider input
|
|
68
|
+
- `switch` - Toggle switch
|
|
69
|
+
- `textarea` - Multi-line text input
|
|
70
|
+
- `label` - Accessible form labels
|
|
71
|
+
|
|
72
|
+
### š Layout Components (4)
|
|
73
|
+
|
|
74
|
+
- `separator` - Horizontal/vertical divider
|
|
75
|
+
- `accordion` - Collapsible content sections
|
|
76
|
+
- `collapsible` - Single collapsible panel
|
|
77
|
+
- `tabs` - Tabbed content organization
|
|
78
|
+
|
|
79
|
+
### š§ Navigation Components (4)
|
|
80
|
+
|
|
81
|
+
- `navigation-menu` - Complex navigation with dropdowns
|
|
82
|
+
- `menubar` - Desktop-style menu bar
|
|
83
|
+
- `context-menu` - Right-click context menus
|
|
84
|
+
- `dropdown-menu` - Action dropdown menus
|
|
85
|
+
|
|
86
|
+
### š Overlay Components (5)
|
|
87
|
+
|
|
88
|
+
- `dialog` - Modal dialogs
|
|
89
|
+
- `alert-dialog` - Confirmation dialogs
|
|
90
|
+
- `popover` - Floating content containers
|
|
91
|
+
- `tooltip` - Hover tooltips
|
|
92
|
+
- `hover-card` - Preview cards on hover
|
|
93
|
+
|
|
94
|
+
### š Data Display Components (6)
|
|
95
|
+
|
|
96
|
+
- `avatar` - User avatars with fallbacks
|
|
97
|
+
- `progress` - Progress bars and indicators
|
|
98
|
+
- `table` - Data tables with sorting
|
|
99
|
+
- `pagination` - Page navigation
|
|
100
|
+
- `empty` - Empty state placeholders
|
|
101
|
+
- `skeleton` - Loading skeletons
|
|
102
|
+
|
|
103
|
+
### āļø Typography & Utilities (2)
|
|
104
|
+
|
|
105
|
+
- `typography` - Text styles and components
|
|
106
|
+
- `kbd` - Keyboard shortcut display
|
|
107
|
+
|
|
108
|
+
### š
Date & Time Components (2)
|
|
109
|
+
|
|
110
|
+
- `calendar` - Date picker calendar
|
|
111
|
+
- `calendar-range` - Date range picker
|
|
112
|
+
|
|
113
|
+
### ā” Advanced Components (4)
|
|
114
|
+
|
|
115
|
+
- `command` - Command palette (āK)
|
|
116
|
+
- `sheet` - Slide-out panels
|
|
117
|
+
- `toolbar` - Action toolbars
|
|
118
|
+
- `tags-input` - Multi-value tag input
|
|
119
|
+
|
|
120
|
+
### š Bonus Components (5)
|
|
121
|
+
|
|
122
|
+
- `aspect-ratio` - Aspect ratio container
|
|
123
|
+
- `badge` - Status badges and labels
|
|
124
|
+
- `card` - Content cards
|
|
125
|
+
- `scroll-area` - Custom scrollbars
|
|
126
|
+
- `toggle` - Toggle buttons
|
|
127
|
+
- `toggle-group` - Toggle button groups
|
|
128
|
+
|
|
129
|
+
## šÆ Framework-Specific Examples
|
|
130
|
+
|
|
131
|
+
### React
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import {Button} from '@/components/ui/button'
|
|
135
|
+
import {Input} from '@/components/ui/input'
|
|
136
|
+
|
|
137
|
+
export function MyComponent() {
|
|
138
|
+
return (
|
|
139
|
+
<div>
|
|
140
|
+
<Button variant="default" size="lg">
|
|
141
|
+
Click me
|
|
142
|
+
</Button>
|
|
143
|
+
<Input placeholder="Enter text..." />
|
|
144
|
+
</div>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Vue
|
|
150
|
+
|
|
151
|
+
```vue
|
|
152
|
+
<script setup lang="ts">
|
|
153
|
+
import {Button} from '@/components/ui/button'
|
|
154
|
+
import {Input} from '@/components/ui/input'
|
|
155
|
+
</script>
|
|
156
|
+
|
|
157
|
+
<template>
|
|
158
|
+
<div>
|
|
159
|
+
<Button variant="default" size="lg">Click me</Button>
|
|
160
|
+
<Input placeholder="Enter text..." />
|
|
161
|
+
</div>
|
|
162
|
+
</template>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Angular
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import {Component} from '@angular/core';
|
|
169
|
+
import {ButtonDirective} from '@/components/ui/button';
|
|
170
|
+
import {InputComponent} from '@/components/ui/input';
|
|
171
|
+
|
|
172
|
+
@Component({
|
|
173
|
+
selector: 'app-my-component',
|
|
174
|
+
standalone: true,
|
|
175
|
+
imports: [ButtonDirective, InputComponent],
|
|
176
|
+
template: `
|
|
177
|
+
<div>
|
|
178
|
+
<button hlmBtn variant="default" size="lg">Click me</button>
|
|
179
|
+
<hlm-input placeholder="Enter text..." />
|
|
180
|
+
</div>
|
|
181
|
+
`,
|
|
182
|
+
})
|
|
183
|
+
export class MyComponent {}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## āļø Configuration
|
|
187
|
+
|
|
188
|
+
Galaxy UI stores configuration in `components.json` at your project root:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"$schema": "https://galaxy-design.vercel.app/schema.json",
|
|
193
|
+
"framework": "react",
|
|
194
|
+
"typescript": true,
|
|
195
|
+
"tailwind": {
|
|
196
|
+
"config": "tailwind.config.js",
|
|
197
|
+
"css": "src/app/globals.css",
|
|
198
|
+
"baseColor": "slate",
|
|
199
|
+
"cssVariables": true,
|
|
200
|
+
"prefix": ""
|
|
201
|
+
},
|
|
202
|
+
"aliases": {
|
|
203
|
+
"components": "@/components",
|
|
204
|
+
"utils": "@/lib/utils",
|
|
205
|
+
"ui": "@/components/ui",
|
|
206
|
+
"lib": "@/lib"
|
|
207
|
+
},
|
|
208
|
+
"iconLibrary": "lucide"
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Configuration Options
|
|
213
|
+
|
|
214
|
+
| Option | Description | Default |
|
|
215
|
+
|--------|-------------|---------|
|
|
216
|
+
| `framework` | Your framework (react/vue/angular) | Auto-detected |
|
|
217
|
+
| `typescript` | Use TypeScript | `true` |
|
|
218
|
+
| `tailwind.config` | Tailwind config path | `tailwind.config.js` |
|
|
219
|
+
| `tailwind.css` | Global CSS file | Framework-specific |
|
|
220
|
+
| `tailwind.baseColor` | Base color scheme | `slate` |
|
|
221
|
+
| `aliases.components` | Components alias | `@/components` |
|
|
222
|
+
| `aliases.utils` | Utils alias | `@/lib/utils` |
|
|
223
|
+
| `iconLibrary` | Icon library to use | `lucide` |
|
|
224
|
+
|
|
225
|
+
## š§ CLI Commands
|
|
226
|
+
|
|
227
|
+
### `init`
|
|
228
|
+
|
|
229
|
+
Initialize Galaxy UI in your project.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npx galaxy-design@latest init
|
|
233
|
+
|
|
234
|
+
# Skip prompts (use defaults)
|
|
235
|
+
npx galaxy-design@latest init --yes
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### `add`
|
|
239
|
+
|
|
240
|
+
Add components to your project.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Interactive mode
|
|
244
|
+
npx galaxy-design@latest add
|
|
245
|
+
|
|
246
|
+
# Add specific components
|
|
247
|
+
npx galaxy-design@latest add button input
|
|
248
|
+
|
|
249
|
+
# Add all components
|
|
250
|
+
npx galaxy-design@latest add --all
|
|
251
|
+
|
|
252
|
+
# Overwrite existing components
|
|
253
|
+
npx galaxy-design@latest add button --overwrite
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### `diff`
|
|
257
|
+
|
|
258
|
+
Check which components have updates available.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
npx galaxy-design@latest diff button
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## š Styling & Theming
|
|
265
|
+
|
|
266
|
+
Galaxy UI uses Tailwind CSS with CSS variables for theming. After running `init`, you can customize colors in your CSS file:
|
|
267
|
+
|
|
268
|
+
```css
|
|
269
|
+
@layer base {
|
|
270
|
+
:root {
|
|
271
|
+
--background: 0 0% 100%;
|
|
272
|
+
--foreground: 222.2 84% 4.9%;
|
|
273
|
+
--primary: 221.2 83.2% 53.3%;
|
|
274
|
+
--primary-foreground: 210 40% 98%;
|
|
275
|
+
/* ... more variables */
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.dark {
|
|
279
|
+
--background: 222.2 84% 4.9%;
|
|
280
|
+
--foreground: 210 40% 98%;
|
|
281
|
+
/* ... dark mode variables */
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## šØ Customization
|
|
287
|
+
|
|
288
|
+
Components are copied to your project, so you have full control:
|
|
289
|
+
|
|
290
|
+
1. **Modify components** - Edit any component in `components/ui/`
|
|
291
|
+
2. **Change styles** - Update Tailwind classes or CSS variables
|
|
292
|
+
3. **Add features** - Extend components with your own functionality
|
|
293
|
+
4. **No lock-in** - Components are yours to modify
|
|
294
|
+
|
|
295
|
+
## š Documentation & Examples
|
|
296
|
+
|
|
297
|
+
- **Live Examples**: Check `examples/` folder for complete React, Vue, and Angular apps
|
|
298
|
+
- **Docs Website**: <https://galaxy-design.vercel.app>
|
|
299
|
+
- **GitHub**: <https://github.com/buikevin/galaxy-design-cli>
|
|
300
|
+
|
|
301
|
+
## š¤ Contributing
|
|
302
|
+
|
|
303
|
+
Contributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md).
|
|
304
|
+
|
|
305
|
+
## š License
|
|
306
|
+
|
|
307
|
+
MIT License - see [LICENSE](../../LICENSE) for details
|
|
308
|
+
|
|
309
|
+
## š Credits
|
|
310
|
+
|
|
311
|
+
- Inspired by [shadcn/ui](<https://ui.shadcn.com>)
|
|
312
|
+
- Built with [Radix UI](<https://radix-ui.com>), [Radix Vue](<https://radix-vue.com>), and [Spartan NG](<https://spartan.ng>)
|
|
313
|
+
- Icons from [Lucide](<https://lucide.dev>)
|
|
314
|
+
- Styling with [Tailwind CSS](<https://tailwindcss.com>)
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
**Made with ā¤ļø by the Galaxy UI team**
|
|
319
|
+
|
|
320
|
+
For issues and feature requests, please visit our [GitHub Issues](<https://github.com/buikevin/galaxy-design-cli/issues>)
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { initCommand } from './commands/init.js';
|
|
4
|
+
import { addCommand } from './commands/add.js';
|
|
5
|
+
const program = new Command();
|
|
6
|
+
program.name('galaxy-ui-cli').description('CLI tool for Galaxy UI component library').version('0.2.0');
|
|
7
|
+
program.command('init').description('Initialize Galaxy UI in your project').option('-y, --yes', 'Skip prompts and use defaults').option('-c, --cwd <path>', 'Current working directory', process.cwd()).action(initCommand);
|
|
8
|
+
program.command('add').description('Add components to your project').argument('[components...]', 'Component names to add').option('-a, --all', 'Add all components').option('-c, --cwd <path>', 'Current working directory', process.cwd()).action(addCommand);
|
|
9
|
+
program.parse();
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { addCommand } from './commands/add.js';\n\nconst program = new Command();\n\nprogram\n .name('galaxy-ui-cli')\n .description('CLI tool for Galaxy UI component library')\n .version('0.2.0');\n\nprogram\n .command('init')\n .description('Initialize Galaxy UI in your project')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .option('-c, --cwd <path>', 'Current working directory', process.cwd())\n .action(initCommand);\n\nprogram\n .command('add')\n .description('Add components to your project')\n .argument('[components...]', 'Component names to add')\n .option('-a, --all', 'Add all components')\n .option('-c, --cwd <path>', 'Current working directory', process.cwd())\n .action(addCommand);\n\nprogram.parse();\n"],"names":["Command","initCommand","addCommand","program","name","description","version","command","option","process","cwd","action","argument","parse"],"mappings":";AACA,SAASA,OAAO,QAAQ,YAAY;AACpC,SAASC,WAAW,QAAQ,qBAAqB;AACjD,SAASC,UAAU,QAAQ,oBAAoB;AAE/C,MAAMC,UAAU,IAAIH;AAEpBG,QACGC,IAAI,CAAC,iBACLC,WAAW,CAAC,4CACZC,OAAO,CAAC;AAEXH,QACGI,OAAO,CAAC,QACRF,WAAW,CAAC,wCACZG,MAAM,CAAC,aAAa,iCACpBA,MAAM,CAAC,oBAAoB,6BAA6BC,QAAQC,GAAG,IACnEC,MAAM,CAACV;AAEVE,QACGI,OAAO,CAAC,OACRF,WAAW,CAAC,kCACZO,QAAQ,CAAC,mBAAmB,0BAC5BJ,MAAM,CAAC,aAAa,sBACpBA,MAAM,CAAC,oBAAoB,6BAA6BC,QAAQC,GAAG,IACnEC,MAAM,CAACT;AAEVC,QAAQU,KAAK"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { resolve, join, dirname } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { loadComponentsConfig, hasComponentsConfig } from '../utils/components-config.js';
|
|
7
|
+
import { loadFrameworkRegistry, getFrameworkComponent, getFrameworkComponentDependencies, getAllFrameworkComponents } from '../utils/framework-registry.js';
|
|
8
|
+
import { writeFile, fileExists, readFile, ensureDir } from '../utils/files.js';
|
|
9
|
+
import { installDependencies } from '../utils/package-manager.js';
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
export async function addCommand(components, options) {
|
|
13
|
+
const cwd = options.cwd;
|
|
14
|
+
// Check if components.json exists (new config system)
|
|
15
|
+
if (!hasComponentsConfig(cwd)) {
|
|
16
|
+
console.log(chalk.red('ā Galaxy UI is not initialized in this project.'));
|
|
17
|
+
console.log(chalk.gray('Run') + chalk.cyan(' galaxy-ui init ') + chalk.gray('first.'));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// Load components.json configuration
|
|
21
|
+
const componentsConfig = loadComponentsConfig(cwd);
|
|
22
|
+
if (!componentsConfig) {
|
|
23
|
+
console.log(chalk.red('ā Failed to load components.json configuration.'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const framework = componentsConfig.framework;
|
|
27
|
+
console.log(chalk.gray(`Framework detected: ${chalk.cyan(framework)}\n`));
|
|
28
|
+
// Load framework-specific registry
|
|
29
|
+
const registry = loadFrameworkRegistry(framework);
|
|
30
|
+
const allComponents = getAllFrameworkComponents(framework);
|
|
31
|
+
// Determine which components to add
|
|
32
|
+
let componentsToAdd = [];
|
|
33
|
+
if (options.all) {
|
|
34
|
+
// Add all components
|
|
35
|
+
componentsToAdd = Object.keys(allComponents);
|
|
36
|
+
} else if (components.length === 0) {
|
|
37
|
+
// Interactive mode
|
|
38
|
+
const choices = [];
|
|
39
|
+
// Create choices organized by category
|
|
40
|
+
const categories = new Map();
|
|
41
|
+
for (const [key, component] of Object.entries(allComponents)){
|
|
42
|
+
const category = component.category || 'other';
|
|
43
|
+
if (!categories.has(category)) {
|
|
44
|
+
categories.set(category, []);
|
|
45
|
+
}
|
|
46
|
+
categories.get(category).push({
|
|
47
|
+
key,
|
|
48
|
+
component
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
for (const [category, items] of categories){
|
|
52
|
+
choices.push({
|
|
53
|
+
title: chalk.bold.cyan(category.charAt(0).toUpperCase() + category.slice(1)),
|
|
54
|
+
value: `category:${category}`,
|
|
55
|
+
disabled: true
|
|
56
|
+
});
|
|
57
|
+
for (const { key, component } of items){
|
|
58
|
+
choices.push({
|
|
59
|
+
title: ` ${component.name}`,
|
|
60
|
+
description: component.description || '',
|
|
61
|
+
value: key
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const response = await prompts({
|
|
66
|
+
type: 'multiselect',
|
|
67
|
+
name: 'components',
|
|
68
|
+
message: 'Which components would you like to add?',
|
|
69
|
+
choices,
|
|
70
|
+
hint: '- Space to select. Return to submit'
|
|
71
|
+
});
|
|
72
|
+
if (!response.components || response.components.length === 0) {
|
|
73
|
+
console.log(chalk.gray('No components selected.'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
componentsToAdd = response.components;
|
|
77
|
+
} else {
|
|
78
|
+
// Add specified components
|
|
79
|
+
for (const input of components){
|
|
80
|
+
// Check if component exists in registry
|
|
81
|
+
if (allComponents[input]) {
|
|
82
|
+
componentsToAdd.push(input);
|
|
83
|
+
} else {
|
|
84
|
+
console.log(chalk.yellow(`ā Component "${input}" not found. Skipping.`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (componentsToAdd.length === 0) {
|
|
89
|
+
console.log(chalk.yellow('No valid components to add.'));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Remove duplicates
|
|
93
|
+
componentsToAdd = [
|
|
94
|
+
...new Set(componentsToAdd)
|
|
95
|
+
];
|
|
96
|
+
console.log(chalk.bold.cyan(`\nš¦ Adding ${componentsToAdd.length} component(s)...\n`));
|
|
97
|
+
// Collect all dependencies
|
|
98
|
+
const allDependencies = [];
|
|
99
|
+
const allDevDependencies = [];
|
|
100
|
+
// Add each component
|
|
101
|
+
const results = [];
|
|
102
|
+
for (const componentKey of componentsToAdd){
|
|
103
|
+
const component = getFrameworkComponent(framework, componentKey);
|
|
104
|
+
if (!component) {
|
|
105
|
+
results.push({
|
|
106
|
+
name: componentKey,
|
|
107
|
+
success: false,
|
|
108
|
+
error: 'Component not found in registry'
|
|
109
|
+
});
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const spinner = ora(`Adding ${chalk.cyan(component.name)}...`).start();
|
|
113
|
+
try {
|
|
114
|
+
// Get component destination path from aliases
|
|
115
|
+
const componentsAlias = componentsConfig.aliases.components;
|
|
116
|
+
const destPath = componentsAlias.replace('@/', '');
|
|
117
|
+
const fullDestPath = resolve(cwd, destPath, 'ui');
|
|
118
|
+
ensureDir(fullDestPath);
|
|
119
|
+
// Get file extension based on framework
|
|
120
|
+
const fileExtensions = {
|
|
121
|
+
vue: '.vue',
|
|
122
|
+
react: '.tsx',
|
|
123
|
+
angular: '.component.ts',
|
|
124
|
+
'react-native': '.tsx',
|
|
125
|
+
flutter: '.dart'
|
|
126
|
+
};
|
|
127
|
+
const ext = fileExtensions[framework];
|
|
128
|
+
// Create component folder
|
|
129
|
+
const componentFolderPath = join(fullDestPath, componentKey);
|
|
130
|
+
ensureDir(componentFolderPath);
|
|
131
|
+
// Copy component files from source packages
|
|
132
|
+
for (const file of component.files){
|
|
133
|
+
const fileName = file.includes('/') ? file.split('/').pop() : file;
|
|
134
|
+
const destFilePath = join(componentFolderPath, fileName);
|
|
135
|
+
// Check if file already exists
|
|
136
|
+
if (fileExists(destFilePath)) {
|
|
137
|
+
spinner.warn(`${chalk.cyan(component.name)} - File already exists: ${fileName}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
// Get source path from packages (blocks/ or components/)
|
|
141
|
+
const sourceFolder = component.type === 'block' ? 'blocks' : 'components';
|
|
142
|
+
const packagePath = resolve(__dirname, '..', '..', '..', framework, 'src', sourceFolder, componentKey);
|
|
143
|
+
const sourcePath = join(packagePath, file);
|
|
144
|
+
// Try to read the source file
|
|
145
|
+
if (fileExists(sourcePath)) {
|
|
146
|
+
const content = readFile(sourcePath);
|
|
147
|
+
writeFile(destFilePath, content);
|
|
148
|
+
} else {
|
|
149
|
+
// Try with capitalized component name
|
|
150
|
+
const capitalizedFile = file.charAt(0).toUpperCase() + file.slice(1);
|
|
151
|
+
const capitalizedSourcePath = join(packagePath, capitalizedFile);
|
|
152
|
+
if (fileExists(capitalizedSourcePath)) {
|
|
153
|
+
const content = readFile(capitalizedSourcePath);
|
|
154
|
+
writeFile(destFilePath, content);
|
|
155
|
+
} else {
|
|
156
|
+
// Fallback to placeholder if source not found
|
|
157
|
+
const placeholderContent = `// ${component.name} component for ${framework}\n// TODO: Component source not found at ${sourcePath}\n`;
|
|
158
|
+
writeFile(destFilePath, placeholderContent);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
spinner.succeed(`${chalk.green('ā')} Added ${chalk.cyan(component.name)} to ${chalk.gray(destPath + '/ui/' + componentKey + '/')}`);
|
|
163
|
+
results.push({
|
|
164
|
+
name: component.name,
|
|
165
|
+
success: true,
|
|
166
|
+
path: componentFolderPath
|
|
167
|
+
});
|
|
168
|
+
// Collect dependencies
|
|
169
|
+
const deps = getFrameworkComponentDependencies(framework, componentKey);
|
|
170
|
+
allDependencies.push(...deps.dependencies);
|
|
171
|
+
allDevDependencies.push(...deps.devDependencies);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
spinner.fail(`Failed to add ${chalk.cyan(component.name)}`);
|
|
174
|
+
results.push({
|
|
175
|
+
name: component.name,
|
|
176
|
+
success: false,
|
|
177
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Install dependencies
|
|
182
|
+
const uniqueDependencies = [
|
|
183
|
+
...new Set(allDependencies)
|
|
184
|
+
];
|
|
185
|
+
const uniqueDevDependencies = [
|
|
186
|
+
...new Set(allDevDependencies)
|
|
187
|
+
];
|
|
188
|
+
if (uniqueDependencies.length > 0 || uniqueDevDependencies.length > 0) {
|
|
189
|
+
console.log('\n');
|
|
190
|
+
const installSpinner = ora('Installing dependencies...').start();
|
|
191
|
+
try {
|
|
192
|
+
if (uniqueDependencies.length > 0) {
|
|
193
|
+
await installDependencies(uniqueDependencies, {
|
|
194
|
+
cwd,
|
|
195
|
+
dev: false,
|
|
196
|
+
silent: true
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (uniqueDevDependencies.length > 0) {
|
|
200
|
+
await installDependencies(uniqueDevDependencies, {
|
|
201
|
+
cwd,
|
|
202
|
+
dev: true,
|
|
203
|
+
silent: true
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
installSpinner.succeed('Dependencies installed');
|
|
207
|
+
} catch (error) {
|
|
208
|
+
installSpinner.fail('Failed to install dependencies');
|
|
209
|
+
console.log(chalk.yellow('Please install them manually:'));
|
|
210
|
+
if (uniqueDependencies.length > 0) {
|
|
211
|
+
console.log(chalk.gray(` npm install ${uniqueDependencies.join(' ')}`));
|
|
212
|
+
}
|
|
213
|
+
if (uniqueDevDependencies.length > 0) {
|
|
214
|
+
console.log(chalk.gray(` npm install -D ${uniqueDevDependencies.join(' ')}`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Summary
|
|
219
|
+
const successful = results.filter((r)=>r.success).length;
|
|
220
|
+
const failed = results.filter((r)=>!r.success).length;
|
|
221
|
+
console.log('\n');
|
|
222
|
+
if (successful > 0) {
|
|
223
|
+
console.log(chalk.green.bold(`ā Successfully added ${successful} component(s)`));
|
|
224
|
+
}
|
|
225
|
+
if (failed > 0) {
|
|
226
|
+
console.log(chalk.red.bold(`ā Failed to add ${failed} component(s)`));
|
|
227
|
+
for (const result of results.filter((r)=>!r.success)){
|
|
228
|
+
console.log(chalk.red(` - ${result.name}: ${result.error}`));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Next steps
|
|
232
|
+
if (successful > 0) {
|
|
233
|
+
console.log('\n' + chalk.gray('Next steps:'));
|
|
234
|
+
switch(framework){
|
|
235
|
+
case 'vue':
|
|
236
|
+
console.log(chalk.gray(' 1. Import the components in your Vue component'));
|
|
237
|
+
console.log(chalk.gray(' 2. Use them in your template'));
|
|
238
|
+
break;
|
|
239
|
+
case 'react':
|
|
240
|
+
console.log(chalk.gray(' 1. Import the components in your React component'));
|
|
241
|
+
console.log(chalk.gray(' 2. Use them in your JSX'));
|
|
242
|
+
break;
|
|
243
|
+
case 'angular':
|
|
244
|
+
console.log(chalk.gray(' 1. Import the components in your Angular module or component'));
|
|
245
|
+
console.log(chalk.gray(' 2. Use them in your templates'));
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
console.log(chalk.gray(' 3. Enjoy building with Galaxy UI! š\n'));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/add.ts"],"sourcesContent":["import prompts from 'prompts';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { resolve, join, dirname } from 'path';\nimport { existsSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { loadConfig, configExists } from '../utils/config.js';\nimport {\n loadComponentsConfig,\n hasComponentsConfig,\n getFrameworkFromConfig,\n} from '../utils/components-config.js';\nimport {\n loadFrameworkRegistry,\n getFrameworkComponent,\n getFrameworkComponentDependencies,\n getAllFrameworkComponents,\n} from '../utils/framework-registry.js';\nimport { writeFile, fileExists, readFile, ensureDir } from '../utils/files.js';\nimport { installDependencies } from '../utils/package-manager.js';\nimport type { Framework } from '../utils/config-schema.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface AddOptions {\n all?: boolean;\n cwd: string;\n}\n\nexport async function addCommand(components: string[], options: AddOptions) {\n const cwd = options.cwd;\n\n // Check if components.json exists (new config system)\n if (!hasComponentsConfig(cwd)) {\n console.log(chalk.red('ā Galaxy UI is not initialized in this project.'));\n console.log(chalk.gray('Run') + chalk.cyan(' galaxy-ui init ') + chalk.gray('first.'));\n return;\n }\n\n // Load components.json configuration\n const componentsConfig = loadComponentsConfig(cwd);\n if (!componentsConfig) {\n console.log(chalk.red('ā Failed to load components.json configuration.'));\n return;\n }\n\n const framework = componentsConfig.framework;\n console.log(chalk.gray(`Framework detected: ${chalk.cyan(framework)}\\n`));\n\n // Load framework-specific registry\n const registry = loadFrameworkRegistry(framework);\n const allComponents = getAllFrameworkComponents(framework);\n\n // Determine which components to add\n let componentsToAdd: string[] = [];\n\n if (options.all) {\n // Add all components\n componentsToAdd = Object.keys(allComponents);\n } else if (components.length === 0) {\n // Interactive mode\n const choices = [];\n\n // Create choices organized by category\n const categories = new Map<string, any[]>();\n\n for (const [key, component] of Object.entries(allComponents)) {\n const category = component.category || 'other';\n if (!categories.has(category)) {\n categories.set(category, []);\n }\n categories.get(category)!.push({ key, component });\n }\n\n for (const [category, items] of categories) {\n choices.push({\n title: chalk.bold.cyan(category.charAt(0).toUpperCase() + category.slice(1)),\n value: `category:${category}`,\n disabled: true,\n });\n\n for (const { key, component } of items) {\n choices.push({\n title: ` ${component.name}`,\n description: component.description || '',\n value: key,\n });\n }\n }\n\n const response = await prompts({\n type: 'multiselect',\n name: 'components',\n message: 'Which components would you like to add?',\n choices,\n hint: '- Space to select. Return to submit',\n });\n\n if (!response.components || response.components.length === 0) {\n console.log(chalk.gray('No components selected.'));\n return;\n }\n\n componentsToAdd = response.components;\n } else {\n // Add specified components\n for (const input of components) {\n // Check if component exists in registry\n if (allComponents[input]) {\n componentsToAdd.push(input);\n } else {\n console.log(chalk.yellow(`ā Component \"${input}\" not found. Skipping.`));\n }\n }\n }\n\n if (componentsToAdd.length === 0) {\n console.log(chalk.yellow('No valid components to add.'));\n return;\n }\n\n // Remove duplicates\n componentsToAdd = [...new Set(componentsToAdd)];\n\n console.log(chalk.bold.cyan(`\\nš¦ Adding ${componentsToAdd.length} component(s)...\\n`));\n\n // Collect all dependencies\n const allDependencies: string[] = [];\n const allDevDependencies: string[] = [];\n\n // Add each component\n const results: { name: string; success: boolean; path?: string; error?: string }[] = [];\n\n for (const componentKey of componentsToAdd) {\n const component = getFrameworkComponent(framework, componentKey);\n\n if (!component) {\n results.push({\n name: componentKey,\n success: false,\n error: 'Component not found in registry',\n });\n continue;\n }\n\n const spinner = ora(`Adding ${chalk.cyan(component.name)}...`).start();\n\n try {\n // Get component destination path from aliases\n const componentsAlias = componentsConfig.aliases.components;\n const destPath = componentsAlias.replace('@/', '');\n const fullDestPath = resolve(cwd, destPath, 'ui');\n ensureDir(fullDestPath);\n\n // Get file extension based on framework\n const fileExtensions: Record<Framework, string> = {\n vue: '.vue',\n react: '.tsx',\n angular: '.component.ts',\n 'react-native': '.tsx',\n flutter: '.dart',\n };\n const ext = fileExtensions[framework];\n\n // Create component folder\n const componentFolderPath = join(fullDestPath, componentKey);\n ensureDir(componentFolderPath);\n\n // Copy component files from source packages\n for (const file of component.files) {\n const fileName = file.includes('/') ? file.split('/').pop()! : file;\n const destFilePath = join(componentFolderPath, fileName);\n\n // Check if file already exists\n if (fileExists(destFilePath)) {\n spinner.warn(\n `${chalk.cyan(component.name)} - File already exists: ${fileName}`\n );\n continue;\n }\n\n // Get source path from packages (blocks/ or components/)\n const sourceFolder = component.type === 'block' ? 'blocks' : 'components';\n const packagePath = resolve(__dirname, '..', '..', '..', framework, 'src', sourceFolder, componentKey);\n const sourcePath = join(packagePath, file);\n\n // Try to read the source file\n if (fileExists(sourcePath)) {\n const content = readFile(sourcePath);\n writeFile(destFilePath, content);\n } else {\n // Try with capitalized component name\n const capitalizedFile = file.charAt(0).toUpperCase() + file.slice(1);\n const capitalizedSourcePath = join(packagePath, capitalizedFile);\n\n if (fileExists(capitalizedSourcePath)) {\n const content = readFile(capitalizedSourcePath);\n writeFile(destFilePath, content);\n } else {\n // Fallback to placeholder if source not found\n const placeholderContent = `// ${component.name} component for ${framework}\\n// TODO: Component source not found at ${sourcePath}\\n`;\n writeFile(destFilePath, placeholderContent);\n }\n }\n }\n\n spinner.succeed(\n `${chalk.green('ā')} Added ${chalk.cyan(component.name)} to ${chalk.gray(\n destPath + '/ui/' + componentKey + '/'\n )}`\n );\n\n results.push({\n name: component.name,\n success: true,\n path: componentFolderPath,\n });\n\n // Collect dependencies\n const deps = getFrameworkComponentDependencies(framework, componentKey);\n allDependencies.push(...deps.dependencies);\n allDevDependencies.push(...deps.devDependencies);\n } catch (error) {\n spinner.fail(`Failed to add ${chalk.cyan(component.name)}`);\n results.push({\n name: component.name,\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n // Install dependencies\n const uniqueDependencies = [...new Set(allDependencies)];\n const uniqueDevDependencies = [...new Set(allDevDependencies)];\n\n if (uniqueDependencies.length > 0 || uniqueDevDependencies.length > 0) {\n console.log('\\n');\n const installSpinner = ora('Installing dependencies...').start();\n\n try {\n if (uniqueDependencies.length > 0) {\n await installDependencies(uniqueDependencies, { cwd, dev: false, silent: true });\n }\n if (uniqueDevDependencies.length > 0) {\n await installDependencies(uniqueDevDependencies, { cwd, dev: true, silent: true });\n }\n installSpinner.succeed('Dependencies installed');\n } catch (error) {\n installSpinner.fail('Failed to install dependencies');\n console.log(chalk.yellow('Please install them manually:'));\n if (uniqueDependencies.length > 0) {\n console.log(chalk.gray(` npm install ${uniqueDependencies.join(' ')}`));\n }\n if (uniqueDevDependencies.length > 0) {\n console.log(chalk.gray(` npm install -D ${uniqueDevDependencies.join(' ')}`));\n }\n }\n }\n\n // Summary\n const successful = results.filter(r => r.success).length;\n const failed = results.filter(r => !r.success).length;\n\n console.log('\\n');\n\n if (successful > 0) {\n console.log(\n chalk.green.bold(`ā Successfully added ${successful} component(s)`)\n );\n }\n\n if (failed > 0) {\n console.log(chalk.red.bold(`ā Failed to add ${failed} component(s)`));\n for (const result of results.filter(r => !r.success)) {\n console.log(chalk.red(` - ${result.name}: ${result.error}`));\n }\n }\n\n // Next steps\n if (successful > 0) {\n console.log('\\n' + chalk.gray('Next steps:'));\n\n switch (framework) {\n case 'vue':\n console.log(chalk.gray(' 1. Import the components in your Vue component'));\n console.log(chalk.gray(' 2. Use them in your template'));\n break;\n case 'react':\n console.log(chalk.gray(' 1. Import the components in your React component'));\n console.log(chalk.gray(' 2. Use them in your JSX'));\n break;\n case 'angular':\n console.log(chalk.gray(' 1. Import the components in your Angular module or component'));\n console.log(chalk.gray(' 2. Use them in your templates'));\n break;\n }\n\n console.log(chalk.gray(' 3. Enjoy building with Galaxy UI! š\\n'));\n }\n}\n"],"names":["prompts","chalk","ora","resolve","join","dirname","fileURLToPath","loadComponentsConfig","hasComponentsConfig","loadFrameworkRegistry","getFrameworkComponent","getFrameworkComponentDependencies","getAllFrameworkComponents","writeFile","fileExists","readFile","ensureDir","installDependencies","__filename","url","__dirname","addCommand","components","options","cwd","console","log","red","gray","cyan","componentsConfig","framework","registry","allComponents","componentsToAdd","all","Object","keys","length","choices","categories","Map","key","component","entries","category","has","set","get","push","items","title","bold","charAt","toUpperCase","slice","value","disabled","name","description","response","type","message","hint","input","yellow","Set","allDependencies","allDevDependencies","results","componentKey","success","error","spinner","start","componentsAlias","aliases","destPath","replace","fullDestPath","fileExtensions","vue","react","angular","flutter","ext","componentFolderPath","file","files","fileName","includes","split","pop","destFilePath","warn","sourceFolder","packagePath","sourcePath","content","capitalizedFile","capitalizedSourcePath","placeholderContent","succeed","green","path","deps","dependencies","devDependencies","fail","Error","uniqueDependencies","uniqueDevDependencies","installSpinner","dev","silent","successful","filter","r","failed","result"],"mappings":"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"}
|