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.
@@ -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
- const content = await fetchFileFromGitHub(githubPath);
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
- const content = await fetchFileFromGitHub(githubPath);
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 the components in your Angular module or component'));
273
- console.log(chalk.gray(' 2. Use them in your templates'));
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(' 3. Enjoy building with Galaxy UI! 🚀\n'));
313
+ console.log(chalk.gray(' 4. Enjoy building with Galaxy UI! 🚀\n'));
277
314
  }
278
315
  }
279
316
 
@@ -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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"}
@@ -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' && framework !== 'angular') {
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
- export default {
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 (shadcn style)",
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 component",
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":"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"}
@@ -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
- return transformNextjsComponent(content, componentName);
155
+ platformResult = transformNextjsComponent(transformedContent, componentName);
156
+ break;
121
157
  case 'nuxtjs':
122
- return transformNuxtjsComponent(content, componentName);
123
- // Other platforms don't need transformation
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
- return {
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.64",
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",