
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.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon