galaxy-design 0.2.64 → 0.2.66
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/commands/add.js +42 -5
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/init.js +29 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/registries/registry-angular.json +46 -14
- package/dist/registries/registry-react.json +77 -0
- package/dist/utils/angular-provider-manager.js +116 -0
- package/dist/utils/angular-provider-manager.js.map +1 -0
- package/dist/utils/component-transformer.js +51 -6
- package/dist/utils/component-transformer.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/add.js
CHANGED
|
@@ -9,6 +9,8 @@ import { loadFrameworkRegistry, getFrameworkComponent, getFrameworkComponentDepe
|
|
|
9
9
|
import { writeFile, fileExists, ensureDir } from '../utils/files.js';
|
|
10
10
|
import { installDependencies } from '../utils/package-manager.js';
|
|
11
11
|
import { fetchFileFromGitHub } from '../utils/github-fetcher.js';
|
|
12
|
+
import { transformComponent } from '../utils/component-transformer.js';
|
|
13
|
+
import { generateAngularProvidersIndex } from '../utils/angular-provider-manager.js';
|
|
12
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
15
|
const __dirname = dirname(__filename);
|
|
14
16
|
export async function addCommand(components, options) {
|
|
@@ -169,7 +171,14 @@ export async function addCommand(components, options) {
|
|
|
169
171
|
// Fetch file from GitHub (use packageFramework for correct path)
|
|
170
172
|
const sourceFolder = component.type === 'block' ? 'blocks' : 'components';
|
|
171
173
|
const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${file}`;
|
|
172
|
-
|
|
174
|
+
let content = await fetchFileFromGitHub(githubPath);
|
|
175
|
+
// Apply transformations (import path fixes, 'use client' for Next.js, etc.)
|
|
176
|
+
const transformResult = transformComponent(content, {
|
|
177
|
+
platform: framework,
|
|
178
|
+
componentName: componentKey,
|
|
179
|
+
filePath: destFilePath
|
|
180
|
+
});
|
|
181
|
+
content = transformResult.content;
|
|
173
182
|
writeFile(destFilePath, content);
|
|
174
183
|
} catch (error) {
|
|
175
184
|
// Try with capitalized file name
|
|
@@ -177,7 +186,14 @@ export async function addCommand(components, options) {
|
|
|
177
186
|
const capitalizedFile = file.charAt(0).toUpperCase() + file.slice(1);
|
|
178
187
|
const sourceFolder = component.type === 'block' ? 'blocks' : 'components';
|
|
179
188
|
const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${capitalizedFile}`;
|
|
180
|
-
|
|
189
|
+
let content = await fetchFileFromGitHub(githubPath);
|
|
190
|
+
// Apply transformations (import path fixes, 'use client' for Next.js, etc.)
|
|
191
|
+
const transformResult = transformComponent(content, {
|
|
192
|
+
platform: framework,
|
|
193
|
+
componentName: componentKey,
|
|
194
|
+
filePath: destFilePath
|
|
195
|
+
});
|
|
196
|
+
content = transformResult.content;
|
|
181
197
|
writeFile(destFilePath, content);
|
|
182
198
|
} catch (capitalizedError) {
|
|
183
199
|
// If both attempts fail, write a placeholder
|
|
@@ -256,6 +272,26 @@ export async function addCommand(components, options) {
|
|
|
256
272
|
console.log(chalk.red(` - ${result.name}: ${result.error}`));
|
|
257
273
|
}
|
|
258
274
|
}
|
|
275
|
+
// For Angular, generate/update the components/ui/index.ts file with providers
|
|
276
|
+
if (framework === 'angular' && successful > 0) {
|
|
277
|
+
console.log('\n');
|
|
278
|
+
const providerSpinner = ora('Generating providers index...').start();
|
|
279
|
+
try {
|
|
280
|
+
const componentsAlias = componentsConfig.aliases.components;
|
|
281
|
+
const destPath = componentsAlias.replace('@/', '');
|
|
282
|
+
const usesSrcDir = hasSrcDirectory(cwd);
|
|
283
|
+
const baseDir = usesSrcDir ? 'src/' : '';
|
|
284
|
+
const fullDestPath = resolve(cwd, baseDir + destPath, 'ui');
|
|
285
|
+
const success = generateAngularProvidersIndex(fullDestPath, framework);
|
|
286
|
+
if (success) {
|
|
287
|
+
providerSpinner.succeed('Generated providers index at ' + chalk.cyan(`${destPath}/ui/index.ts`));
|
|
288
|
+
} else {
|
|
289
|
+
providerSpinner.warn('Could not generate providers index');
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
providerSpinner.fail('Failed to generate providers index');
|
|
293
|
+
}
|
|
294
|
+
}
|
|
259
295
|
// Next steps
|
|
260
296
|
if (successful > 0) {
|
|
261
297
|
console.log('\n' + chalk.gray('Next steps:'));
|
|
@@ -269,11 +305,12 @@ export async function addCommand(components, options) {
|
|
|
269
305
|
console.log(chalk.gray(' 2. Use them in your JSX'));
|
|
270
306
|
break;
|
|
271
307
|
case 'angular':
|
|
272
|
-
console.log(chalk.gray(' 1. Import
|
|
273
|
-
console.log(chalk.gray(' 2.
|
|
308
|
+
console.log(chalk.gray(' 1. Import provideGalaxyComponents() in your app.config.ts providers array'));
|
|
309
|
+
console.log(chalk.gray(' 2. Import the components in your Angular component'));
|
|
310
|
+
console.log(chalk.gray(' 3. Use them in your templates'));
|
|
274
311
|
break;
|
|
275
312
|
}
|
|
276
|
-
console.log(chalk.gray('
|
|
313
|
+
console.log(chalk.gray(' 4. Enjoy building with Galaxy UI! 🚀\n'));
|
|
277
314
|
}
|
|
278
315
|
}
|
|
279
316
|
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +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 { hasSrcDirectory } from '../utils/detect.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';\nimport { fetchFileFromGitHub, getComponentGitHubPath } from '../utils/github-fetcher.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-design 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 // Resolve registry dependencies\n const resolvedComponents = new Set<string>(componentsToAdd);\n const toProcess = [...componentsToAdd];\n\n while (toProcess.length > 0) {\n const componentKey = toProcess.pop()!;\n const component = getFrameworkComponent(framework, componentKey);\n\n if (component && component.registryDependencies && component.registryDependencies.length > 0) {\n for (const depKey of component.registryDependencies) {\n if (!resolvedComponents.has(depKey)) {\n resolvedComponents.add(depKey);\n toProcess.push(depKey);\n }\n }\n }\n }\n\n componentsToAdd = Array.from(resolvedComponents);\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\n // Detect if project uses src/ directory and adjust path\n const usesSrcDir = hasSrcDirectory(cwd);\n const baseDir = usesSrcDir ? 'src/' : '';\n const fullDestPath = resolve(cwd, baseDir + 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 // Map framework to actual package framework for GitHub path\n // Next.js uses React components, Nuxt.js uses Vue components\n let packageFramework = framework;\n if (framework === 'nextjs') packageFramework = 'react';\n if (framework === 'nuxtjs') packageFramework = 'vue';\n\n // Copy component files from GitHub\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 try {\n // Fetch file from GitHub (use packageFramework for correct path)\n const sourceFolder = component.type === 'block' ? 'blocks' : 'components';\n const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${file}`;\n const content = await fetchFileFromGitHub(githubPath);\n writeFile(destFilePath, content);\n } catch (error) {\n // Try with capitalized file name\n try {\n const capitalizedFile = file.charAt(0).toUpperCase() + file.slice(1);\n const sourceFolder = component.type === 'block' ? 'blocks' : 'components';\n const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${capitalizedFile}`;\n const content = await fetchFileFromGitHub(githubPath);\n writeFile(destFilePath, content);\n } catch (capitalizedError) {\n // If both attempts fail, write a placeholder\n const placeholderContent = `// ${component.name} component for ${framework}\\n// TODO: Failed to fetch component from GitHub: ${error instanceof Error ? error.message : 'Unknown error'}\\n`;\n writeFile(destFilePath, placeholderContent);\n spinner.warn(`${chalk.yellow('⚠')} Failed to fetch ${file} from GitHub, created placeholder`);\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","hasSrcDirectory","loadFrameworkRegistry","getFrameworkComponent","getFrameworkComponentDependencies","getAllFrameworkComponents","writeFile","fileExists","ensureDir","installDependencies","fetchFileFromGitHub","__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","resolvedComponents","toProcess","componentKey","pop","registryDependencies","depKey","add","Array","from","allDependencies","allDevDependencies","results","success","error","spinner","start","componentsAlias","aliases","destPath","replace","usesSrcDir","baseDir","fullDestPath","fileExtensions","vue","react","angular","flutter","ext","componentFolderPath","packageFramework","file","files","fileName","includes","split","destFilePath","warn","sourceFolder","githubPath","content","capitalizedFile","capitalizedError","placeholderContent","Error","succeed","green","path","deps","dependencies","devDependencies","fail","uniqueDependencies","uniqueDevDependencies","installSpinner","dev","silent","successful","filter","r","failed","result"],"mappings":"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"}
|
|
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 { hasSrcDirectory } from '../utils/detect.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';\nimport { fetchFileFromGitHub, getComponentGitHubPath } from '../utils/github-fetcher.js';\nimport { transformComponent } from '../utils/component-transformer.js';\nimport { generateAngularProvidersIndex } from '../utils/angular-provider-manager.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-design 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 // Resolve registry dependencies\n const resolvedComponents = new Set<string>(componentsToAdd);\n const toProcess = [...componentsToAdd];\n\n while (toProcess.length > 0) {\n const componentKey = toProcess.pop()!;\n const component = getFrameworkComponent(framework, componentKey);\n\n if (component && component.registryDependencies && component.registryDependencies.length > 0) {\n for (const depKey of component.registryDependencies) {\n if (!resolvedComponents.has(depKey)) {\n resolvedComponents.add(depKey);\n toProcess.push(depKey);\n }\n }\n }\n }\n\n componentsToAdd = Array.from(resolvedComponents);\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\n // Detect if project uses src/ directory and adjust path\n const usesSrcDir = hasSrcDirectory(cwd);\n const baseDir = usesSrcDir ? 'src/' : '';\n const fullDestPath = resolve(cwd, baseDir + 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 // Map framework to actual package framework for GitHub path\n // Next.js uses React components, Nuxt.js uses Vue components\n let packageFramework = framework;\n if (framework === 'nextjs') packageFramework = 'react';\n if (framework === 'nuxtjs') packageFramework = 'vue';\n\n // Copy component files from GitHub\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 try {\n // Fetch file from GitHub (use packageFramework for correct path)\n const sourceFolder = component.type === 'block' ? 'blocks' : 'components';\n const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${file}`;\n let content = await fetchFileFromGitHub(githubPath);\n\n // Apply transformations (import path fixes, 'use client' for Next.js, etc.)\n const transformResult = transformComponent(content, {\n platform: framework,\n componentName: componentKey,\n filePath: destFilePath,\n });\n content = transformResult.content;\n\n writeFile(destFilePath, content);\n } catch (error) {\n // Try with capitalized file name\n try {\n const capitalizedFile = file.charAt(0).toUpperCase() + file.slice(1);\n const sourceFolder = component.type === 'block' ? 'blocks' : 'components';\n const githubPath = `packages/${packageFramework}/src/${sourceFolder}/${componentKey}/${capitalizedFile}`;\n let content = await fetchFileFromGitHub(githubPath);\n\n // Apply transformations (import path fixes, 'use client' for Next.js, etc.)\n const transformResult = transformComponent(content, {\n platform: framework,\n componentName: componentKey,\n filePath: destFilePath,\n });\n content = transformResult.content;\n\n writeFile(destFilePath, content);\n } catch (capitalizedError) {\n // If both attempts fail, write a placeholder\n const placeholderContent = `// ${component.name} component for ${framework}\\n// TODO: Failed to fetch component from GitHub: ${error instanceof Error ? error.message : 'Unknown error'}\\n`;\n writeFile(destFilePath, placeholderContent);\n spinner.warn(`${chalk.yellow('⚠')} Failed to fetch ${file} from GitHub, created placeholder`);\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 // For Angular, generate/update the components/ui/index.ts file with providers\n if (framework === 'angular' && successful > 0) {\n console.log('\\n');\n const providerSpinner = ora('Generating providers index...').start();\n\n try {\n const componentsAlias = componentsConfig.aliases.components;\n const destPath = componentsAlias.replace('@/', '');\n const usesSrcDir = hasSrcDirectory(cwd);\n const baseDir = usesSrcDir ? 'src/' : '';\n const fullDestPath = resolve(cwd, baseDir + destPath, 'ui');\n\n const success = generateAngularProvidersIndex(fullDestPath, framework);\n\n if (success) {\n providerSpinner.succeed('Generated providers index at ' + chalk.cyan(`${destPath}/ui/index.ts`));\n } else {\n providerSpinner.warn('Could not generate providers index');\n }\n } catch (error) {\n providerSpinner.fail('Failed to generate providers index');\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 provideGalaxyComponents() in your app.config.ts providers array'));\n console.log(chalk.gray(' 2. Import the components in your Angular component'));\n console.log(chalk.gray(' 3. Use them in your templates'));\n break;\n }\n\n console.log(chalk.gray(' 4. Enjoy building with Galaxy UI! 🚀\\n'));\n }\n}\n"],"names":["prompts","chalk","ora","resolve","join","dirname","fileURLToPath","loadComponentsConfig","hasComponentsConfig","hasSrcDirectory","loadFrameworkRegistry","getFrameworkComponent","getFrameworkComponentDependencies","getAllFrameworkComponents","writeFile","fileExists","ensureDir","installDependencies","fetchFileFromGitHub","transformComponent","generateAngularProvidersIndex","__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","resolvedComponents","toProcess","componentKey","pop","registryDependencies","depKey","add","Array","from","allDependencies","allDevDependencies","results","success","error","spinner","start","componentsAlias","aliases","destPath","replace","usesSrcDir","baseDir","fullDestPath","fileExtensions","vue","react","angular","flutter","ext","componentFolderPath","packageFramework","file","files","fileName","includes","split","destFilePath","warn","sourceFolder","githubPath","content","transformResult","platform","componentName","filePath","capitalizedFile","capitalizedError","placeholderContent","Error","succeed","green","path","deps","dependencies","devDependencies","fail","uniqueDependencies","uniqueDevDependencies","installSpinner","dev","silent","successful","filter","r","failed","result","providerSpinner"],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -185,6 +185,7 @@ export async function initCommand(options) {
|
|
|
185
185
|
case 'angular':
|
|
186
186
|
// Angular components use Radix NG primitives
|
|
187
187
|
dependencies.push('@radix-ng/primitives');
|
|
188
|
+
devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');
|
|
188
189
|
if (config.iconLibrary === 'lucide') {
|
|
189
190
|
dependencies.push('lucide-angular');
|
|
190
191
|
}
|
|
@@ -251,7 +252,7 @@ export async function initCommand(options) {
|
|
|
251
252
|
return;
|
|
252
253
|
}
|
|
253
254
|
// Create Tailwind CSS configuration files (only for frameworks that use Tailwind)
|
|
254
|
-
if (framework !== 'flutter'
|
|
255
|
+
if (framework !== 'flutter') {
|
|
255
256
|
const tailwindSpinner = ora('Creating Tailwind CSS configuration...').start();
|
|
256
257
|
try {
|
|
257
258
|
// Create tailwind.config.js
|
|
@@ -260,7 +261,7 @@ export async function initCommand(options) {
|
|
|
260
261
|
writeFile(tailwindConfigPath, tailwindConfigContent);
|
|
261
262
|
// Create postcss.config.js
|
|
262
263
|
const postcssConfigPath = resolve(cwd, 'postcss.config.js');
|
|
263
|
-
const postcssConfigContent = getPostCSSConfigContent();
|
|
264
|
+
const postcssConfigContent = getPostCSSConfigContent(framework);
|
|
264
265
|
writeFile(postcssConfigPath, postcssConfigContent);
|
|
265
266
|
tailwindSpinner.succeed('Tailwind CSS configuration created');
|
|
266
267
|
} catch (error) {
|
|
@@ -340,11 +341,16 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
340
341
|
]` : framework === 'vue' || framework === 'nuxtjs' ? `[
|
|
341
342
|
"./index.html",
|
|
342
343
|
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
|
344
|
+
]` : framework === 'angular' ? `[
|
|
345
|
+
"./src/**/*.{html,ts}",
|
|
346
|
+
"./src/components/**/*.{html,ts}",
|
|
343
347
|
]` : `[
|
|
344
348
|
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
|
345
349
|
]`;
|
|
350
|
+
// Angular uses CommonJS, other frameworks use ES modules
|
|
351
|
+
const exportStatement = framework === 'angular' ? 'module.exports = ' : 'export default ';
|
|
346
352
|
return `/** @type {import('tailwindcss').Config} */
|
|
347
|
-
|
|
353
|
+
${exportStatement}{
|
|
348
354
|
darkMode: ["class"],
|
|
349
355
|
content: ${contentPaths},
|
|
350
356
|
theme: {
|
|
@@ -397,7 +403,17 @@ export default {
|
|
|
397
403
|
}
|
|
398
404
|
/**
|
|
399
405
|
* Get postcss.config.js content
|
|
400
|
-
*/ function getPostCSSConfigContent() {
|
|
406
|
+
*/ function getPostCSSConfigContent(framework) {
|
|
407
|
+
// Angular uses CommonJS, other frameworks use ES modules
|
|
408
|
+
if (framework === 'angular') {
|
|
409
|
+
return `module.exports = {
|
|
410
|
+
plugins: {
|
|
411
|
+
tailwindcss: {},
|
|
412
|
+
autoprefixer: {},
|
|
413
|
+
},
|
|
414
|
+
}
|
|
415
|
+
`;
|
|
416
|
+
}
|
|
401
417
|
return `export default {
|
|
402
418
|
plugins: {
|
|
403
419
|
tailwindcss: {},
|
|
@@ -631,6 +647,15 @@ export default {
|
|
|
631
647
|
${colors.dark}
|
|
632
648
|
}
|
|
633
649
|
}
|
|
650
|
+
|
|
651
|
+
@layer base {
|
|
652
|
+
* {
|
|
653
|
+
@apply border-border;
|
|
654
|
+
}
|
|
655
|
+
body {
|
|
656
|
+
@apply bg-background text-foreground;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
634
659
|
`;
|
|
635
660
|
}
|
|
636
661
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import prompts from 'prompts';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectFramework,\n detectPackageManager,\n hasSrcDirectory,\n type Framework as DetectedFramework,\n} from '../utils/detect.js';\nimport {\n createComponentsConfig,\n hasComponentsConfig,\n loadComponentsConfig,\n type Framework,\n} from '../utils/components-config.js';\nimport {\n getDefaultConfig,\n type BaseColor,\n type IconLibrary,\n} from '../utils/config-schema.js';\nimport { writeFile, ensureDir, readFile } from '../utils/files.js';\nimport { installDependencies } from '../utils/package-manager.js';\nimport { resolve } from 'path';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\n\ninterface InitOptions {\n yes?: boolean;\n cwd: string;\n}\n\nexport async function initCommand(options: InitOptions) {\n console.log(chalk.bold.cyan('\\n🌌 Galaxy UI CLI - Multi-Framework Edition\\n'));\n\n const cwd = options.cwd;\n\n // Check if already initialized\n if (hasComponentsConfig(cwd)) {\n console.log(chalk.yellow('⚠ components.json already exists in this project.'));\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'Do you want to overwrite the existing configuration?',\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n }\n\n // Detect framework\n const detectedFramework = detectFramework(cwd);\n\n if (detectedFramework === 'unknown') {\n console.log(\n chalk.red(\n '❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, Next.js, Nuxt.js, React Native, or Flutter project.'\n )\n );\n return;\n }\n\n console.log(chalk.green(`✓ Detected ${chalk.bold(detectedFramework)} framework`));\n\n // Map detected framework to Framework type\n const frameworkMap: Record<DetectedFramework, Framework | null> = {\n angular: 'angular',\n react: 'react',\n vue: 'vue',\n 'react-native': 'react-native',\n flutter: 'flutter',\n nextjs: 'nextjs',\n nuxtjs: 'nuxtjs',\n unknown: null,\n };\n\n const framework = frameworkMap[detectedFramework];\n if (!framework) {\n console.log(chalk.red('❌ Unsupported framework detected.'));\n return;\n }\n\n // Detect package manager\n const packageManager = detectPackageManager(cwd);\n console.log(chalk.green(`✓ Using ${chalk.bold(packageManager)} package manager`));\n\n // Get configuration from user (or use defaults with --yes)\n let config = getDefaultConfig(framework);\n\n // Detect if project uses src/ directory and adjust paths accordingly\n const usesSrcDir = hasSrcDirectory(cwd);\n if (usesSrcDir) {\n console.log(chalk.green(`✓ Detected ${chalk.bold('src/')} directory structure`));\n }\n\n if (!options.yes) {\n console.log(chalk.cyan('\\n📝 Configuration\\n'));\n\n // Build prompts based on framework\n const promptQuestions: any[] = [];\n\n // TypeScript prompt (not for Flutter)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'toggle',\n name: 'typescript',\n message: 'Would you like to use TypeScript?',\n initial: true,\n active: 'yes',\n inactive: 'no',\n });\n }\n\n // Base color prompt (for all frameworks)\n promptQuestions.push({\n type: 'select',\n name: 'baseColor',\n message: 'Which base color would you like to use?',\n choices: [\n { title: 'Slate', value: 'slate' },\n { title: 'Gray', value: 'gray' },\n { title: 'Zinc', value: 'zinc' },\n { title: 'Neutral', value: 'neutral' },\n { title: 'Stone', value: 'stone' },\n ],\n initial: 0,\n });\n\n // Icon library prompt (not for Flutter - uses built-in icons)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'select',\n name: 'iconLibrary',\n message: 'Which icon library would you like to use?',\n choices: [\n { title: 'Lucide (Recommended)', value: 'lucide' },\n { title: 'Heroicons', value: 'heroicons' },\n { title: 'Radix Icons', value: 'radix-icons' },\n ],\n initial: 0,\n });\n }\n\n // CSS file prompt (only for web frameworks and React Native)\n if (framework !== 'flutter' && config.tailwind.css) {\n promptQuestions.push({\n type: 'text',\n name: 'cssFile',\n message: framework === 'react-native'\n ? 'Where is your global CSS file (for NativeWind)?'\n : 'Where is your global CSS file?',\n initial: config.tailwind.css,\n });\n }\n\n const answers = await prompts(promptQuestions);\n\n if (Object.keys(answers).length === 0) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n\n // Update config with user choices\n config = {\n ...config,\n typescript: answers.typescript ?? config.typescript,\n iconLibrary: (answers.iconLibrary as IconLibrary) ?? config.iconLibrary,\n tailwind: {\n ...config.tailwind,\n baseColor: (answers.baseColor as BaseColor) ?? config.tailwind.baseColor,\n css: answers.cssFile ?? config.tailwind.css,\n },\n };\n }\n\n console.log(chalk.cyan('\\n📦 Installing dependencies...\\n'));\n\n // Install dependencies\n const spinner = ora('Installing dependencies...').start();\n\n const dependencies: string[] = [];\n const devDependencies: string[] = [];\n\n // Common dependencies\n dependencies.push('clsx', 'tailwind-merge');\n\n // Framework-specific dependencies\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n dependencies.push('radix-vue');\n devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-vue-next');\n }\n if (config.typescript) {\n devDependencies.push('@types/node');\n }\n break;\n\n case 'react':\n case 'nextjs':\n dependencies.push('@radix-ui/react-slot');\n devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-react');\n }\n if (config.typescript) {\n devDependencies.push('@types/react', '@types/react-dom', '@types/node');\n }\n break;\n\n case 'angular':\n // Angular components use Radix NG primitives\n dependencies.push('@radix-ng/primitives');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-angular');\n }\n break;\n }\n\n try {\n // Install dependencies\n if (dependencies.length > 0) {\n await installDependencies(dependencies, {\n cwd,\n silent: true,\n });\n }\n\n // Install devDependencies\n if (devDependencies.length > 0) {\n await installDependencies(devDependencies, {\n cwd,\n dev: true,\n silent: true,\n });\n }\n\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red(error));\n return;\n }\n\n // Create directories\n const dirSpinner = ora('Creating directories...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const componentsPath = resolve(cwd, baseDir + config.aliases.components.replace('@/', ''));\n const utilsPath = resolve(cwd, baseDir + config.aliases.utils.replace('@/', ''));\n\n await ensureDir(componentsPath);\n await ensureDir(resolve(componentsPath, 'ui'));\n await ensureDir(utilsPath.replace('/utils', '')); // Create lib dir\n\n dirSpinner.succeed('Directories created');\n } catch (error) {\n dirSpinner.fail('Failed to create directories');\n console.error(chalk.red(error));\n return;\n }\n\n // Create utils file\n const utilsSpinner = ora('Creating utility functions...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const utilsPath = resolve(cwd, baseDir + config.aliases.utils.replace('@/', '') + '.ts');\n const utilsContent = getUtilsContent();\n writeFile(utilsPath, utilsContent);\n\n utilsSpinner.succeed('Utility functions created');\n } catch (error) {\n utilsSpinner.fail('Failed to create utility functions');\n console.error(chalk.red(error));\n return;\n }\n\n // Save components.json\n const configSpinner = ora('Creating components.json...').start();\n\n try {\n createComponentsConfig(cwd, framework);\n configSpinner.succeed('components.json created');\n } catch (error) {\n configSpinner.fail('Failed to create components.json');\n console.error(chalk.red(error));\n return;\n }\n\n // Create Tailwind CSS configuration files (only for frameworks that use Tailwind)\n if (framework !== 'flutter' && framework !== 'angular') {\n const tailwindSpinner = ora('Creating Tailwind CSS configuration...').start();\n\n try {\n // Create tailwind.config.js\n const tailwindConfigPath = resolve(cwd, config.tailwind.config);\n const tailwindConfigContent = getTailwindConfigContent(framework);\n writeFile(tailwindConfigPath, tailwindConfigContent);\n\n // Create postcss.config.js\n const postcssConfigPath = resolve(cwd, 'postcss.config.js');\n const postcssConfigContent = getPostCSSConfigContent();\n writeFile(postcssConfigPath, postcssConfigContent);\n\n tailwindSpinner.succeed('Tailwind CSS configuration created');\n } catch (error) {\n tailwindSpinner.fail('Failed to create Tailwind CSS configuration');\n console.error(chalk.red(error));\n return;\n }\n\n // Create or update CSS file with Tailwind directives\n const cssSpinner = ora('Setting up CSS file...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const cssPath = resolve(cwd, baseDir + config.tailwind.css.replace('src/', ''));\n const cssContent = getCSSContent(config.tailwind.baseColor);\n writeFile(cssPath, cssContent);\n\n cssSpinner.succeed('CSS file configured');\n } catch (error) {\n cssSpinner.fail('Failed to configure CSS file');\n console.error(chalk.red(error));\n return;\n }\n }\n\n // Configure path aliases for TypeScript and bundler\n if (config.typescript && framework !== 'flutter') {\n const aliasSpinner = ora('Configuring path aliases...').start();\n\n try {\n // Configure TypeScript path aliases\n if (framework === 'react' || framework === 'angular' || framework === 'vue') {\n // Vite React, Angular, and Vue use tsconfig.app.json\n configureTypeScriptAliases(cwd, 'tsconfig.app.json', usesSrcDir);\n } else if (framework === 'nextjs') {\n // Next.js uses tsconfig.json\n configureTypeScriptAliases(cwd, 'tsconfig.json', usesSrcDir);\n }\n\n // Configure bundler path aliases (only for Vite projects, not Next.js/Nuxt)\n if (framework === 'react' || framework === 'vue') {\n // Both React and Vue Vite projects use vite.config.ts\n configureViteAliases(cwd, 'vite.config.ts');\n }\n\n aliasSpinner.succeed('Path aliases configured');\n } catch (error) {\n aliasSpinner.fail('Failed to configure path aliases');\n console.error(chalk.red(error));\n // Don't return - this is not critical\n }\n }\n\n // Success message\n console.log(chalk.green('\\n✨ Success! Galaxy UI has been initialized.\\n'));\n console.log(chalk.cyan('Next steps:\\n'));\n console.log(chalk.white(` 1. Add components:`));\n console.log(chalk.gray(` galaxy-design add button`));\n console.log(chalk.gray(` galaxy-design add input card`));\n console.log(chalk.gray(` galaxy-design add --all\\n`));\n\n console.log(chalk.cyan('Learn more:'));\n console.log(chalk.white(' Documentation: https://galaxy-design.vercel.app'));\n console.log(chalk.white(' GitHub: https://github.com/buikevin/galaxy-design\\n'));\n}\n\n/**\n * Get utils.ts content\n */\nfunction getUtilsContent(): string {\n return `import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge Tailwind CSS classes\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n`;\n}\n\n/**\n * Get tailwind.config.js content\n */\nfunction getTailwindConfigContent(framework: Framework): string {\n const contentPaths =\n framework === 'react' || framework === 'nextjs'\n ? `[\n \"./index.html\",\n \"./src/**/*.{js,ts,jsx,tsx}\",\n ]`\n : framework === 'vue' || framework === 'nuxtjs'\n ? `[\n \"./index.html\",\n \"./src/**/*.{vue,js,ts,jsx,tsx}\",\n ]`\n : `[\n \"./src/**/*.{js,ts,jsx,tsx,mdx}\",\n ]`;\n\n return `/** @type {import('tailwindcss').Config} */\nexport default {\n darkMode: [\"class\"],\n content: ${contentPaths},\n theme: {\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n },\n },\n plugins: [],\n}\n`;\n}\n\n/**\n * Get postcss.config.js content\n */\nfunction getPostCSSConfigContent(): string {\n return `export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n}\n`;\n}\n\n/**\n * Get CSS file content with Tailwind directives and CSS variables\n */\nfunction getCSSContent(baseColor: BaseColor): string {\n // CSS variables based on base color\n const colorVariables: Record<BaseColor, { light: string; dark: string }> = {\n slate: {\n light: `--background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n --radius: 0.5rem;`,\n dark: `--background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;`,\n },\n gray: {\n light: `--background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n --border: 220 13% 91%;\n --input: 220 13% 91%;\n --ring: 224 71.4% 4.1%;\n --radius: 0.5rem;`,\n dark: `--background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n --ring: 216 12.2% 83.9%;`,\n },\n zinc: {\n light: `--background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n --ring: 240 10% 3.9%;\n --radius: 0.5rem;`,\n dark: `--background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n --ring: 240 4.9% 83.9%;`,\n },\n neutral: {\n light: `--background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n --ring: 0 0% 3.9%;\n --radius: 0.5rem;`,\n dark: `--background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n --ring: 0 0% 83.1%;`,\n },\n stone: {\n light: `--background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n --ring: 20 14.3% 4.1%;\n --radius: 0.5rem;`,\n dark: `--background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n --ring: 24 5.7% 82.9%;`,\n },\n };\n\n const colors = colorVariables[baseColor];\n\n return `@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n ${colors.light}\n }\n\n .dark {\n ${colors.dark}\n }\n}\n`;\n}\n\n/**\n * Configure TypeScript path aliases in tsconfig\n */\nfunction configureTypeScriptAliases(cwd: string, tsconfigFile: string, usesSrcDir: boolean): void {\n const tsconfigPath = resolve(cwd, tsconfigFile);\n\n if (!existsSync(tsconfigPath)) {\n return;\n }\n\n try {\n let content = readFileSync(tsconfigPath, 'utf-8');\n\n // Determine the correct path based on project structure\n const pathMapping = usesSrcDir ? './src/*' : './*';\n\n // Simple check: if \"paths\" already exists anywhere in the file, skip\n // This prevents duplicates for frameworks like Next.js that pre-configure paths\n if (content.includes('\"paths\"')) {\n return; // Paths already configured, skip to avoid duplicates\n }\n\n // Find the position to insert path aliases\n const compilerOptionsMatch = content.match(/\"compilerOptions\"\\s*:\\s*{/);\n if (!compilerOptionsMatch) {\n throw new Error('compilerOptions not found');\n }\n\n // Strategy: Insert before the closing } of compilerOptions\n // Match the closing brace of compilerOptions followed by next root property\n const insertPattern = /(\\n)(\\s*)(}\\s*,?\\s*\\n\\s*\"(?:include|exclude|files|references))/;\n const match = content.match(insertPattern);\n\n if (match) {\n // Detect indent level from the closing brace\n const baseIndent = match[2] || ' ';\n const propertyIndent = baseIndent + ' ';\n\n // Insert path config before the closing brace\n const pathConfig = `,${match[1]}${propertyIndent}/* Path Aliases */${match[1]}${propertyIndent}\"baseUrl\": \".\",${match[1]}${propertyIndent}\"paths\": {${match[1]}${propertyIndent} \"@/*\": [\"${pathMapping}\"]${match[1]}${propertyIndent}}`;\n\n content = content.replace(insertPattern, `${pathConfig}${match[1]}${match[2]}${match[3]}`);\n writeFileSync(tsconfigPath, content, 'utf-8');\n }\n } catch (error) {\n // Silently fail - path aliases are not critical\n }\n}\n\n/**\n * Configure Vite path aliases in vite.config\n */\nfunction configureViteAliases(cwd: string, viteConfigFile: string): void {\n const viteConfigPath = resolve(cwd, viteConfigFile);\n\n if (!existsSync(viteConfigPath)) {\n return;\n }\n\n try {\n let content = readFileSync(viteConfigPath, 'utf-8');\n\n // Check if path is already imported\n if (!content.includes(\"import path from 'path'\") && !content.includes('import path from \"path\"')) {\n // Add path import after the first import line\n content = content.replace(\n /(import .+ from .+\\n)/,\n \"$1import path from 'path'\\n\"\n );\n }\n\n // Check if resolve.alias is already configured\n if (!content.includes('resolve:') && !content.includes('@:')) {\n // Add resolve.alias configuration\n content = content.replace(\n /(plugins: \\[.+\\],?)/s,\n `$1\\n resolve: {\\n alias: {\\n '@': path.resolve(__dirname, './src'),\\n },\\n },`\n );\n }\n\n writeFileSync(viteConfigPath, content, 'utf-8');\n } catch (error) {\n console.error(chalk.yellow(`Warning: Could not update ${viteConfigFile}`));\n }\n}\n"],"names":["prompts","chalk","ora","detectFramework","detectPackageManager","hasSrcDirectory","createComponentsConfig","hasComponentsConfig","getDefaultConfig","writeFile","ensureDir","installDependencies","resolve","existsSync","readFileSync","writeFileSync","initCommand","options","console","log","bold","cyan","cwd","yellow","overwrite","type","name","message","initial","gray","detectedFramework","red","green","frameworkMap","angular","react","vue","flutter","nextjs","nuxtjs","unknown","framework","packageManager","config","usesSrcDir","yes","promptQuestions","push","active","inactive","choices","title","value","tailwind","css","answers","Object","keys","length","typescript","iconLibrary","baseColor","cssFile","spinner","start","dependencies","devDependencies","silent","dev","succeed","error","fail","dirSpinner","baseDir","componentsPath","aliases","components","replace","utilsPath","utils","utilsSpinner","utilsContent","getUtilsContent","configSpinner","tailwindSpinner","tailwindConfigPath","tailwindConfigContent","getTailwindConfigContent","postcssConfigPath","postcssConfigContent","getPostCSSConfigContent","cssSpinner","cssPath","cssContent","getCSSContent","aliasSpinner","configureTypeScriptAliases","configureViteAliases","white","contentPaths","colorVariables","slate","light","dark","zinc","neutral","stone","colors","tsconfigFile","tsconfigPath","content","pathMapping","includes","compilerOptionsMatch","match","Error","insertPattern","baseIndent","propertyIndent","pathConfig","viteConfigFile","viteConfigPath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import prompts from 'prompts';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectFramework,\n detectPackageManager,\n hasSrcDirectory,\n type Framework as DetectedFramework,\n} from '../utils/detect.js';\nimport {\n createComponentsConfig,\n hasComponentsConfig,\n loadComponentsConfig,\n type Framework,\n} from '../utils/components-config.js';\nimport {\n getDefaultConfig,\n type BaseColor,\n type IconLibrary,\n} from '../utils/config-schema.js';\nimport { writeFile, ensureDir, readFile } from '../utils/files.js';\nimport { installDependencies } from '../utils/package-manager.js';\nimport { resolve } from 'path';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\n\ninterface InitOptions {\n yes?: boolean;\n cwd: string;\n}\n\nexport async function initCommand(options: InitOptions) {\n console.log(chalk.bold.cyan('\\n🌌 Galaxy UI CLI - Multi-Framework Edition\\n'));\n\n const cwd = options.cwd;\n\n // Check if already initialized\n if (hasComponentsConfig(cwd)) {\n console.log(chalk.yellow('⚠ components.json already exists in this project.'));\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: 'Do you want to overwrite the existing configuration?',\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n }\n\n // Detect framework\n const detectedFramework = detectFramework(cwd);\n\n if (detectedFramework === 'unknown') {\n console.log(\n chalk.red(\n '❌ Could not detect framework. Please ensure you are in a valid Angular, React, Vue, Next.js, Nuxt.js, React Native, or Flutter project.'\n )\n );\n return;\n }\n\n console.log(chalk.green(`✓ Detected ${chalk.bold(detectedFramework)} framework`));\n\n // Map detected framework to Framework type\n const frameworkMap: Record<DetectedFramework, Framework | null> = {\n angular: 'angular',\n react: 'react',\n vue: 'vue',\n 'react-native': 'react-native',\n flutter: 'flutter',\n nextjs: 'nextjs',\n nuxtjs: 'nuxtjs',\n unknown: null,\n };\n\n const framework = frameworkMap[detectedFramework];\n if (!framework) {\n console.log(chalk.red('❌ Unsupported framework detected.'));\n return;\n }\n\n // Detect package manager\n const packageManager = detectPackageManager(cwd);\n console.log(chalk.green(`✓ Using ${chalk.bold(packageManager)} package manager`));\n\n // Get configuration from user (or use defaults with --yes)\n let config = getDefaultConfig(framework);\n\n // Detect if project uses src/ directory and adjust paths accordingly\n const usesSrcDir = hasSrcDirectory(cwd);\n if (usesSrcDir) {\n console.log(chalk.green(`✓ Detected ${chalk.bold('src/')} directory structure`));\n }\n\n if (!options.yes) {\n console.log(chalk.cyan('\\n📝 Configuration\\n'));\n\n // Build prompts based on framework\n const promptQuestions: any[] = [];\n\n // TypeScript prompt (not for Flutter)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'toggle',\n name: 'typescript',\n message: 'Would you like to use TypeScript?',\n initial: true,\n active: 'yes',\n inactive: 'no',\n });\n }\n\n // Base color prompt (for all frameworks)\n promptQuestions.push({\n type: 'select',\n name: 'baseColor',\n message: 'Which base color would you like to use?',\n choices: [\n { title: 'Slate', value: 'slate' },\n { title: 'Gray', value: 'gray' },\n { title: 'Zinc', value: 'zinc' },\n { title: 'Neutral', value: 'neutral' },\n { title: 'Stone', value: 'stone' },\n ],\n initial: 0,\n });\n\n // Icon library prompt (not for Flutter - uses built-in icons)\n if (framework !== 'flutter') {\n promptQuestions.push({\n type: 'select',\n name: 'iconLibrary',\n message: 'Which icon library would you like to use?',\n choices: [\n { title: 'Lucide (Recommended)', value: 'lucide' },\n { title: 'Heroicons', value: 'heroicons' },\n { title: 'Radix Icons', value: 'radix-icons' },\n ],\n initial: 0,\n });\n }\n\n // CSS file prompt (only for web frameworks and React Native)\n if (framework !== 'flutter' && config.tailwind.css) {\n promptQuestions.push({\n type: 'text',\n name: 'cssFile',\n message: framework === 'react-native'\n ? 'Where is your global CSS file (for NativeWind)?'\n : 'Where is your global CSS file?',\n initial: config.tailwind.css,\n });\n }\n\n const answers = await prompts(promptQuestions);\n\n if (Object.keys(answers).length === 0) {\n console.log(chalk.gray('Initialization cancelled.'));\n return;\n }\n\n // Update config with user choices\n config = {\n ...config,\n typescript: answers.typescript ?? config.typescript,\n iconLibrary: (answers.iconLibrary as IconLibrary) ?? config.iconLibrary,\n tailwind: {\n ...config.tailwind,\n baseColor: (answers.baseColor as BaseColor) ?? config.tailwind.baseColor,\n css: answers.cssFile ?? config.tailwind.css,\n },\n };\n }\n\n console.log(chalk.cyan('\\n📦 Installing dependencies...\\n'));\n\n // Install dependencies\n const spinner = ora('Installing dependencies...').start();\n\n const dependencies: string[] = [];\n const devDependencies: string[] = [];\n\n // Common dependencies\n dependencies.push('clsx', 'tailwind-merge');\n\n // Framework-specific dependencies\n switch (framework) {\n case 'vue':\n case 'nuxtjs':\n dependencies.push('radix-vue');\n devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-vue-next');\n }\n if (config.typescript) {\n devDependencies.push('@types/node');\n }\n break;\n\n case 'react':\n case 'nextjs':\n dependencies.push('@radix-ui/react-slot');\n devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-react');\n }\n if (config.typescript) {\n devDependencies.push('@types/react', '@types/react-dom', '@types/node');\n }\n break;\n\n case 'angular':\n // Angular components use Radix NG primitives\n dependencies.push('@radix-ng/primitives');\n devDependencies.push('tailwindcss@3.4.0', 'autoprefixer', 'postcss');\n if (config.iconLibrary === 'lucide') {\n dependencies.push('lucide-angular');\n }\n break;\n }\n\n try {\n // Install dependencies\n if (dependencies.length > 0) {\n await installDependencies(dependencies, {\n cwd,\n silent: true,\n });\n }\n\n // Install devDependencies\n if (devDependencies.length > 0) {\n await installDependencies(devDependencies, {\n cwd,\n dev: true,\n silent: true,\n });\n }\n\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red(error));\n return;\n }\n\n // Create directories\n const dirSpinner = ora('Creating directories...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const componentsPath = resolve(cwd, baseDir + config.aliases.components.replace('@/', ''));\n const utilsPath = resolve(cwd, baseDir + config.aliases.utils.replace('@/', ''));\n\n await ensureDir(componentsPath);\n await ensureDir(resolve(componentsPath, 'ui'));\n await ensureDir(utilsPath.replace('/utils', '')); // Create lib dir\n\n dirSpinner.succeed('Directories created');\n } catch (error) {\n dirSpinner.fail('Failed to create directories');\n console.error(chalk.red(error));\n return;\n }\n\n // Create utils file\n const utilsSpinner = ora('Creating utility functions...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const utilsPath = resolve(cwd, baseDir + config.aliases.utils.replace('@/', '') + '.ts');\n const utilsContent = getUtilsContent();\n writeFile(utilsPath, utilsContent);\n\n utilsSpinner.succeed('Utility functions created');\n } catch (error) {\n utilsSpinner.fail('Failed to create utility functions');\n console.error(chalk.red(error));\n return;\n }\n\n // Save components.json\n const configSpinner = ora('Creating components.json...').start();\n\n try {\n createComponentsConfig(cwd, framework);\n configSpinner.succeed('components.json created');\n } catch (error) {\n configSpinner.fail('Failed to create components.json');\n console.error(chalk.red(error));\n return;\n }\n\n // Create Tailwind CSS configuration files (only for frameworks that use Tailwind)\n if (framework !== 'flutter') {\n const tailwindSpinner = ora('Creating Tailwind CSS configuration...').start();\n\n try {\n // Create tailwind.config.js\n const tailwindConfigPath = resolve(cwd, config.tailwind.config);\n const tailwindConfigContent = getTailwindConfigContent(framework);\n writeFile(tailwindConfigPath, tailwindConfigContent);\n\n // Create postcss.config.js\n const postcssConfigPath = resolve(cwd, 'postcss.config.js');\n const postcssConfigContent = getPostCSSConfigContent(framework);\n writeFile(postcssConfigPath, postcssConfigContent);\n\n tailwindSpinner.succeed('Tailwind CSS configuration created');\n } catch (error) {\n tailwindSpinner.fail('Failed to create Tailwind CSS configuration');\n console.error(chalk.red(error));\n return;\n }\n\n // Create or update CSS file with Tailwind directives\n const cssSpinner = ora('Setting up CSS file...').start();\n\n try {\n const baseDir = usesSrcDir ? 'src/' : '';\n const cssPath = resolve(cwd, baseDir + config.tailwind.css.replace('src/', ''));\n const cssContent = getCSSContent(config.tailwind.baseColor);\n writeFile(cssPath, cssContent);\n\n cssSpinner.succeed('CSS file configured');\n } catch (error) {\n cssSpinner.fail('Failed to configure CSS file');\n console.error(chalk.red(error));\n return;\n }\n }\n\n // Configure path aliases for TypeScript and bundler\n if (config.typescript && framework !== 'flutter') {\n const aliasSpinner = ora('Configuring path aliases...').start();\n\n try {\n // Configure TypeScript path aliases\n if (framework === 'react' || framework === 'angular' || framework === 'vue') {\n // Vite React, Angular, and Vue use tsconfig.app.json\n configureTypeScriptAliases(cwd, 'tsconfig.app.json', usesSrcDir);\n } else if (framework === 'nextjs') {\n // Next.js uses tsconfig.json\n configureTypeScriptAliases(cwd, 'tsconfig.json', usesSrcDir);\n }\n\n // Configure bundler path aliases (only for Vite projects, not Next.js/Nuxt)\n if (framework === 'react' || framework === 'vue') {\n // Both React and Vue Vite projects use vite.config.ts\n configureViteAliases(cwd, 'vite.config.ts');\n }\n\n aliasSpinner.succeed('Path aliases configured');\n } catch (error) {\n aliasSpinner.fail('Failed to configure path aliases');\n console.error(chalk.red(error));\n // Don't return - this is not critical\n }\n }\n\n // Success message\n console.log(chalk.green('\\n✨ Success! Galaxy UI has been initialized.\\n'));\n console.log(chalk.cyan('Next steps:\\n'));\n console.log(chalk.white(` 1. Add components:`));\n console.log(chalk.gray(` galaxy-design add button`));\n console.log(chalk.gray(` galaxy-design add input card`));\n console.log(chalk.gray(` galaxy-design add --all\\n`));\n\n console.log(chalk.cyan('Learn more:'));\n console.log(chalk.white(' Documentation: https://galaxy-design.vercel.app'));\n console.log(chalk.white(' GitHub: https://github.com/buikevin/galaxy-design\\n'));\n}\n\n/**\n * Get utils.ts content\n */\nfunction getUtilsContent(): string {\n return `import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge Tailwind CSS classes\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n`;\n}\n\n/**\n * Get tailwind.config.js content\n */\nfunction getTailwindConfigContent(framework: Framework): string {\n const contentPaths =\n framework === 'react' || framework === 'nextjs'\n ? `[\n \"./index.html\",\n \"./src/**/*.{js,ts,jsx,tsx}\",\n ]`\n : framework === 'vue' || framework === 'nuxtjs'\n ? `[\n \"./index.html\",\n \"./src/**/*.{vue,js,ts,jsx,tsx}\",\n ]`\n : framework === 'angular'\n ? `[\n \"./src/**/*.{html,ts}\",\n \"./src/components/**/*.{html,ts}\",\n ]`\n : `[\n \"./src/**/*.{js,ts,jsx,tsx,mdx}\",\n ]`;\n\n // Angular uses CommonJS, other frameworks use ES modules\n const exportStatement = framework === 'angular'\n ? 'module.exports = '\n : 'export default ';\n\n return `/** @type {import('tailwindcss').Config} */\n${exportStatement}{\n darkMode: [\"class\"],\n content: ${contentPaths},\n theme: {\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n },\n },\n plugins: [],\n}\n`;\n}\n\n/**\n * Get postcss.config.js content\n */\nfunction getPostCSSConfigContent(framework: Framework): string {\n // Angular uses CommonJS, other frameworks use ES modules\n if (framework === 'angular') {\n return `module.exports = {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n}\n`;\n }\n\n return `export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n}\n`;\n}\n\n/**\n * Get CSS file content with Tailwind directives and CSS variables\n */\nfunction getCSSContent(baseColor: BaseColor): string {\n // CSS variables based on base color\n const colorVariables: Record<BaseColor, { light: string; dark: string }> = {\n slate: {\n light: `--background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n --radius: 0.5rem;`,\n dark: `--background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;`,\n },\n gray: {\n light: `--background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n --border: 220 13% 91%;\n --input: 220 13% 91%;\n --ring: 224 71.4% 4.1%;\n --radius: 0.5rem;`,\n dark: `--background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n --ring: 216 12.2% 83.9%;`,\n },\n zinc: {\n light: `--background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n --ring: 240 10% 3.9%;\n --radius: 0.5rem;`,\n dark: `--background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n --ring: 240 4.9% 83.9%;`,\n },\n neutral: {\n light: `--background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n --ring: 0 0% 3.9%;\n --radius: 0.5rem;`,\n dark: `--background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n --ring: 0 0% 83.1%;`,\n },\n stone: {\n light: `--background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n --ring: 20 14.3% 4.1%;\n --radius: 0.5rem;`,\n dark: `--background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n --ring: 24 5.7% 82.9%;`,\n },\n };\n\n const colors = colorVariables[baseColor];\n\n return `@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n ${colors.light}\n }\n\n .dark {\n ${colors.dark}\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}\n`;\n}\n\n/**\n * Configure TypeScript path aliases in tsconfig\n */\nfunction configureTypeScriptAliases(cwd: string, tsconfigFile: string, usesSrcDir: boolean): void {\n const tsconfigPath = resolve(cwd, tsconfigFile);\n\n if (!existsSync(tsconfigPath)) {\n return;\n }\n\n try {\n let content = readFileSync(tsconfigPath, 'utf-8');\n\n // Determine the correct path based on project structure\n const pathMapping = usesSrcDir ? './src/*' : './*';\n\n // Simple check: if \"paths\" already exists anywhere in the file, skip\n // This prevents duplicates for frameworks like Next.js that pre-configure paths\n if (content.includes('\"paths\"')) {\n return; // Paths already configured, skip to avoid duplicates\n }\n\n // Find the position to insert path aliases\n const compilerOptionsMatch = content.match(/\"compilerOptions\"\\s*:\\s*{/);\n if (!compilerOptionsMatch) {\n throw new Error('compilerOptions not found');\n }\n\n // Strategy: Insert before the closing } of compilerOptions\n // Match the closing brace of compilerOptions followed by next root property\n const insertPattern = /(\\n)(\\s*)(}\\s*,?\\s*\\n\\s*\"(?:include|exclude|files|references))/;\n const match = content.match(insertPattern);\n\n if (match) {\n // Detect indent level from the closing brace\n const baseIndent = match[2] || ' ';\n const propertyIndent = baseIndent + ' ';\n\n // Insert path config before the closing brace\n const pathConfig = `,${match[1]}${propertyIndent}/* Path Aliases */${match[1]}${propertyIndent}\"baseUrl\": \".\",${match[1]}${propertyIndent}\"paths\": {${match[1]}${propertyIndent} \"@/*\": [\"${pathMapping}\"]${match[1]}${propertyIndent}}`;\n\n content = content.replace(insertPattern, `${pathConfig}${match[1]}${match[2]}${match[3]}`);\n writeFileSync(tsconfigPath, content, 'utf-8');\n }\n } catch (error) {\n // Silently fail - path aliases are not critical\n }\n}\n\n/**\n * Configure Vite path aliases in vite.config\n */\nfunction configureViteAliases(cwd: string, viteConfigFile: string): void {\n const viteConfigPath = resolve(cwd, viteConfigFile);\n\n if (!existsSync(viteConfigPath)) {\n return;\n }\n\n try {\n let content = readFileSync(viteConfigPath, 'utf-8');\n\n // Check if path is already imported\n if (!content.includes(\"import path from 'path'\") && !content.includes('import path from \"path\"')) {\n // Add path import after the first import line\n content = content.replace(\n /(import .+ from .+\\n)/,\n \"$1import path from 'path'\\n\"\n );\n }\n\n // Check if resolve.alias is already configured\n if (!content.includes('resolve:') && !content.includes('@:')) {\n // Add resolve.alias configuration\n content = content.replace(\n /(plugins: \\[.+\\],?)/s,\n `$1\\n resolve: {\\n alias: {\\n '@': path.resolve(__dirname, './src'),\\n },\\n },`\n );\n }\n\n writeFileSync(viteConfigPath, content, 'utf-8');\n } catch (error) {\n console.error(chalk.yellow(`Warning: Could not update ${viteConfigFile}`));\n }\n}\n"],"names":["prompts","chalk","ora","detectFramework","detectPackageManager","hasSrcDirectory","createComponentsConfig","hasComponentsConfig","getDefaultConfig","writeFile","ensureDir","installDependencies","resolve","existsSync","readFileSync","writeFileSync","initCommand","options","console","log","bold","cyan","cwd","yellow","overwrite","type","name","message","initial","gray","detectedFramework","red","green","frameworkMap","angular","react","vue","flutter","nextjs","nuxtjs","unknown","framework","packageManager","config","usesSrcDir","yes","promptQuestions","push","active","inactive","choices","title","value","tailwind","css","answers","Object","keys","length","typescript","iconLibrary","baseColor","cssFile","spinner","start","dependencies","devDependencies","silent","dev","succeed","error","fail","dirSpinner","baseDir","componentsPath","aliases","components","replace","utilsPath","utils","utilsSpinner","utilsContent","getUtilsContent","configSpinner","tailwindSpinner","tailwindConfigPath","tailwindConfigContent","getTailwindConfigContent","postcssConfigPath","postcssConfigContent","getPostCSSConfigContent","cssSpinner","cssPath","cssContent","getCSSContent","aliasSpinner","configureTypeScriptAliases","configureViteAliases","white","contentPaths","exportStatement","colorVariables","slate","light","dark","zinc","neutral","stone","colors","tsconfigFile","tsconfigPath","content","pathMapping","includes","compilerOptionsMatch","match","Error","insertPattern","baseIndent","propertyIndent","pathConfig","viteConfigFile","viteConfigPath"],"mappings":"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"}
|
|
@@ -174,9 +174,10 @@
|
|
|
174
174
|
"name": "Accordion",
|
|
175
175
|
"selector": "g-accordion",
|
|
176
176
|
"type": "layout",
|
|
177
|
-
"description": "Collapsible sections with expand/collapse",
|
|
177
|
+
"description": "Collapsible sections with expand/collapse (directive-based with Radix support)",
|
|
178
178
|
"files": [
|
|
179
179
|
"accordion.component.ts",
|
|
180
|
+
"accordion.directive.ts",
|
|
180
181
|
"index.ts"
|
|
181
182
|
],
|
|
182
183
|
"dependencies": [
|
|
@@ -187,16 +188,21 @@
|
|
|
187
188
|
],
|
|
188
189
|
"exports": [
|
|
189
190
|
"AccordionComponent",
|
|
190
|
-
"AccordionItemComponent"
|
|
191
|
+
"AccordionItemComponent",
|
|
192
|
+
"UiAccordionRootDirective",
|
|
193
|
+
"UiAccordionItemDirective",
|
|
194
|
+
"UiAccordionTriggerDirective",
|
|
195
|
+
"UiAccordionContentDirective"
|
|
191
196
|
]
|
|
192
197
|
},
|
|
193
198
|
"collapsible": {
|
|
194
199
|
"name": "Collapsible",
|
|
195
200
|
"selector": "g-collapsible",
|
|
196
201
|
"type": "layout",
|
|
197
|
-
"description": "Collapsible content panel",
|
|
202
|
+
"description": "Collapsible content panel (directive-based with Radix support)",
|
|
198
203
|
"files": [
|
|
199
204
|
"collapsible.component.ts",
|
|
205
|
+
"collapsible.directive.ts",
|
|
200
206
|
"index.ts"
|
|
201
207
|
],
|
|
202
208
|
"dependencies": [
|
|
@@ -204,7 +210,10 @@
|
|
|
204
210
|
],
|
|
205
211
|
"peerDependencies": [],
|
|
206
212
|
"exports": [
|
|
207
|
-
"CollapsibleComponent"
|
|
213
|
+
"CollapsibleComponent",
|
|
214
|
+
"UiCollapsibleRootDirective",
|
|
215
|
+
"UiCollapsibleTriggerDirective",
|
|
216
|
+
"UiCollapsibleContentDirective"
|
|
208
217
|
]
|
|
209
218
|
},
|
|
210
219
|
"separator": {
|
|
@@ -228,10 +237,11 @@
|
|
|
228
237
|
"name": "Tabs",
|
|
229
238
|
"selector": "g-tabs",
|
|
230
239
|
"type": "navigation",
|
|
231
|
-
"description": "Tabbed content organization",
|
|
240
|
+
"description": "Tabbed content organization (directive-based with Radix support)",
|
|
232
241
|
"files": [
|
|
233
242
|
"index.ts",
|
|
234
|
-
"tabs.component.ts"
|
|
243
|
+
"tabs.component.ts",
|
|
244
|
+
"tabs.directive.ts"
|
|
235
245
|
],
|
|
236
246
|
"dependencies": [
|
|
237
247
|
"@radix-ng/primitives"
|
|
@@ -242,7 +252,11 @@
|
|
|
242
252
|
"exports": [
|
|
243
253
|
"TabsComponent",
|
|
244
254
|
"TabComponent",
|
|
245
|
-
"TabPanelComponent"
|
|
255
|
+
"TabPanelComponent",
|
|
256
|
+
"UiTabsRootDirective",
|
|
257
|
+
"UiTabsListDirective",
|
|
258
|
+
"UiTabsTriggerDirective",
|
|
259
|
+
"UiTabsContentDirective"
|
|
246
260
|
]
|
|
247
261
|
},
|
|
248
262
|
"dropdown-menu": {
|
|
@@ -337,18 +351,26 @@
|
|
|
337
351
|
"name": "Tooltip",
|
|
338
352
|
"selector": "g-tooltip",
|
|
339
353
|
"type": "modal-overlay",
|
|
340
|
-
"description": "Tooltip component for hover information (
|
|
354
|
+
"description": "Tooltip component for hover information (directive-based with Radix support)",
|
|
341
355
|
"files": [
|
|
342
356
|
"index.ts",
|
|
343
|
-
"tooltip.component.ts"
|
|
357
|
+
"tooltip.component.ts",
|
|
358
|
+
"tooltip.directive.ts"
|
|
344
359
|
],
|
|
345
360
|
"dependencies": [
|
|
346
361
|
"@radix-ng/primitives"
|
|
347
362
|
],
|
|
348
363
|
"peerDependencies": [],
|
|
349
364
|
"exports": [
|
|
350
|
-
"TooltipComponent"
|
|
351
|
-
|
|
365
|
+
"TooltipComponent",
|
|
366
|
+
"UiTooltipRootDirective",
|
|
367
|
+
"UiTooltipTriggerDirective",
|
|
368
|
+
"UiTooltipContentDirective"
|
|
369
|
+
],
|
|
370
|
+
"providers": {
|
|
371
|
+
"import": "import { provideRdxTooltipConfig } from '@radix-ng/primitives/tooltip2';",
|
|
372
|
+
"function": "...provideRdxTooltipConfig({})"
|
|
373
|
+
}
|
|
352
374
|
},
|
|
353
375
|
"line-chart": {
|
|
354
376
|
"name": "LineChart",
|
|
@@ -519,7 +541,7 @@
|
|
|
519
541
|
"name": "Dialog",
|
|
520
542
|
"selector": "g-dialog",
|
|
521
543
|
"type": "modal-overlay",
|
|
522
|
-
"description": "Modal dialog
|
|
544
|
+
"description": "Modal dialog using Radix template API (uses rdxDialogTrigger directive - see Angular docs for usage)",
|
|
523
545
|
"files": [
|
|
524
546
|
"dialog.component.ts",
|
|
525
547
|
"index.ts"
|
|
@@ -531,8 +553,18 @@
|
|
|
531
553
|
"lucide-angular"
|
|
532
554
|
],
|
|
533
555
|
"exports": [
|
|
534
|
-
"DialogComponent"
|
|
535
|
-
|
|
556
|
+
"DialogComponent",
|
|
557
|
+
"DialogTriggerComponent",
|
|
558
|
+
"DialogContentComponent",
|
|
559
|
+
"DialogTitleComponent",
|
|
560
|
+
"DialogDescriptionComponent",
|
|
561
|
+
"DialogHeaderComponent",
|
|
562
|
+
"DialogFooterComponent"
|
|
563
|
+
],
|
|
564
|
+
"providers": {
|
|
565
|
+
"import": "import { provideRdxDialogConfig } from '@radix-ng/primitives/dialog';",
|
|
566
|
+
"function": "...provideRdxDialogConfig()"
|
|
567
|
+
}
|
|
536
568
|
},
|
|
537
569
|
"alert-dialog": {
|
|
538
570
|
"name": "Alert Dialog",
|
|
@@ -787,6 +787,79 @@
|
|
|
787
787
|
],
|
|
788
788
|
"category": "form"
|
|
789
789
|
},
|
|
790
|
+
"date-picker": {
|
|
791
|
+
"name": "Date Picker",
|
|
792
|
+
"type": "form",
|
|
793
|
+
"description": "A date picker component with popover and calendar",
|
|
794
|
+
"dependencies": [
|
|
795
|
+
"date-fns"
|
|
796
|
+
],
|
|
797
|
+
"devDependencies": [],
|
|
798
|
+
"registryDependencies": [
|
|
799
|
+
"calendar",
|
|
800
|
+
"popover",
|
|
801
|
+
"button"
|
|
802
|
+
],
|
|
803
|
+
"files": [
|
|
804
|
+
"DatePicker.tsx",
|
|
805
|
+
"index.ts"
|
|
806
|
+
],
|
|
807
|
+
"category": "form"
|
|
808
|
+
},
|
|
809
|
+
"date-range-picker": {
|
|
810
|
+
"name": "Date Range Picker",
|
|
811
|
+
"type": "form",
|
|
812
|
+
"description": "A date range picker component with popover and calendar range",
|
|
813
|
+
"dependencies": [
|
|
814
|
+
"date-fns"
|
|
815
|
+
],
|
|
816
|
+
"devDependencies": [],
|
|
817
|
+
"registryDependencies": [
|
|
818
|
+
"calendar-range",
|
|
819
|
+
"popover",
|
|
820
|
+
"button"
|
|
821
|
+
],
|
|
822
|
+
"files": [
|
|
823
|
+
"DateRangePicker.tsx",
|
|
824
|
+
"index.ts"
|
|
825
|
+
],
|
|
826
|
+
"category": "form"
|
|
827
|
+
},
|
|
828
|
+
"time-picker": {
|
|
829
|
+
"name": "Time Picker",
|
|
830
|
+
"type": "form",
|
|
831
|
+
"description": "A time picker component with popover and select inputs for hours and minutes",
|
|
832
|
+
"dependencies": [],
|
|
833
|
+
"devDependencies": [],
|
|
834
|
+
"registryDependencies": [
|
|
835
|
+
"popover",
|
|
836
|
+
"button",
|
|
837
|
+
"select"
|
|
838
|
+
],
|
|
839
|
+
"files": [
|
|
840
|
+
"TimePicker.tsx",
|
|
841
|
+
"index.ts"
|
|
842
|
+
],
|
|
843
|
+
"category": "form"
|
|
844
|
+
},
|
|
845
|
+
"date-time-picker": {
|
|
846
|
+
"name": "Date Time Picker",
|
|
847
|
+
"type": "form",
|
|
848
|
+
"description": "A combined date and time picker component",
|
|
849
|
+
"dependencies": [
|
|
850
|
+
"date-fns"
|
|
851
|
+
],
|
|
852
|
+
"devDependencies": [],
|
|
853
|
+
"registryDependencies": [
|
|
854
|
+
"date-picker",
|
|
855
|
+
"time-picker"
|
|
856
|
+
],
|
|
857
|
+
"files": [
|
|
858
|
+
"DateTimePicker.tsx",
|
|
859
|
+
"index.ts"
|
|
860
|
+
],
|
|
861
|
+
"category": "form"
|
|
862
|
+
},
|
|
790
863
|
"command": {
|
|
791
864
|
"name": "Command",
|
|
792
865
|
"type": "navigation",
|
|
@@ -869,6 +942,10 @@
|
|
|
869
942
|
"form",
|
|
870
943
|
"calendar",
|
|
871
944
|
"calendar-range",
|
|
945
|
+
"date-picker",
|
|
946
|
+
"date-range-picker",
|
|
947
|
+
"time-picker",
|
|
948
|
+
"date-time-picker",
|
|
872
949
|
"tags-input"
|
|
873
950
|
]
|
|
874
951
|
},
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { readdirSync, existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { writeFile } from './files.js';
|
|
4
|
+
import { getFrameworkComponent } from './framework-registry.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate or update the components/ui/index.ts file with auto-generated providers
|
|
7
|
+
* This implements Solution 4 - dynamic provider management based on installed components
|
|
8
|
+
*
|
|
9
|
+
* @param componentsUiPath - Path to components/ui directory
|
|
10
|
+
* @param framework - Framework (should be 'angular')
|
|
11
|
+
* @returns Success boolean
|
|
12
|
+
*/ export function generateAngularProvidersIndex(componentsUiPath, framework = 'angular') {
|
|
13
|
+
try {
|
|
14
|
+
// Scan components/ui directory to find all installed components
|
|
15
|
+
if (!existsSync(componentsUiPath)) {
|
|
16
|
+
console.log(`Components directory does not exist: ${componentsUiPath}`);
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const installedComponents = readdirSync(componentsUiPath, {
|
|
20
|
+
withFileTypes: true
|
|
21
|
+
}).filter((dirent)=>dirent.isDirectory()).map((dirent)=>dirent.name).filter((name)=>!name.startsWith('.') && !name.startsWith('_'));
|
|
22
|
+
// For each installed component, check if it has provider configuration
|
|
23
|
+
const componentsWithProviders = [];
|
|
24
|
+
for (const componentKey of installedComponents){
|
|
25
|
+
const component = getFrameworkComponent(framework, componentKey);
|
|
26
|
+
if (component && component.providers) {
|
|
27
|
+
componentsWithProviders.push({
|
|
28
|
+
componentKey,
|
|
29
|
+
componentName: component.name,
|
|
30
|
+
provider: component.providers
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Generate the index.ts file content
|
|
35
|
+
const content = generateIndexContent(installedComponents, componentsWithProviders);
|
|
36
|
+
// Write the file
|
|
37
|
+
const indexPath = join(componentsUiPath, 'index.ts');
|
|
38
|
+
writeFile(indexPath, content);
|
|
39
|
+
return true;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('Failed to generate Angular providers index:', error);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate the content for the auto-generated index.ts file
|
|
47
|
+
*
|
|
48
|
+
* @param allComponents - All installed component keys
|
|
49
|
+
* @param componentsWithProviders - Components that have provider configuration
|
|
50
|
+
* @returns Generated file content
|
|
51
|
+
*/ function generateIndexContent(allComponents, componentsWithProviders) {
|
|
52
|
+
const lines = [];
|
|
53
|
+
// Header comment
|
|
54
|
+
lines.push('// Auto-generated by galaxy-design CLI - DO NOT EDIT MANUALLY');
|
|
55
|
+
lines.push('// This file is regenerated every time you add or remove components');
|
|
56
|
+
lines.push('');
|
|
57
|
+
// Export all components
|
|
58
|
+
lines.push('// Component exports');
|
|
59
|
+
for (const componentKey of allComponents.sort()){
|
|
60
|
+
lines.push(`export * from './${componentKey}';`);
|
|
61
|
+
}
|
|
62
|
+
// Only add providers section if there are components with providers
|
|
63
|
+
if (componentsWithProviders.length > 0) {
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push('// Provider imports for components that require Angular providers');
|
|
66
|
+
// Add import statements
|
|
67
|
+
const uniqueImports = new Set();
|
|
68
|
+
for (const { provider } of componentsWithProviders){
|
|
69
|
+
uniqueImports.add(provider.import);
|
|
70
|
+
}
|
|
71
|
+
for (const importStatement of Array.from(uniqueImports).sort()){
|
|
72
|
+
lines.push(importStatement);
|
|
73
|
+
}
|
|
74
|
+
lines.push('');
|
|
75
|
+
lines.push('/**');
|
|
76
|
+
lines.push(' * Provide all required Angular providers for Galaxy UI components');
|
|
77
|
+
lines.push(' * Add this to your app.config.ts providers array:');
|
|
78
|
+
lines.push(' * ');
|
|
79
|
+
lines.push(' * ```typescript');
|
|
80
|
+
lines.push(' * export const appConfig: ApplicationConfig = {');
|
|
81
|
+
lines.push(' * providers: [');
|
|
82
|
+
lines.push(' * provideGalaxyComponents(),');
|
|
83
|
+
lines.push(' * // ... other providers');
|
|
84
|
+
lines.push(' * ]');
|
|
85
|
+
lines.push(' * };');
|
|
86
|
+
lines.push(' * ```');
|
|
87
|
+
lines.push(' * ');
|
|
88
|
+
lines.push(` * This function provides configuration for: ${componentsWithProviders.map((c)=>c.componentName).join(', ')}`);
|
|
89
|
+
lines.push(' */');
|
|
90
|
+
lines.push('export function provideGalaxyComponents() {');
|
|
91
|
+
lines.push(' return [');
|
|
92
|
+
// Add provider function calls
|
|
93
|
+
for (const { provider } of componentsWithProviders){
|
|
94
|
+
lines.push(` ${provider.function},`);
|
|
95
|
+
}
|
|
96
|
+
lines.push(' ];');
|
|
97
|
+
lines.push('}');
|
|
98
|
+
} else {
|
|
99
|
+
lines.push('');
|
|
100
|
+
lines.push('// No components requiring Angular providers are currently installed');
|
|
101
|
+
}
|
|
102
|
+
lines.push('');
|
|
103
|
+
return lines.join('\n');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a component has provider configuration
|
|
107
|
+
*
|
|
108
|
+
* @param componentKey - Component key
|
|
109
|
+
* @param framework - Framework
|
|
110
|
+
* @returns True if component has providers
|
|
111
|
+
*/ export function componentHasProviders(componentKey, framework = 'angular') {
|
|
112
|
+
const component = getFrameworkComponent(framework, componentKey);
|
|
113
|
+
return !!(component && component.providers);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=angular-provider-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/angular-provider-manager.ts"],"sourcesContent":["import { readdirSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { writeFile } from './files.js';\nimport { getFrameworkComponent } from './framework-registry.js';\n\n/**\n * Provider configuration from registry\n */\ninterface ProviderConfig {\n import: string;\n function: string;\n}\n\n/**\n * Component with provider information\n */\ninterface ComponentWithProvider {\n componentKey: string;\n componentName: string;\n provider: ProviderConfig;\n}\n\n/**\n * Generate or update the components/ui/index.ts file with auto-generated providers\n * This implements Solution 4 - dynamic provider management based on installed components\n *\n * @param componentsUiPath - Path to components/ui directory\n * @param framework - Framework (should be 'angular')\n * @returns Success boolean\n */\nexport function generateAngularProvidersIndex(\n componentsUiPath: string,\n framework: 'angular' = 'angular'\n): boolean {\n try {\n // Scan components/ui directory to find all installed components\n if (!existsSync(componentsUiPath)) {\n console.log(`Components directory does not exist: ${componentsUiPath}`);\n return false;\n }\n\n const installedComponents = readdirSync(componentsUiPath, { withFileTypes: true })\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name)\n .filter((name) => !name.startsWith('.') && !name.startsWith('_'));\n\n // For each installed component, check if it has provider configuration\n const componentsWithProviders: ComponentWithProvider[] = [];\n\n for (const componentKey of installedComponents) {\n const component = getFrameworkComponent(framework, componentKey);\n\n if (component && component.providers) {\n componentsWithProviders.push({\n componentKey,\n componentName: component.name,\n provider: component.providers,\n });\n }\n }\n\n // Generate the index.ts file content\n const content = generateIndexContent(installedComponents, componentsWithProviders);\n\n // Write the file\n const indexPath = join(componentsUiPath, 'index.ts');\n writeFile(indexPath, content);\n\n return true;\n } catch (error) {\n console.error('Failed to generate Angular providers index:', error);\n return false;\n }\n}\n\n/**\n * Generate the content for the auto-generated index.ts file\n *\n * @param allComponents - All installed component keys\n * @param componentsWithProviders - Components that have provider configuration\n * @returns Generated file content\n */\nfunction generateIndexContent(\n allComponents: string[],\n componentsWithProviders: ComponentWithProvider[]\n): string {\n const lines: string[] = [];\n\n // Header comment\n lines.push('// Auto-generated by galaxy-design CLI - DO NOT EDIT MANUALLY');\n lines.push('// This file is regenerated every time you add or remove components');\n lines.push('');\n\n // Export all components\n lines.push('// Component exports');\n for (const componentKey of allComponents.sort()) {\n lines.push(`export * from './${componentKey}';`);\n }\n\n // Only add providers section if there are components with providers\n if (componentsWithProviders.length > 0) {\n lines.push('');\n lines.push('// Provider imports for components that require Angular providers');\n\n // Add import statements\n const uniqueImports = new Set<string>();\n for (const { provider } of componentsWithProviders) {\n uniqueImports.add(provider.import);\n }\n\n for (const importStatement of Array.from(uniqueImports).sort()) {\n lines.push(importStatement);\n }\n\n lines.push('');\n lines.push('/**');\n lines.push(' * Provide all required Angular providers for Galaxy UI components');\n lines.push(' * Add this to your app.config.ts providers array:');\n lines.push(' * ');\n lines.push(' * ```typescript');\n lines.push(' * export const appConfig: ApplicationConfig = {');\n lines.push(' * providers: [');\n lines.push(' * provideGalaxyComponents(),');\n lines.push(' * // ... other providers');\n lines.push(' * ]');\n lines.push(' * };');\n lines.push(' * ```');\n lines.push(' * ');\n lines.push(\n ` * This function provides configuration for: ${componentsWithProviders.map((c) => c.componentName).join(', ')}`\n );\n lines.push(' */');\n lines.push('export function provideGalaxyComponents() {');\n lines.push(' return [');\n\n // Add provider function calls\n for (const { provider } of componentsWithProviders) {\n lines.push(` ${provider.function},`);\n }\n\n lines.push(' ];');\n lines.push('}');\n } else {\n lines.push('');\n lines.push('// No components requiring Angular providers are currently installed');\n }\n\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Check if a component has provider configuration\n *\n * @param componentKey - Component key\n * @param framework - Framework\n * @returns True if component has providers\n */\nexport function componentHasProviders(\n componentKey: string,\n framework: 'angular' = 'angular'\n): boolean {\n const component = getFrameworkComponent(framework, componentKey);\n return !!(component && component.providers);\n}\n"],"names":["readdirSync","existsSync","join","writeFile","getFrameworkComponent","generateAngularProvidersIndex","componentsUiPath","framework","console","log","installedComponents","withFileTypes","filter","dirent","isDirectory","map","name","startsWith","componentsWithProviders","componentKey","component","providers","push","componentName","provider","content","generateIndexContent","indexPath","error","allComponents","lines","sort","length","uniqueImports","Set","add","import","importStatement","Array","from","c","function","componentHasProviders"],"mappings":"AAAA,SAASA,WAAW,EAAEC,UAAU,QAAQ,KAAK;AAC7C,SAASC,IAAI,QAAQ,OAAO;AAC5B,SAASC,SAAS,QAAQ,aAAa;AACvC,SAASC,qBAAqB,QAAQ,0BAA0B;AAmBhE;;;;;;;CAOC,GACD,OAAO,SAASC,8BACdC,gBAAwB,EACxBC,YAAuB,SAAS;IAEhC,IAAI;QACF,gEAAgE;QAChE,IAAI,CAACN,WAAWK,mBAAmB;YACjCE,QAAQC,GAAG,CAAC,CAAC,qCAAqC,EAAEH,kBAAkB;YACtE,OAAO;QACT;QAEA,MAAMI,sBAAsBV,YAAYM,kBAAkB;YAAEK,eAAe;QAAK,GAC7EC,MAAM,CAAC,CAACC,SAAWA,OAAOC,WAAW,IACrCC,GAAG,CAAC,CAACF,SAAWA,OAAOG,IAAI,EAC3BJ,MAAM,CAAC,CAACI,OAAS,CAACA,KAAKC,UAAU,CAAC,QAAQ,CAACD,KAAKC,UAAU,CAAC;QAE9D,uEAAuE;QACvE,MAAMC,0BAAmD,EAAE;QAE3D,KAAK,MAAMC,gBAAgBT,oBAAqB;YAC9C,MAAMU,YAAYhB,sBAAsBG,WAAWY;YAEnD,IAAIC,aAAaA,UAAUC,SAAS,EAAE;gBACpCH,wBAAwBI,IAAI,CAAC;oBAC3BH;oBACAI,eAAeH,UAAUJ,IAAI;oBAC7BQ,UAAUJ,UAAUC,SAAS;gBAC/B;YACF;QACF;QAEA,qCAAqC;QACrC,MAAMI,UAAUC,qBAAqBhB,qBAAqBQ;QAE1D,iBAAiB;QACjB,MAAMS,YAAYzB,KAAKI,kBAAkB;QACzCH,UAAUwB,WAAWF;QAErB,OAAO;IACT,EAAE,OAAOG,OAAO;QACdpB,QAAQoB,KAAK,CAAC,+CAA+CA;QAC7D,OAAO;IACT;AACF;AAEA;;;;;;CAMC,GACD,SAASF,qBACPG,aAAuB,EACvBX,uBAAgD;IAEhD,MAAMY,QAAkB,EAAE;IAE1B,iBAAiB;IACjBA,MAAMR,IAAI,CAAC;IACXQ,MAAMR,IAAI,CAAC;IACXQ,MAAMR,IAAI,CAAC;IAEX,wBAAwB;IACxBQ,MAAMR,IAAI,CAAC;IACX,KAAK,MAAMH,gBAAgBU,cAAcE,IAAI,GAAI;QAC/CD,MAAMR,IAAI,CAAC,CAAC,iBAAiB,EAAEH,aAAa,EAAE,CAAC;IACjD;IAEA,oEAAoE;IACpE,IAAID,wBAAwBc,MAAM,GAAG,GAAG;QACtCF,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QAEX,wBAAwB;QACxB,MAAMW,gBAAgB,IAAIC;QAC1B,KAAK,MAAM,EAAEV,QAAQ,EAAE,IAAIN,wBAAyB;YAClDe,cAAcE,GAAG,CAACX,SAASY,MAAM;QACnC;QAEA,KAAK,MAAMC,mBAAmBC,MAAMC,IAAI,CAACN,eAAeF,IAAI,GAAI;YAC9DD,MAAMR,IAAI,CAACe;QACb;QAEAP,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CACR,CAAC,6CAA6C,EAAEJ,wBAAwBH,GAAG,CAAC,CAACyB,IAAMA,EAAEjB,aAAa,EAAErB,IAAI,CAAC,OAAO;QAElH4B,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;QAEX,8BAA8B;QAC9B,KAAK,MAAM,EAAEE,QAAQ,EAAE,IAAIN,wBAAyB;YAClDY,MAAMR,IAAI,CAAC,CAAC,IAAI,EAAEE,SAASiB,QAAQ,CAAC,CAAC,CAAC;QACxC;QAEAX,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;IACb,OAAO;QACLQ,MAAMR,IAAI,CAAC;QACXQ,MAAMR,IAAI,CAAC;IACb;IAEAQ,MAAMR,IAAI,CAAC;IAEX,OAAOQ,MAAM5B,IAAI,CAAC;AACpB;AAEA;;;;;;CAMC,GACD,OAAO,SAASwC,sBACdvB,YAAoB,EACpBZ,YAAuB,SAAS;IAEhC,MAAMa,YAAYhB,sBAAsBG,WAAWY;IACnD,OAAO,CAAC,CAAEC,CAAAA,aAAaA,UAAUC,SAAS,AAAD;AAC3C"}
|
|
@@ -107,6 +107,32 @@ import { readFileSync } from 'fs';
|
|
|
107
107
|
notes
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Transform import paths to match user's project structure
|
|
112
|
+
*
|
|
113
|
+
* Transforms @/components/xxx to @/components/ui/xxx
|
|
114
|
+
*/ function transformImportPaths(content) {
|
|
115
|
+
const notes = [];
|
|
116
|
+
let modified = false;
|
|
117
|
+
let transformedContent = content;
|
|
118
|
+
// Transform @/components/ imports to @/components/ui/
|
|
119
|
+
// Match patterns like: from '@/components/calendar'
|
|
120
|
+
const importPattern = /from\s+['"]@\/components\/([^'"]+)['"]/g;
|
|
121
|
+
transformedContent = content.replace(importPattern, (match, componentPath)=>{
|
|
122
|
+
// Skip if already has /ui/ in path
|
|
123
|
+
if (componentPath.includes('ui/')) {
|
|
124
|
+
return match;
|
|
125
|
+
}
|
|
126
|
+
modified = true;
|
|
127
|
+
notes.push(`Transformed import path: @/components/${componentPath} -> @/components/ui/${componentPath}`);
|
|
128
|
+
return `from '@/components/ui/${componentPath}'`;
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
content: transformedContent,
|
|
132
|
+
modified,
|
|
133
|
+
notes
|
|
134
|
+
};
|
|
135
|
+
}
|
|
110
136
|
/**
|
|
111
137
|
* Transform component file based on platform
|
|
112
138
|
*
|
|
@@ -115,26 +141,45 @@ import { readFileSync } from 'fs';
|
|
|
115
141
|
* @returns Transform result
|
|
116
142
|
*/ export function transformComponent(content, options) {
|
|
117
143
|
const { platform, componentName } = options;
|
|
144
|
+
// First, apply import path transformations for all platforms
|
|
145
|
+
const importTransform = transformImportPaths(content);
|
|
146
|
+
let transformedContent = importTransform.content;
|
|
147
|
+
let notes = [
|
|
148
|
+
...importTransform.notes
|
|
149
|
+
];
|
|
150
|
+
let modified = importTransform.modified;
|
|
151
|
+
// Then apply platform-specific transformations
|
|
152
|
+
let platformResult;
|
|
118
153
|
switch(platform){
|
|
119
154
|
case 'nextjs':
|
|
120
|
-
|
|
155
|
+
platformResult = transformNextjsComponent(transformedContent, componentName);
|
|
156
|
+
break;
|
|
121
157
|
case 'nuxtjs':
|
|
122
|
-
|
|
123
|
-
|
|
158
|
+
platformResult = transformNuxtjsComponent(transformedContent, componentName);
|
|
159
|
+
break;
|
|
160
|
+
// Other platforms don't need additional transformation
|
|
124
161
|
case 'react':
|
|
125
162
|
case 'vue':
|
|
126
163
|
case 'angular':
|
|
127
164
|
case 'react-native':
|
|
128
165
|
case 'flutter':
|
|
129
166
|
default:
|
|
130
|
-
|
|
131
|
-
content,
|
|
167
|
+
platformResult = {
|
|
168
|
+
content: transformedContent,
|
|
132
169
|
modified: false,
|
|
133
|
-
notes: [
|
|
170
|
+
notes: modified ? [] : [
|
|
134
171
|
'No transformation needed for this platform'
|
|
135
172
|
]
|
|
136
173
|
};
|
|
137
174
|
}
|
|
175
|
+
return {
|
|
176
|
+
content: platformResult.content,
|
|
177
|
+
modified: modified || platformResult.modified,
|
|
178
|
+
notes: [
|
|
179
|
+
...notes,
|
|
180
|
+
...platformResult.notes
|
|
181
|
+
]
|
|
182
|
+
};
|
|
138
183
|
}
|
|
139
184
|
/**
|
|
140
185
|
* Transform component file from file path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/component-transformer.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport type { Platform } from './platform-detector';\n\n/**\n * Transform options for component files\n */\nexport interface TransformOptions {\n\t/** Target platform */\n\tplatform: Platform;\n\t/** Component name */\n\tcomponentName: string;\n\t/** File path */\n\tfilePath: string;\n}\n\n/**\n * Transform result\n */\nexport interface TransformResult {\n\t/** Transformed content */\n\tcontent: string;\n\t/** Whether content was modified */\n\tmodified: boolean;\n\t/** Transformation notes */\n\tnotes: string[];\n}\n\n/**\n * Check if a React/Next.js component needs 'use client' directive\n *\n * Components need 'use client' if they use:\n * - React hooks (useState, useEffect, etc.)\n * - Event handlers (onClick, onChange, etc.)\n * - Browser APIs (window, document, etc.)\n * - Client-side libraries\n */\nfunction needsUseClient(content: string): boolean {\n\tconst clientIndicators = [\n\t\t// React hooks\n\t\t/\\buse[A-Z]\\w+\\s*\\(/,\n\t\t/useState|useEffect|useContext|useReducer|useCallback|useMemo|useRef/,\n\n\t\t// Event handlers\n\t\t/\\bon[A-Z]\\w+\\s*=/,\n\t\t/onClick|onChange|onSubmit|onFocus|onBlur|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave/,\n\n\t\t// Browser APIs\n\t\t/\\bwindow\\./,\n\t\t/\\bdocument\\./,\n\t\t/\\bnavigator\\./,\n\t\t/\\blocalStorage\\./,\n\t\t/\\bsessionStorage\\./,\n\n\t\t// Client-side only features\n\t\t/addEventListener/,\n\t\t/removeEventListener/,\n\t\t/createPortal/,\n\t];\n\n\treturn clientIndicators.some(indicator => indicator.test(content));\n}\n\n/**\n * Check if file already has 'use client' directive\n */\nfunction hasUseClientDirective(content: string): boolean {\n\tconst lines = content.split('\\n');\n\tconst firstNonEmptyLine = lines.find(line => line.trim() !== '');\n\treturn firstNonEmptyLine?.trim().startsWith(\"'use client'\") ||\n\t firstNonEmptyLine?.trim().startsWith('\"use client\"') || false;\n}\n\n/**\n * Add 'use client' directive to Next.js component\n */\nfunction addUseClientDirective(content: string): string {\n\t// Skip if already has the directive\n\tif (hasUseClientDirective(content)) {\n\t\treturn content;\n\t}\n\n\t// Find the first import or code line\n\tconst lines = content.split('\\n');\n\tlet insertIndex = 0;\n\n\t// Skip shebang and comments at the top\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i].trim();\n\t\tif (line === '' || line.startsWith('//') || line.startsWith('/*')) {\n\t\t\tinsertIndex = i + 1;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Insert 'use client' directive\n\tlines.splice(insertIndex, 0, \"'use client'\", '');\n\treturn lines.join('\\n');\n}\n\n/**\n * Transform component for Next.js\n *\n * Adds 'use client' directive if component uses client-side features\n */\nfunction transformNextjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\tlet modified = false;\n\tlet transformedContent = content;\n\n\t// Check if component needs 'use client'\n\tif (needsUseClient(content) && !hasUseClientDirective(content)) {\n\t\ttransformedContent = addUseClientDirective(content);\n\t\tmodified = true;\n\t\tnotes.push(`Added 'use client' directive (component uses client-side features)`);\n\t} else if (hasUseClientDirective(content)) {\n\t\tnotes.push(`Component already has 'use client' directive`);\n\t} else {\n\t\tnotes.push(`Component appears to be server-safe (no 'use client' needed)`);\n\t}\n\n\treturn {\n\t\tcontent: transformedContent,\n\t\tmodified,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component for Nuxt.js\n *\n * Currently no transformations needed, but placeholder for future enhancements\n */\nfunction transformNuxtjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\n\t// Check for Nuxt-specific patterns\n\tconst hasNuxtImports = /from ['\"]#app['\"]/.test(content);\n\tconst hasAutoImports = /\\b(navigateTo|useFetch|useAsyncData|useState)\\b/.test(content);\n\n\tif (hasNuxtImports) {\n\t\tnotes.push('Component uses Nuxt 3 auto-imports (#app)');\n\t}\n\tif (hasAutoImports) {\n\t\tnotes.push('Component uses Nuxt 3 composables (auto-imported)');\n\t}\n\tif (!hasNuxtImports && !hasAutoImports) {\n\t\tnotes.push('Component appears to be standard Vue 3 (works in Nuxt)');\n\t}\n\n\treturn {\n\t\tcontent,\n\t\tmodified: false,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component file based on platform\n *\n * @param content - File content\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponent(content: string, options: TransformOptions): TransformResult {\n\tconst { platform, componentName } = options;\n\n\tswitch (platform) {\n\t\tcase 'nextjs':\n\t\t\treturn transformNextjsComponent(content, componentName);\n\n\t\tcase 'nuxtjs':\n\t\t\treturn transformNuxtjsComponent(content, componentName);\n\n\t\t// Other platforms don't need transformation\n\t\tcase 'react':\n\t\tcase 'vue':\n\t\tcase 'angular':\n\t\tcase 'react-native':\n\t\tcase 'flutter':\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tcontent,\n\t\t\t\tmodified: false,\n\t\t\t\tnotes: ['No transformation needed for this platform'],\n\t\t\t};\n\t}\n}\n\n/**\n * Transform component file from file path\n *\n * @param filePath - Path to component file\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponentFile(filePath: string, options: Omit<TransformOptions, 'filePath'>): TransformResult {\n\tconst content = readFileSync(filePath, 'utf-8');\n\treturn transformComponent(content, { ...options, filePath });\n}\n\n/**\n * Batch transform multiple files\n *\n * @param files - Array of file paths\n * @param options - Transform options (without filePath)\n * @returns Array of transform results\n */\nexport function transformComponentFiles(\n\tfiles: string[],\n\toptions: Omit<TransformOptions, 'filePath' | 'componentName'>\n): Map<string, TransformResult> {\n\tconst results = new Map<string, TransformResult>();\n\n\tfor (const filePath of files) {\n\t\tconst componentName = options.componentName || extractComponentName(filePath);\n\t\tconst result = transformComponentFile(filePath, { ...options, componentName });\n\t\tresults.set(filePath, result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Extract component name from file path\n */\nfunction extractComponentName(filePath: string): string {\n\tconst fileName = filePath.split('/').pop() || '';\n\treturn fileName.replace(/\\.(tsx?|vue|js|jsx)$/, '');\n}\n"],"names":["readFileSync","needsUseClient","content","clientIndicators","some","indicator","test","hasUseClientDirective","lines","split","firstNonEmptyLine","find","line","trim","startsWith","addUseClientDirective","insertIndex","i","length","splice","join","transformNextjsComponent","componentName","notes","modified","transformedContent","push","transformNuxtjsComponent","hasNuxtImports","hasAutoImports","transformComponent","options","platform","transformComponentFile","filePath","transformComponentFiles","files","results","Map","extractComponentName","result","set","fileName","pop","replace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/component-transformer.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport type { Platform } from './platform-detector';\n\n/**\n * Transform options for component files\n */\nexport interface TransformOptions {\n\t/** Target platform */\n\tplatform: Platform;\n\t/** Component name */\n\tcomponentName: string;\n\t/** File path */\n\tfilePath: string;\n}\n\n/**\n * Transform result\n */\nexport interface TransformResult {\n\t/** Transformed content */\n\tcontent: string;\n\t/** Whether content was modified */\n\tmodified: boolean;\n\t/** Transformation notes */\n\tnotes: string[];\n}\n\n/**\n * Check if a React/Next.js component needs 'use client' directive\n *\n * Components need 'use client' if they use:\n * - React hooks (useState, useEffect, etc.)\n * - Event handlers (onClick, onChange, etc.)\n * - Browser APIs (window, document, etc.)\n * - Client-side libraries\n */\nfunction needsUseClient(content: string): boolean {\n\tconst clientIndicators = [\n\t\t// React hooks\n\t\t/\\buse[A-Z]\\w+\\s*\\(/,\n\t\t/useState|useEffect|useContext|useReducer|useCallback|useMemo|useRef/,\n\n\t\t// Event handlers\n\t\t/\\bon[A-Z]\\w+\\s*=/,\n\t\t/onClick|onChange|onSubmit|onFocus|onBlur|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave/,\n\n\t\t// Browser APIs\n\t\t/\\bwindow\\./,\n\t\t/\\bdocument\\./,\n\t\t/\\bnavigator\\./,\n\t\t/\\blocalStorage\\./,\n\t\t/\\bsessionStorage\\./,\n\n\t\t// Client-side only features\n\t\t/addEventListener/,\n\t\t/removeEventListener/,\n\t\t/createPortal/,\n\t];\n\n\treturn clientIndicators.some(indicator => indicator.test(content));\n}\n\n/**\n * Check if file already has 'use client' directive\n */\nfunction hasUseClientDirective(content: string): boolean {\n\tconst lines = content.split('\\n');\n\tconst firstNonEmptyLine = lines.find(line => line.trim() !== '');\n\treturn firstNonEmptyLine?.trim().startsWith(\"'use client'\") ||\n\t firstNonEmptyLine?.trim().startsWith('\"use client\"') || false;\n}\n\n/**\n * Add 'use client' directive to Next.js component\n */\nfunction addUseClientDirective(content: string): string {\n\t// Skip if already has the directive\n\tif (hasUseClientDirective(content)) {\n\t\treturn content;\n\t}\n\n\t// Find the first import or code line\n\tconst lines = content.split('\\n');\n\tlet insertIndex = 0;\n\n\t// Skip shebang and comments at the top\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i].trim();\n\t\tif (line === '' || line.startsWith('//') || line.startsWith('/*')) {\n\t\t\tinsertIndex = i + 1;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Insert 'use client' directive\n\tlines.splice(insertIndex, 0, \"'use client'\", '');\n\treturn lines.join('\\n');\n}\n\n/**\n * Transform component for Next.js\n *\n * Adds 'use client' directive if component uses client-side features\n */\nfunction transformNextjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\tlet modified = false;\n\tlet transformedContent = content;\n\n\t// Check if component needs 'use client'\n\tif (needsUseClient(content) && !hasUseClientDirective(content)) {\n\t\ttransformedContent = addUseClientDirective(content);\n\t\tmodified = true;\n\t\tnotes.push(`Added 'use client' directive (component uses client-side features)`);\n\t} else if (hasUseClientDirective(content)) {\n\t\tnotes.push(`Component already has 'use client' directive`);\n\t} else {\n\t\tnotes.push(`Component appears to be server-safe (no 'use client' needed)`);\n\t}\n\n\treturn {\n\t\tcontent: transformedContent,\n\t\tmodified,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component for Nuxt.js\n *\n * Currently no transformations needed, but placeholder for future enhancements\n */\nfunction transformNuxtjsComponent(content: string, componentName: string): TransformResult {\n\tconst notes: string[] = [];\n\n\t// Check for Nuxt-specific patterns\n\tconst hasNuxtImports = /from ['\"]#app['\"]/.test(content);\n\tconst hasAutoImports = /\\b(navigateTo|useFetch|useAsyncData|useState)\\b/.test(content);\n\n\tif (hasNuxtImports) {\n\t\tnotes.push('Component uses Nuxt 3 auto-imports (#app)');\n\t}\n\tif (hasAutoImports) {\n\t\tnotes.push('Component uses Nuxt 3 composables (auto-imported)');\n\t}\n\tif (!hasNuxtImports && !hasAutoImports) {\n\t\tnotes.push('Component appears to be standard Vue 3 (works in Nuxt)');\n\t}\n\n\treturn {\n\t\tcontent,\n\t\tmodified: false,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform import paths to match user's project structure\n *\n * Transforms @/components/xxx to @/components/ui/xxx\n */\nfunction transformImportPaths(content: string): TransformResult {\n\tconst notes: string[] = [];\n\tlet modified = false;\n\tlet transformedContent = content;\n\n\t// Transform @/components/ imports to @/components/ui/\n\t// Match patterns like: from '@/components/calendar'\n\tconst importPattern = /from\\s+['\"]@\\/components\\/([^'\"]+)['\"]/g;\n\n\ttransformedContent = content.replace(importPattern, (match, componentPath) => {\n\t\t// Skip if already has /ui/ in path\n\t\tif (componentPath.includes('ui/')) {\n\t\t\treturn match;\n\t\t}\n\t\tmodified = true;\n\t\tnotes.push(`Transformed import path: @/components/${componentPath} -> @/components/ui/${componentPath}`);\n\t\treturn `from '@/components/ui/${componentPath}'`;\n\t});\n\n\treturn {\n\t\tcontent: transformedContent,\n\t\tmodified,\n\t\tnotes,\n\t};\n}\n\n/**\n * Transform component file based on platform\n *\n * @param content - File content\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponent(content: string, options: TransformOptions): TransformResult {\n\tconst { platform, componentName } = options;\n\n\t// First, apply import path transformations for all platforms\n\tconst importTransform = transformImportPaths(content);\n\tlet transformedContent = importTransform.content;\n\tlet notes = [...importTransform.notes];\n\tlet modified = importTransform.modified;\n\n\t// Then apply platform-specific transformations\n\tlet platformResult: TransformResult;\n\tswitch (platform) {\n\t\tcase 'nextjs':\n\t\t\tplatformResult = transformNextjsComponent(transformedContent, componentName);\n\t\t\tbreak;\n\n\t\tcase 'nuxtjs':\n\t\t\tplatformResult = transformNuxtjsComponent(transformedContent, componentName);\n\t\t\tbreak;\n\n\t\t// Other platforms don't need additional transformation\n\t\tcase 'react':\n\t\tcase 'vue':\n\t\tcase 'angular':\n\t\tcase 'react-native':\n\t\tcase 'flutter':\n\t\tdefault:\n\t\t\tplatformResult = {\n\t\t\t\tcontent: transformedContent,\n\t\t\t\tmodified: false,\n\t\t\t\tnotes: modified ? [] : ['No transformation needed for this platform'],\n\t\t\t};\n\t}\n\n\treturn {\n\t\tcontent: platformResult.content,\n\t\tmodified: modified || platformResult.modified,\n\t\tnotes: [...notes, ...platformResult.notes],\n\t};\n}\n\n/**\n * Transform component file from file path\n *\n * @param filePath - Path to component file\n * @param options - Transform options\n * @returns Transform result\n */\nexport function transformComponentFile(filePath: string, options: Omit<TransformOptions, 'filePath'>): TransformResult {\n\tconst content = readFileSync(filePath, 'utf-8');\n\treturn transformComponent(content, { ...options, filePath });\n}\n\n/**\n * Batch transform multiple files\n *\n * @param files - Array of file paths\n * @param options - Transform options (without filePath)\n * @returns Array of transform results\n */\nexport function transformComponentFiles(\n\tfiles: string[],\n\toptions: Omit<TransformOptions, 'filePath' | 'componentName'>\n): Map<string, TransformResult> {\n\tconst results = new Map<string, TransformResult>();\n\n\tfor (const filePath of files) {\n\t\tconst componentName = options.componentName || extractComponentName(filePath);\n\t\tconst result = transformComponentFile(filePath, { ...options, componentName });\n\t\tresults.set(filePath, result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Extract component name from file path\n */\nfunction extractComponentName(filePath: string): string {\n\tconst fileName = filePath.split('/').pop() || '';\n\treturn fileName.replace(/\\.(tsx?|vue|js|jsx)$/, '');\n}\n"],"names":["readFileSync","needsUseClient","content","clientIndicators","some","indicator","test","hasUseClientDirective","lines","split","firstNonEmptyLine","find","line","trim","startsWith","addUseClientDirective","insertIndex","i","length","splice","join","transformNextjsComponent","componentName","notes","modified","transformedContent","push","transformNuxtjsComponent","hasNuxtImports","hasAutoImports","transformImportPaths","importPattern","replace","match","componentPath","includes","transformComponent","options","platform","importTransform","platformResult","transformComponentFile","filePath","transformComponentFiles","files","results","Map","extractComponentName","result","set","fileName","pop"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "galaxy-design",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.66",
|
|
4
4
|
"description": "CLI tool for adding Galaxy UI components to your Vue, React, Angular, Next.js, Nuxt.js, React Native, or Flutter project",
|
|
5
5
|
"author": "Bùi Trọng Hiếu (kevinbui) <kevinbui210191@gmail.com>",
|
|
6
6
|
"license": "MIT",
|