Skip to content

Latest commit

Β 

History

History
462 lines (361 loc) Β· 9.9 KB

File metadata and controls

462 lines (361 loc) Β· 9.9 KB

Development Guide

Comprehensive guide for developers working with UI8Kit. Here you'll find everything you need for efficient development.

πŸ“‹ Contents

🎯 Key Concepts

Utility-First Architecture

UI8Kit is built on utility-first design principles, where every visual aspect is accessible through props:

// Instead of CSS classes
<div className="p-4 bg-blue-500 text-white rounded-md">

// Use props
<Block p="md" bg="primary" c="primary-foreground" rounded="md" />

Polymorphic Components

All components can render as any HTML element:

// Semantic markup
<Block component="section">
  <Block component="h1">Title</Block>
</Block>

// Accessibility
<Button component="a" href="/dashboard">
  Go to Dashboard
</Button>

Variant System (CVA)

Type-safe variants through Class Variance Authority:

// Variants are automatically typed
<Button variant="primary" size="lg" />

// TypeScript knows all possible values
type ButtonProps = {
  variant?: "default" | "primary" | "destructive" | ...
  size?: "xs" | "sm" | "default" | "lg" | "xl" | "icon"
}

πŸ—οΈ Project Architecture

Recommended Structure

src/
β”œβ”€β”€ components/          # Reusable components
β”‚   β”œβ”€β”€ ui/             # Basic UI components
β”‚   β”œβ”€β”€ forms/          # Forms and input fields
β”‚   β”œβ”€β”€ layout/         # Layout components
β”‚   └── feedback/       # Notifications, modals
β”œβ”€β”€ hooks/              # Custom hooks
β”œβ”€β”€ lib/                # Utilities and helpers
β”œβ”€β”€ providers/          # Context providers (theme, auth, etc.)
β”œβ”€β”€ styles/             # Global styles
β”œβ”€β”€ types/              # TypeScript types
β”œβ”€β”€ constants/          # Application constants
└── utils/              # Helper functions

Component Organization

// components/index.ts - Barrel exports
export { Button } from './ui/Button'
export { Card } from './ui/Card'
export { Input } from './forms/Input'
export { Modal } from './feedback/Modal'

// components/ui/Button/index.ts
export { Button } from './Button'
export type { ButtonProps } from './Button'

// components/ui/Button/Button.tsx
export interface ButtonProps extends /* ... */ {
  // Props
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => {
    // Implementation
  }
)

Button.displayName = 'Button'

🎨 Working with Themes

Basic Setup

// providers/theme.tsx
import { createContext, useContext, ReactNode } from 'react'

export type ThemeBase = {
  name: string
  rounded: Record<string, any> & { default: any }
  buttonSize: Record<string, any> & { default: any }
  isNavFixed?: boolean
}

export function ThemeProvider({ children, theme }: {
  children: ReactNode
  theme: ThemeBase
}) {
  // Implementation
}

export function useTheme<T extends ThemeBase = ThemeBase>() {
  // Implementation
}

Custom Themes

// themes/index.ts
export const lightTheme = {
  name: "Light",
  rounded: {
    default: "md" as const,
    button: "lg" as const,
    card: "xl" as const
  },
  buttonSize: {
    default: "sm" as const,
    icon: "md" as const
  },
  isNavFixed: true
}

export const darkTheme = {
  // Dark theme configuration
}

πŸ”§ Development Tools

TypeScript Configuration

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

ESLint Configuration

// eslint.config.js
import js from '@eslint/js'
import ts from 'typescript-eslint'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'

export default [
  js.configs.recommended,
  ...ts.configs.recommended,
  react.configs.flat.recommended,
  reactHooks.configs.recommended,
  {
    rules: {
      // Custom rules
      'react/react-in-jsx-scope': 'off',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }]
    }
  }
]

Prettier Configuration

// prettier.config.js
export default {
  semi: false,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'none',
  printWidth: 100
}

πŸ§ͺ Testing

Test Environment Setup

// src/test-utils.tsx
import { render, RenderOptions } from '@testing-library/react'
import { ThemeProvider } from '@/providers/theme'
import { defaultTheme } from '@/themes'

const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
  return (
    <ThemeProvider theme={defaultTheme}>
      {children}
    </ThemeProvider>
  )
}

const customRender = (
  ui: React.ReactElement,
  options?: Omit<RenderOptions, 'wrapper'>,
) => render(ui, { wrapper: AllTheProviders, ...options })

export * from '@testing-library/react'
export { customRender as render }

Test Examples

// components/__tests__/Button.test.tsx
import { render, screen, fireEvent } from '@/test-utils'
import { Button } from '../Button'

describe('Button', () => {
  it('renders children correctly', () => {
    render(<Button>Hello World</Button>)
    expect(screen.getByText('Hello World')).toBeInTheDocument()
  })

  it('handles click events', () => {
    const handleClick = jest.fn()
    render(<Button onClick={handleClick}>Click me</Button>)

    fireEvent.click(screen.getByRole('button'))
    expect(handleClick).toHaveBeenCalledTimes(1)
  })

  it('applies correct styles', () => {
    const { container } = render(<Button variant="primary">Button</Button>)
    expect(container.firstChild).toHaveClass('bg-primary')
  })
})

πŸš€ Performance Optimization

React DevTools

Use React DevTools for profiling:

  1. Install browser extension
  2. Enable "Highlight updates when components render"
  3. Use Profiler for performance analysis

Bundle Analysis

# Analyze bundle size
npm install -D vite-bundle-analyzer
npm run build
npx vite-bundle-analyzer dist

Optimizations

// Component memoization
const MemoizedComponent = memo(function Component({ data }) {
  return <div>{data}</div>
})

// Computation memoization
const filteredData = useMemo(() =>
  data.filter(item => item.active),
  [data]
)

// Stable callbacks
const handleClick = useCallback(() => {
  setCount(c => c + 1)
}, [])

β™Ώ Accessibility

ARIA Attributes

// Correct ARIA usage
<Button
  aria-expanded={isOpen}
  aria-controls="menu"
  aria-haspopup="menu"
>
  Menu
</Button>

// Screen reader content
<Text className="sr-only">
  Screen reader only text
</Text>

Keyboard navigation

// Correct focus management
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault()
    handleSelect()
  }
}

Color contrast

// Use semantic colors
<Text c="foreground">High contrast text</Text>
<Text c="muted">Lower contrast text</Text>

// Don't use hardcoded colors
<Text className="text-gray-600">Bad contrast</Text>

πŸ”„ CI/CD

GitHub Actions workflow

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - run: npm ci
      - run: npm run type-check
      - run: npm run lint
      - run: npm run test
      - run: npm run build

Pre-commit hooks

# Install husky
npm install -D husky
npx husky install

# Add hooks
echo 'npm run type-check' > .husky/pre-commit
echo 'npm run lint' >> .husky/pre-commit
echo 'npm run test' >> .husky/pre-commit

πŸ“š Resources

Official Documentation

Tools

Community

πŸ†˜ Troubleshooting

Common Issues

  1. TypeScript Errors

    • Check tsconfig.json
    • Ensure imports are correct
  2. Styles Not Applied

    • Check Tailwind configuration
    • Ensure content paths are correct
  3. Components Not Rendering

    • Check ThemeProvider
    • Ensure CSS variables are correct
  4. Performance

    • Use React DevTools Profiler
    • Check bundle analyzer

Debug Mode

// Add debug helpers in development
if (process.env.NODE_ENV === 'development') {
  console.log('Component props:', props)
  console.log('Theme context:', useTheme())
}

🎯 Next Steps

Now that you're familiar with the basics:

  1. Start with Basic Workflow
  2. Learn Best Practices
  3. Set up Dark Mode
  4. Create your components
  5. Write tests
  6. Optimize performance

Join the community and share your components! πŸš€