
ui-skills
by levisegal
SKILL.md
name: ui-skills description: Comprehensive UI/frontend development skill for React, Next.js, Vue, Svelte, and Tailwind CSS. Provides guidance on component architecture, accessibility, responsive design, state management, and modern CSS techniques. Automatically triggers for any frontend/UI work including building components, pages, styling, and interactive features.
UI Skills - Frontend Development Guide
Overview
This skill provides comprehensive guidance for modern UI/frontend development across multiple frameworks and libraries. Use this skill whenever you're working on user interfaces, components, styling, or interactive features.
When This Skill Activates
This skill automatically activates when:
- Building or modifying UI components (React, Vue, Svelte, etc.)
- Working with Next.js, Create React App, Vite, or other frontend tooling
- Implementing styles with Tailwind CSS, CSS Modules, or styled-components
- Creating layouts, forms, navigation, or interactive elements
- Implementing responsive design or accessibility features
- Working with state management (React hooks, Zustand, Redux, Pinia, etc.)
Design System Selection
IMPORTANT: Before starting ANY new UI work, you should invoke the ui-portfolio-design skill to help the user select a design direction. This ensures consistent, intentional aesthetics from the start.
To invoke the portfolio selection:
- Detect when starting new UI work (not modifying existing components)
- Present the portfolio selection from
/docs/ui-portfolio/index.html - Once user selects a direction, apply that design system consistently
Skip portfolio selection only when:
- Modifying existing components (maintain current style)
- User explicitly requests a specific style
- Working in a codebase with established design system
Core Principles
1. Component Architecture
Single Responsibility
- Each component should do one thing well
- Extract complex logic into custom hooks or composables
- Keep components small and focused (< 200 lines)
Composition Over Complexity
// Good: Composable, reusable
<Card>
<CardHeader>
<CardTitle>Dashboard</CardTitle>
</CardHeader>
<CardContent>
{children}
</CardContent>
</Card>
// Avoid: Monolithic with too many props
<Card
title="Dashboard"
showHeader
headerAlign="left"
contentPadding="large"
// ... 20 more props
/>
Props Design
- Use discriminated unions for variants
- Prefer
childrenover render props when possible - Make common use cases simple, advanced use cases possible
- Use TypeScript for prop validation
2. Accessibility (a11y)
Always Include
- Semantic HTML elements (
<button>,<nav>,<main>, etc.) - ARIA labels where needed (
aria-label,aria-describedby) - Keyboard navigation (Tab, Enter, Escape, Arrow keys)
- Focus management (visible focus states, focus trapping in modals)
- Color contrast ratios (WCAG AA minimum: 4.5:1 for text)
Common Patterns
// Accessible button
<button
onClick={handleClick}
aria-label="Close dialog"
aria-pressed={isActive}
>
<Icon aria-hidden="true" />
Close
</button>
// Accessible form input
<div>
<label htmlFor="email" className="block mb-2">
Email Address
</label>
<input
id="email"
type="email"
aria-describedby="email-hint"
aria-invalid={hasError}
/>
<span id="email-hint" className="text-sm text-gray-600">
We'll never share your email
</span>
</div>
// Skip to main content
<a href="#main-content" className="sr-only focus:not-sr-only">
Skip to main content
</a>
<main id="main-content">
{/* content */}
</main>
3. Responsive Design
Mobile-First Approach
- Start with mobile layout, enhance for larger screens
- Use Tailwind breakpoints:
sm:,md:,lg:,xl:,2xl: - Test at breakpoints: 320px, 768px, 1024px, 1440px
Fluid Typography & Spacing
/* Use clamp for fluid sizing */
font-size: clamp(1rem, 2vw + 0.5rem, 2rem);
/* Or Tailwind responsive utilities */
<h1 className="text-2xl sm:text-3xl lg:text-5xl">
Container Queries (when supported)
@container (min-width: 400px) {
.card { grid-template-columns: 1fr 1fr; }
}
4. State Management
Local State First
- Use component state (
useState,ref) for UI-only state - Lift state only when needed by multiple components
- Use context sparingly (avoid overuse)
Server State
- Use TanStack Query (React Query) for server data
- Implement optimistic updates for better UX
- Handle loading, error, and success states
Form State
- React Hook Form for complex forms
- Controlled vs uncontrolled inputs (prefer uncontrolled with refs)
- Validation with Zod or Yup
// Good: Server state with TanStack Query
const { data, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
})
// Good: Form state with React Hook Form
const { register, handleSubmit, formState: { errors } } = useForm()
5. Performance
Lazy Loading
// Code splitting
const Dashboard = lazy(() => import('./Dashboard'))
// Image optimization
<Image
src="/hero.jpg"
alt="Hero"
loading="lazy"
width={1200}
height={600}
/>
Memoization
- Use
useMemofor expensive calculations - Use
useCallbackfor stable function references - Use
memo()for expensive components - Don't over-optimize - profile first
Virtual Lists
- Use react-virtual for long lists (> 100 items)
- Implement infinite scroll with Intersection Observer
6. Styling Best Practices
Tailwind CSS
- Use
@applysparingly (components only) - Prefer utility classes in JSX
- Extract repeated patterns to components, not
@apply - Use arbitrary values when needed:
w-[347px]
Component Variants
// Using class-variance-authority (cva)
const buttonVariants = cva(
"rounded font-medium transition-colors", // base
{
variants: {
variant: {
default: "bg-blue-600 text-white hover:bg-blue-700",
outline: "border border-gray-300 hover:bg-gray-50",
ghost: "hover:bg-gray-100",
},
size: {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-base",
lg: "px-6 py-3 text-lg",
},
},
defaultVariants: {
variant: "default",
size: "md",
},
}
)
CSS Modules (when not using Tailwind)
- Use for component-scoped styles
- Name files
Component.module.css - Compose styles with
composes
7. Component Patterns
Compound Components
// API that reads well
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
<TabsContent value="overview">
{/* content */}
</TabsContent>
</Tabs>
Render Props (when composition isn't enough)
<DataFetcher url="/api/users">
{({ data, loading, error }) => (
loading ? <Spinner /> : <UserList users={data} />
)}
</DataFetcher>
Slots Pattern (React, Vue)
// React
<Layout
header={<Header />}
sidebar={<Sidebar />}
footer={<Footer />}
>
{children}
</Layout>
8. Error Handling
Error Boundaries (React)
<ErrorBoundary fallback={<ErrorPage />}>
<App />
</ErrorBoundary>
Error States in UI
if (error) {
return (
<Alert variant="error">
<AlertTitle>Failed to load data</AlertTitle>
<AlertDescription>
{error.message}
<Button onClick={retry}>Try Again</Button>
</AlertDescription>
</Alert>
)
}
9. Animation & Transitions
Framer Motion (React)
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
>
{content}
</motion.div>
CSS Transitions (Tailwind)
<div className="transition-all duration-200 hover:scale-105">
Reduced Motion
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
10. Testing
Component Tests
- Test user interactions, not implementation
- Use Testing Library queries (
getByRole,getByLabelText) - Test accessibility (keyboard nav, screen reader labels)
Visual Regression
- Consider Storybook + Chromatic for component libraries
- Screenshot tests for critical UI
Framework-Specific Guidance
React / Next.js
File Organization
src/
components/
ui/ # Reusable UI primitives (Button, Input, Card)
features/ # Feature-specific components
hooks/ # Custom hooks
lib/ # Utilities, API clients
app/ # Next.js app router
Server Components (Next.js 13+)
- Default to Server Components
- Use Client Components only when needed (interactivity, hooks)
- Pass server data as props to client components
Data Fetching
// Server Component
async function Page() {
const data = await fetch('https://api.example.com/data')
return <Dashboard data={data} />
}
// Client Component with TanStack Query
'use client'
function Dashboard() {
const { data } = useQuery(...)
return <div>{data}</div>
}
Vue / Nuxt
Composition API
- Prefer
<script setup>syntax - Use composables for reusable logic
- Leverage auto-imports
Reactivity
// Reactive state
const state = reactive({ count: 0 })
// Computed properties
const doubled = computed(() => state.count * 2)
// Watch for changes
watch(() => state.count, (newVal) => {
console.log(newVal)
})
Svelte / SvelteKit
Reactivity
<script>
let count = 0
$: doubled = count * 2 // Reactive declaration
</script>
<button on:click={() => count++}>
Count: {count}, Doubled: {doubled}
</button>
Stores
// Writable store
const count = writable(0)
// Derived store
const doubled = derived(count, $count => $count * 2)
// Auto-subscription in components
<script>
import { count } from './stores'
</script>
<div>{$count}</div>
Common Anti-Patterns to Avoid
❌ Don't
Over-Abstraction
// TOO GENERIC
<FlexBox direction="column" justify="center" align="items" gap={4}>
Prop Drilling
- Passing props through 3+ levels
- Solution: Context, composition, or state management
Inline Functions in JSX (if causing perf issues)
// Can cause re-renders
<button onClick={() => handleClick(id)}>
Magic Numbers
// Bad
<div className="w-[347px] h-[291px]">
// Good
<div className="w-80 h-72"> // or semantic sizes
Ignoring Loading States
// Bad: Just shows nothing while loading
{data && <UserList users={data} />}
// Good: Show skeleton or spinner
{isLoading ? <Skeleton /> : <UserList users={data} />}
✅ Do
Use Semantic HTML
<button> for actions, not <div onClick>
<a> for navigation, not <div onClick>
<nav>, <main>, <article>, <section>
Keep Props Simple
// Good: Clear, typed props
interface ButtonProps {
variant?: 'default' | 'outline' | 'ghost'
size?: 'sm' | 'md' | 'lg'
disabled?: boolean
onClick?: () => void
children: React.ReactNode
}
Handle Edge Cases
- Empty states (no data)
- Loading states (fetching data)
- Error states (failed request)
- Disabled states (form submission)
Tools & Libraries
Essential
- Tailwind CSS - Utility-first CSS
- TanStack Query - Server state management
- React Hook Form - Form state
- Zod - Schema validation
UI Components
- shadcn/ui - Copy-paste components
- Radix UI - Headless components
- Headless UI - Tailwind-specific
Animation
- Framer Motion - React animations
- Auto-animate - Drop-in animations
Icons
- Lucide React - Icon library
- Heroicons - Tailwind icons
Workflow
Starting New UI Work
-
Check for existing design system
- Look for existing components in
components/ui/ - Check for Tailwind config, color schemes
- Review any design documentation
- Look for existing components in
-
If no design system exists
- Invoke
ui-portfolio-designskill - Present portfolio selection to user
- Load chosen design system specifications
- Invoke
-
Build components
- Start with semantic HTML
- Apply styles (Tailwind or CSS Modules)
- Add interactivity (event handlers, state)
- Implement accessibility features
- Handle loading/error states
-
Test & refine
- Test keyboard navigation
- Test at different screen sizes
- Test with screen reader (if possible)
- Review with user
Modifying Existing UI
-
Understand current patterns
- Read existing component code
- Identify naming conventions
- Note styling approach (Tailwind, CSS Modules, etc.)
-
Maintain consistency
- Match existing component structure
- Use same styling patterns
- Follow established naming conventions
-
Improve incrementally
- Fix accessibility issues when found
- Suggest refactors only when asked
- Don't rewrite working code without reason
Best Practices Summary
- Accessibility First - Always include semantic HTML, ARIA labels, keyboard nav
- Mobile First - Start mobile, enhance for desktop
- Performance - Lazy load, code split, optimize images
- Composition - Small, reusable components
- Type Safety - Use TypeScript for props and state
- Error Handling - Always handle loading, error, empty states
- Testing - Test user behavior, not implementation
- Consistency - Follow existing patterns in the codebase
When to Ask for Clarification
- Design direction unclear - Invoke portfolio selection
- Accessibility requirements - Ask about target WCAG level
- Browser support - Ask about target browsers/devices
- Performance constraints - Ask about expected data volume
- State management - Ask if existing solution is in place
Remember: Before starting new UI work, consider invoking the ui-portfolio-design skill to select a design direction. This ensures intentional, cohesive aesthetics from the start.
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です