Contributing
Thank you for your interest in contributing to Galaxy UI! This guide will help you get started.
Getting Started
Prerequisites
- Node.js: 18.0.0 or higher
- Package Manager: npm, pnpm, yarn, or bun
- Git: For version control
Fork and Clone
Fork the repository
Visit github.com/galaxy-nebula/galaxy-design and click "Fork"
Clone your fork
bashgit clone https://github.com/YOUR_USERNAME/galaxy-design.git cd galaxy-designAdd upstream remote
bashgit remote add upstream https://github.com/galaxy-nebula/galaxy-design.git
Install Dependencies
# Install dependencies
npm install
# or
bun installProject Structure
galaxy-design/
├── packages/
│ ├── cli/ # CLI tool source
│ │ ├── src/
│ │ │ ├── commands/ # CLI commands (init, add)
│ │ │ ├── utils/ # Utility functions
│ │ │ └── registries/ # Component registries
│ │ └── package.json
│ │
│ ├── react/ # React components
│ │ └── src/components/
│ │
│ ├── vue/ # Vue components
│ │ └── src/components/
│ │
│ └── angular/ # Angular components
│ └── src/components/
│
├── docs/ # VitePress documentation
│ ├── .vitepress/
│ ├── guide/
│ ├── components/
│ └── vi/ # Vietnamese docs
│
└── examples/ # Example projects
├── react-example/
├── vue-example/
└── angular-example/Development Workflow
1. Create a Branch
# Update main branch
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feat/your-feature-name
# or for bug fixes
git checkout -b fix/bug-description2. Make Changes
Follow our coding standards and commit conventions.
3. Test Changes
# Build CLI
npm run build
# Test CLI locally
cd examples/react-example
node ../../packages/cli/dist/bin.js add button
# Run dev server
npm run dev4. Commit Changes
git add .
git commit -m "feat: add new button variant"5. Push and Create PR
git push origin feat/your-feature-nameThen create a Pull Request on GitHub.
Contribution Types
🐛 Bug Fixes
- Search existing issues to avoid duplicates
- Create an issue describing the bug
- Fix the bug and add tests
- Submit PR referencing the issue
✨ New Features
- Open a discussion for major features
- Get approval before starting work
- Implement feature with tests and docs
- Submit PR with detailed description
📝 Documentation
- Identify gaps in documentation
- Write clear, concise docs
- Add code examples
- Submit PR
🎨 New Components
Adding a new component requires work across multiple packages:
React Component
# Create component directory
mkdir -p packages/react/src/components/new-component
# Create component files
touch packages/react/src/components/new-component/NewComponent.tsx
touch packages/react/src/components/new-component/index.tsNewComponent.tsx:
import * as React from 'react'
import { cn } from '@/lib/utils'
export interface NewComponentProps extends React.HTMLAttributes<HTMLDivElement> {
// Component-specific props
}
const NewComponent = React.forwardRef<HTMLDivElement, NewComponentProps>(
({ className, ...props }, ref) => {
return (
<div
ref={ref}
className={cn('new-component-base-classes', className)}
{...props}
/>
)
}
)
NewComponent.displayName = 'NewComponent'
export { NewComponent }index.ts:
export * from './NewComponent'Vue Component
mkdir -p packages/vue/src/components/new-component
touch packages/vue/src/components/new-component/NewComponent.vue
touch packages/vue/src/components/new-component/index.tsNewComponent.vue:
<script setup lang="ts">
import { cn } from '@/lib/utils'
import { computed } from 'vue'
interface Props {
class?: string
}
const props = defineProps<Props>()
const className = computed(() => cn('new-component-base-classes', props.class))
</script>
<template>
<div :class="className">
<slot />
</div>
</template>Angular Component
mkdir -p packages/angular/src/components/new-component
touch packages/angular/src/components/new-component/new-component.component.ts
touch packages/angular/src/components/new-component/index.tsnew-component.component.ts:
import { Component, Input } from '@angular/core'
import { cn } from '@/lib/utils'
@Component({
selector: 'ui-new-component',
standalone: true,
template: `
<div [class]="className">
<ng-content />
</div>
`
})
export class NewComponentComponent {
@Input() class?: string
get className() {
return cn('new-component-base-classes', this.class)
}
}Update Registries
Add component to all three registry files:
packages/cli/src/registries/registry-react.json:
{
"new-component": {
"name": "NewComponent",
"type": "other",
"description": "Description of new component",
"dependencies": [],
"devDependencies": [],
"registryDependencies": [],
"files": ["NewComponent.tsx", "index.ts"],
"category": "other"
}
}Repeat for registry-vue.json and registry-angular.json.
Create Documentation
touch docs/components/new-component.mdnew-component.md:
# New Component
Description of the component and its purpose.
## Import
::: code-group
```tsx [React]
import { NewComponent } from '@/components/ui/new-component'
```
```vue [Vue]
import { NewComponent } from '@/components/ui/new-component'
```
```typescript [Angular]
import { NewComponentComponent } from '@/components/ui/new-component'
```
:::
## Usage
::: code-group
```tsx [React]
export default function Example() {
return <NewComponent>Content</NewComponent>
}
```
```vue [Vue]
<template>
<NewComponent>Content</NewComponent>
</template>
```
```typescript [Angular]
@Component({
template: `<ui-new-component>Content</ui-new-component>`
})
```
:::
## API
### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `class` | `string` | - | Additional CSS classes |
## Examples
### Basic
[Add examples here]Update Sidebar
Add component to docs/.vitepress/config.ts:
{
text: 'Components',
items: [
// ... existing items
{ text: 'New Component', link: '/components/new-component' },
],
}Coding Standards
TypeScript
- Use TypeScript for all code
- Enable strict mode
- Add types for all props and functions
- Avoid
anytype
// ✅ Good
interface Props {
variant: 'default' | 'secondary'
onClick?: () => void
}
// ❌ Bad
interface Props {
variant: any
onClick: Function
}Component Style
- Use functional components
- Use React.forwardRef for React components
- Export interfaces/types
- Add
displayNamefor React components
// ✅ Good
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'default' | 'secondary'
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = 'default', ...props }, ref) => {
return <button ref={ref} {...props} />
}
)
Button.displayName = 'Button'Styling
- Use Tailwind CSS classes
- Use cn() utility for class merging
- Support dark mode
// ✅ Good
<div className={cn('bg-background text-foreground', className)} />
// ❌ Bad
<div className={`bg-white text-black ${className}`} />File Naming
- React: PascalCase (Button.tsx)
- Vue: PascalCase (Button.vue)
- Angular: kebab-case (button.component.ts)
Commit Conventions
We follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]Types
feat: New featurefix: Bug fixdocs: Documentation onlystyle: Code style (formatting, no code change)refactor: Code refactoringtest: Adding testschore: Maintenance tasks
Examples
# Feature
feat(cli): add support for pnpm package manager
# Bug fix
fix(react): fix button disabled state styling
# Documentation
docs: update installation guide
# Breaking change
feat(vue)!: change dialog API to use composable
BREAKING CHANGE: Dialog now requires useDialog composablePull Request Guidelines
PR Title
Follow commit conventions:
feat(react): add tooltip component
fix(cli): resolve path alias on Windows
docs: add dark mode guidePR Description
Use this template:
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-reviewed code
- [ ] Added/updated tests
- [ ] Added/updated documentation
- [ ] Changes generate no new warnings
- [ ] Tested in all frameworks (React, Vue, Angular)
## Screenshots (if applicable)
[Add screenshots]
## Related Issues
Fixes #123Review Process
- Automated checks must pass (linting, type checking)
- Maintainer review - may request changes
- Approval - PR will be merged
- Release - Changes included in next release
Testing
Component Testing
Test components in all three frameworks:
# React
cd examples/react-example
npm run dev
# Vue
cd examples/vue-example
npm run dev
# Angular
cd examples/angular-example
npm run devCLI Testing
# Build CLI
cd packages/cli
npm run build
# Test init command
cd ../../examples/react-example
rm -rf components components.json
node ../../packages/cli/dist/bin.js init
# Test add command
node ../../packages/cli/dist/bin.js add buttonDocumentation
Writing Guidelines
- Be clear and concise
- Use code examples for all features
- Include all frameworks (React, Vue, Angular)
- Add TypeScript types
- Show both basic and advanced usage
Code Examples
Always provide examples for all frameworks:
::: code-group
\`\`\`tsx [React]
// React example
\`\`\`
\`\`\`vue [Vue]
// Vue example
\`\`\`
\`\`\`typescript [Angular]
// Angular example
\`\`\`
:::Local Docs Development
cd docs
npm install
npm run devVisit http://localhost:5173
Community
Getting Help
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions and discussions
- Discord: Real-time chat (coming soon)
Code of Conduct
Be respectful and constructive. We follow the Contributor Covenant Code of Conduct.
License
By contributing, you agree that your contributions will be licensed under the project's MIT License.
Questions?
- Read the documentation
- Search existing issues
- Open a new discussion
Thank you for contributing! 🎉
