Skip to content

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 ​

  1. Fork the repository

    Visit github.com/galaxy-nebula/galaxy-design and click "Fork"

  2. Clone your fork

    bash
    git clone https://github.com/YOUR_USERNAME/galaxy-design.git
    cd galaxy-design
  3. Add upstream remote

    bash
    git remote add upstream https://github.com/galaxy-nebula/galaxy-design.git

Install Dependencies ​

bash
# Install dependencies
npm install

# or
bun install

Project 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 ​

bash
# 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-description

2. Make Changes ​

Follow our coding standards and commit conventions.

3. Test Changes ​

bash
# 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 dev

4. Commit Changes ​

bash
git add .
git commit -m "feat: add new button variant"

5. Push and Create PR ​

bash
git push origin feat/your-feature-name

Then create a Pull Request on GitHub.

Contribution Types ​

🐛 Bug Fixes ​

  1. Search existing issues to avoid duplicates
  2. Create an issue describing the bug
  3. Fix the bug and add tests
  4. Submit PR referencing the issue

✨ New Features ​

  1. Open a discussion for major features
  2. Get approval before starting work
  3. Implement feature with tests and docs
  4. Submit PR with detailed description

📝 Documentation ​

  1. Identify gaps in documentation
  2. Write clear, concise docs
  3. Add code examples
  4. Submit PR

🎨 New Components ​

Adding a new component requires work across multiple packages:

React Component ​

bash
# 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.ts

NewComponent.tsx:

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:

typescript
export * from './NewComponent'

Vue Component ​

bash
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.ts

NewComponent.vue:

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 ​

bash
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.ts

new-component.component.ts:

typescript
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:

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 ​

bash
touch docs/components/new-component.md

new-component.md:

markdown
# 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:

typescript
{
  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 any type
typescript
// ✅ 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 displayName for React components
tsx
// ✅ 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
tsx
// ✅ 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 feature
  • fix: Bug fix
  • docs: Documentation only
  • style: Code style (formatting, no code change)
  • refactor: Code refactoring
  • test: Adding tests
  • chore: Maintenance tasks

Examples ​

bash
# 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 composable

Pull Request Guidelines ​

PR Title ​

Follow commit conventions:

feat(react): add tooltip component
fix(cli): resolve path alias on Windows
docs: add dark mode guide

PR Description ​

Use this template:

markdown
## 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 #123

Review Process ​

  1. Automated checks must pass (linting, type checking)
  2. Maintainer review - may request changes
  3. Approval - PR will be merged
  4. Release - Changes included in next release

Testing ​

Component Testing ​

Test components in all three frameworks:

bash
# React
cd examples/react-example
npm run dev

# Vue
cd examples/vue-example
npm run dev

# Angular
cd examples/angular-example
npm run dev

CLI Testing ​

bash
# 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 button

Documentation ​

Writing Guidelines ​

  1. Be clear and concise
  2. Use code examples for all features
  3. Include all frameworks (React, Vue, Angular)
  4. Add TypeScript types
  5. Show both basic and advanced usage

Code Examples ​

Always provide examples for all frameworks:

markdown
::: code-group

\`\`\`tsx [React]
// React example
\`\`\`

\`\`\`vue [Vue]
// Vue example
\`\`\`

\`\`\`typescript [Angular]
// Angular example
\`\`\`

:::

Local Docs Development ​

bash
cd docs
npm install
npm run dev

Visit 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? ​

Thank you for contributing! 🎉

Released under the MIT License.