# Web Component Design > Master React, Vue, and Svelte component patterns including CSS-in-JS, composition strategies, and reusable component architecture. Use when building UI component libraries, designing component APIs, or implementing frontend design systems. Source: https://skillsagentes.com/skills/wshobson/agents/web-component-design Repository: https://github.com/wshobson/agents Author: wshobson License: MIT Updated: hace 5 meses Context cost: 60 tok installed, 1.9k tok once triggered, 11.5k tok with every bundled file Bundle: 4 files, 45 KB Permissions requested: none declared ## Install ```bash npx -y skills add wshobson/agents --skill web-component-design --agent claude-code ``` ## What it does - Aplica patrones de composición de componentes: compound components, render props y slots - Define enfoques CSS-in-JS (Tailwind, CSS Modules, styled-components, Emotion, Vanilla Extract) - Diseña APIs de componentes con props semánticas y valores por defecto sensatos - Genera ejemplos de código para React, Vue 3 y Svelte 5 ## Use it when - Diseñar librerías de componentes reutilizables o sistemas de diseño - Implementar patrones complejos de composición de componentes - Elegir y aplicar una solución CSS-in-JS - Refactorizar componentes legacy hacia patrones modernos ## What triggers it - "Ayúdame a diseñar un componente Accordion con compound components en React" - "Necesito elegir entre Tailwind y styled-components para mi design system" - "Crea un Button reutilizable con variantes usando class-variance-authority" - "Cómo implemento slots con nombre en Vue 3" ## Files - SKILL.md — 7 KB - references/accessibility-patterns.md — 15 KB - references/component-patterns.md — 10 KB - references/css-styling-approaches.md — 12 KB ## SKILL.md Reproduced verbatim from wshobson/agents under MIT. This section is the upstream document and is in English. # Web Component Design Build reusable, maintainable UI components using modern frameworks with clean composition patterns and styling approaches. ## When to Use This Skill - Designing reusable component libraries or design systems - Implementing complex component composition patterns - Choosing and applying CSS-in-JS solutions - Building accessible, responsive UI components - Creating consistent component APIs across a codebase - Refactoring legacy components into modern patterns - Implementing compound components or render props ## Core Concepts ### 1. Component Composition Patterns **Compound Components**: Related components that work together ```tsx // Usage ``` **Render Props**: Delegate rendering to parent ```tsx {({ data, loading, error }) => loading ? : } ``` **Slots (Vue/Svelte)**: Named content injection points ```vue ``` ### 2. CSS-in-JS Approaches | Solution | Approach | Best For | | --------------------- | ---------------------- | --------------------------------- | | **Tailwind CSS** | Utility classes | Rapid prototyping, design systems | | **CSS Modules** | Scoped CSS files | Existing CSS, gradual adoption | | **styled-components** | Template literals | React, dynamic styling | | **Emotion** | Object/template styles | Flexible, SSR-friendly | | **Vanilla Extract** | Zero-runtime | Performance-critical apps | ### 3. Component API Design ```tsx interface ButtonProps { variant?: "primary" | "secondary" | "ghost"; size?: "sm" | "md" | "lg"; isLoading?: boolean; isDisabled?: boolean; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; children: React.ReactNode; onClick?: () => void; } ``` **Principles**: - Use semantic prop names (`isLoading` vs `loading`) - Provide sensible defaults - Support composition via `children` - Allow style overrides via `className` or `style` ## Quick Start: React Component with Tailwind ```tsx import { forwardRef, type ComponentPropsWithoutRef } from "react"; import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; const buttonVariants = cva( "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { primary: "bg-blue-600 text-white hover:bg-blue-700", secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200", ghost: "hover:bg-gray-100 hover:text-gray-900", }, size: { sm: "h-8 px-3 text-sm", md: "h-10 px-4 text-sm", lg: "h-12 px-6 text-base", }, }, defaultVariants: { variant: "primary", size: "md", }, }, ); interface ButtonProps extends ComponentPropsWithoutRef<"button">, VariantProps { isLoading?: boolean; } export const Button = forwardRef( ({ className, variant, size, isLoading, children, ...props }, ref) => ( ), ); Button.displayName = "Button"; ``` ## Framework Patterns ### React: Compound Components ```tsx import { createContext, useContext, useState, type ReactNode } from "react"; interface AccordionContextValue { openItems: Set; toggle: (id: string) => void; } const AccordionContext = createContext(null); function useAccordion() { const context = useContext(AccordionContext); if (!context) throw new Error("Must be used within Accordion"); return context; } export function Accordion({ children }: { children: ReactNode }) { const [openItems, setOpenItems] = useState>(new Set()); const toggle = (id: string) => { setOpenItems((prev) => { const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next; }); }; return (
{children}
); } Accordion.Item = function AccordionItem({ id, title, children, }: { id: string; title: string; children: ReactNode; }) { const { openItems, toggle } = useAccordion(); const isOpen = openItems.has(id); return (
{isOpen &&
{children}
}
); }; ``` ### Vue 3: Composables ```vue ``` ### Svelte 5: Runes ```svelte ``` ## Best Practices 1. **Single Responsibility**: Each component does one thing well 2. **Prop Drilling Prevention**: Use context for deeply nested data 3. **Accessible by Default**: Include ARIA attributes, keyboard support 4. **Controlled vs Uncontrolled**: Support both patterns when appropriate 5. **Forward Refs**: Allow parent access to DOM nodes 6. **Memoization**: Use `React.memo`, `useMemo` for expensive renders 7. **Error Boundaries**: Wrap components that may fail ## Common Issues - **Prop Explosion**: Too many props - consider composition instead - **Style Conflicts**: Use scoped styles or CSS Modules - **Re-render Cascades**: Profile with React DevTools, memo appropriately - **Accessibility Gaps**: Test with screen readers and keyboard navigation - **Bundle Size**: Tree-shake unused component variants --- Skills Agentes — https://skillsagentes.com/skills/wshobson/agents/web-component-design