Comprehensive guide for developers working with UI8Kit. Here you'll find everything you need for efficient development.
- Basic Workflow - Step-by-step getting started guide
- Best Practices - Recommendations and patterns
- Dark Mode - Theme support implementation
- Component Development - Creating custom components
- Theme Customization - Theme customization
- Testing - Component testing
- Performance - Performance optimization
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" />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>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"
}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
// 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'// 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
}// 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
}// 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.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.config.js
export default {
semi: false,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
printWidth: 100
}// 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 }// 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')
})
})Use React DevTools for profiling:
- Install browser extension
- Enable "Highlight updates when components render"
- Use Profiler for performance analysis
# Analyze bundle size
npm install -D vite-bundle-analyzer
npm run build
npx vite-bundle-analyzer dist// 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)
}, [])// 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>// Correct focus management
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleSelect()
}
}// 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># .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# 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- React DevTools
- Vite Bundle Analyzer
- Lighthouse
- axe-core - Accessibility testing
-
TypeScript Errors
- Check
tsconfig.json - Ensure imports are correct
- Check
-
Styles Not Applied
- Check Tailwind configuration
- Ensure content paths are correct
-
Components Not Rendering
- Check ThemeProvider
- Ensure CSS variables are correct
-
Performance
- Use React DevTools Profiler
- Check bundle analyzer
// Add debug helpers in development
if (process.env.NODE_ENV === 'development') {
console.log('Component props:', props)
console.log('Theme context:', useTheme())
}Now that you're familiar with the basics:
- Start with Basic Workflow
- Learn Best Practices
- Set up Dark Mode
- Create your components
- Write tests
- Optimize performance
Join the community and share your components! π