Skip to content

Latest commit

 

History

History
331 lines (262 loc) · 6.89 KB

File metadata and controls

331 lines (262 loc) · 6.89 KB

Contributing to UIX

Thanks for your interest in contributing! UIX is an AI-to-UI protocol layer, not a traditional component library.

Core Concept

The consumer is AI, not developers.

When contributing, remember:

  • We're building a protocol that AI can generate (UIX IR)
  • Components are renderers for UIX IR types
  • The focus is on AI-generatable JSON, not developer ergonomics

Package Structure

Package Layer Purpose
@uix-ai/core Protocol UIX IR JSON Schema & TypeScript types
@uix-ai/react Renderer React renderer & base components
@uix-ai/stream Renderer Streaming content (self-healing markdown)
@uix-ai/agent Renderer Conversation & block renderers
@uix-ai/tokens Design System Colors, typography, spacing

This guide will help you add new components or improve existing ones.

📋 Component Development Checklist

When creating a new component, ensure it meets these criteria:

1. Accessibility First

  • Keyboard navigation support
  • Screen reader compatible (ARIA labels)
  • Focus management
  • Proper semantic HTML

2. Design Consistency

  • Uses design tokens from @uix-ai/tokens
  • Follows Lucid color philosophy (no AI purple)
  • Consistent with existing component patterns
  • Responsive by default

3. Developer Experience

  • TypeScript types fully defined
  • Props documented with JSDoc comments
  • Examples in component file
  • Composable via asChild when appropriate

4. AI Readability

  • Clear inline documentation
  • Usage examples in comments
  • Design rationale explained
  • Common patterns demonstrated

🏗️ Component Structure

packages/react/src/components/[component-name]/
├── [component-name].tsx    # Main component file
├── index.ts                 # Exports
└── README.md               # Component-specific docs (optional)

📝 Component Template

Use this template when creating a new component:

/**
 * [ComponentName] Component
 *
 * [Brief description of what this component does]
 *
 * ## AI Usage Guide
 *
 * ### Basic Usage
 * ```tsx
 * import { ComponentName } from '@uix-ai/react'
 *
 * <ComponentName>Content</ComponentName>
 * ```
 *
 * ### Design Principles
 * - [Principle 1]
 * - [Principle 2]
 *
 * ### Variants
 * - variant1: [description]
 * - variant2: [description]
 */

import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '../../lib/utils'

const componentVariants = cva(
  // Base styles
  'base-class-here',
  {
    variants: {
      variant: {
        default: 'default-classes',
        // Add more variants
      },
      size: {
        sm: 'small-size-classes',
        default: 'default-size-classes',
        lg: 'large-size-classes',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  }
)

export interface ComponentNameProps
  extends React.HTMLAttributes<HTMLDivElement>, // or appropriate HTML element
    VariantProps<typeof componentVariants> {
  /**
   * Prop description
   */
  propName?: string
}

const ComponentName = React.forwardRef<HTMLDivElement, ComponentNameProps>(
  ({ className, variant, size, ...props }, ref) => {
    return (
      <div
        className={cn(componentVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    )
  }
)
ComponentName.displayName = 'ComponentName'

export { ComponentName, componentVariants }

🎨 Design Token Usage

Always use design tokens, never hardcoded values:

✅ Good

className="bg-primary-500 text-white border-border"

❌ Bad

className="bg-[#0EA5E9] text-[#FFFFFF] border-[#E5E5E5]"

Semantic Tokens

Prefer semantic tokens when available:

className="bg-background text-foreground" // ✅
className="bg-white text-gray-900"        // ⚠️ Less semantic

🧪 Testing Your Component

  1. Build the package:
cd packages/react
pnpm build
  1. Check TypeScript types:
pnpm tsc --noEmit
  1. Test in Storybook (once configured):
pnpm storybook

📚 Documentation Standards

Component File Documentation

Every component should have:

  1. Header comment explaining purpose
  2. AI Usage Guide section with:
    • Basic usage examples
    • Design principles
    • Variant explanations
  3. JSDoc for all props
  4. Inline comments for complex logic

Example:

/**
 * Render as a child element instead of a div.
 * Useful for creating links that look like cards.
 *
 * @example
 * <Card asChild>
 *   <a href="/somewhere">Card link</a>
 * </Card>
 */
asChild?: boolean

🚀 Submitting Changes

  1. Fork the repository
  2. Create a feature branch:
    git checkout -b feat/add-card-component
  3. Make your changes
  4. Commit with clear message:
    git commit -m "feat: add Card component with variants"
  5. Push and create PR:
    git push origin feat/add-card-component

Commit Message Format

type(scope): subject

[optional body]

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • style: Formatting
  • refactor: Code restructuring
  • test: Adding tests
  • chore: Maintenance

🎯 Contribution Priorities

We're building in this order:

Phase 1: Protocol Core (Current)

  • UIX IR JSON Schema definition
  • TypeScript type definitions
  • Design tokens system
  • React base components

Phase 2: Block Renderers

  • TextBlock → StreamMarkdown
  • ToolBlock → ToolResult
  • ThinkingBlock → ThinkingIndicator
  • ImageBlock → Image renderer
  • FileBlock → File renderer

Phase 3: Renderers & Adapters

  • ReactRenderer (default)
  • AgentX adapter
  • A2UI adapter (when mature)
  • MCP Apps adapter (when mature)

💡 Best Practices

1. Composition over Configuration

Prefer simple, composable components:

// ✅ Good
<Card>
  <CardHeader>Title</CardHeader>
  <CardContent>Content</CardContent>
</Card>

// ❌ Avoid
<Card title="Title" content="Content" />

2. Radix UI Integration

Use Radix primitives for complex interactions:

import * as Dialog from '@radix-ui/react-dialog'

// Build on top of Radix, add Lucid styling

3. Avoid Over-Engineering

Keep it simple:

  • Don't add variants "just in case"
  • Don't create abstractions for single use cases
  • Prefer explicit over clever

4. Mobile-First

Always design mobile-first with Tailwind:

// ✅ Mobile-first
className="text-sm md:text-base lg:text-lg"

// ❌ Desktop-first
className="text-lg md:text-base sm:text-sm"

🤔 Questions?


Made with ❤️ by Deepractice