본문으로 건너뛰기
cccskills
무료GitHub에 공개

web-component-design

Design reusable interface components in React, Vue, and Svelte. Organize how components fit together, define clear configuration options, and choose styling approaches while addressing accessibility, responsive layouts, and maintenance across component libraries or design systems.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

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.

설치 방법 보기

이럴 때 유용합니다

  • Build a reusable UI component library
  • Standardize component options across a design system
  • Refactor complex existing components
  • Improve keyboard access and responsive component layouts

포함된 파일(4)

  • SKILL.md7.3 KB
  • references/accessibility-patterns.md15.5 KB
  • references/component-patterns.md9.5 KB
  • references/css-styling-approaches.md12.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

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

// Usage
<Select value={value} onChange={setValue}>
  <Select.Trigger>Choose option</Select.Trigger>
  <Select.Options>
    <Select.Option value="a">Option A</Select.Option>
    <Select.Option value="b">Option B</Select.Option>
  </Select.Options>
</Select>

Render Props: Delegate rendering to parent

<DataFetcher url="/api/users">
  {({ data, loading, error }) =>
    loading ? <Spinner /> : <UserList users={data} />
  }
</DataFetcher>

Slots (Vue/Svelte): Named content injection points

<template>
  <Card>
    <template #header>Title</template>
    <template #content>Body text</template>
    <template #footer><Button>Action</Button></template>
  </Card>
</template>

2. CSS-in-JS Approaches

SolutionApproachBest For
Tailwind CSSUtility classesRapid prototyping, design systems
CSS ModulesScoped CSS filesExisting CSS, gradual adoption
styled-componentsTemplate literalsReact, dynamic styling
EmotionObject/template stylesFlexible, SSR-friendly
Vanilla ExtractZero-runtimePerformance-critical apps

3. Component API Design

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

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<typeof buttonVariants> {
  isLoading?: boolean;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, isLoading, children, ...props }, ref) => (
    <button
      ref={ref}
      className={cn(buttonVariants({ variant, size }), className)}
      disabled={isLoading || props.disabled}
      {...props}
    >
      {isLoading && <Spinner className="mr-2 h-4 w-4" />}
      {children}
    </button>
  ),
);
Button.displayName = "Button";

Framework Patterns

React: Compound Components

import { createContext, useContext, useState, type ReactNode } from "react";

interface AccordionContextValue {
  openItems: Set<string>;
  toggle: (id: string) => void;
}

const AccordionContext = createContext<AccordionContextValue | null>(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<Set<string>>(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 (
    <AccordionContext.Provider value={{ openItems, toggle }}>
      <div className="divide-y">{children}</div>
    </AccordionContext.Provider>
  );
}

Accordion.Item = function AccordionItem({
  id,
  title,
  children,
}: {
  id: string;
  title: string;
  children: ReactNode;
}) {
  const { openItems, toggle } = useAccordion();
  const isOpen = openItems.has(id);

  return (
    <div>
      <button onClick={() => toggle(id)} className="w-full text-left py-3">
        {title}
      </button>
      {isOpen && <div className="pb-3">{children}</div>}
    </div>
  );
};

Vue 3: Composables

<script setup lang="ts">
import { ref, computed, provide, inject, type InjectionKey } from "vue";

interface TabsContext {
  activeTab: Ref<string>;
  setActive: (id: string) => void;
}

const TabsKey: InjectionKey<TabsContext> = Symbol("tabs");

// Parent component
const activeTab = ref("tab-1");
provide(TabsKey, {
  activeTab,
  setActive: (id: string) => {
    activeTab.value = id;
  },
});

// Child component usage
const tabs = inject(TabsKey);
const isActive = computed(() => tabs?.activeTab.value === props.id);
</script>

Svelte 5: Runes

<script lang="ts">
  interface Props {
    variant?: 'primary' | 'secondary';
    size?: 'sm' | 'md' | 'lg';
    onclick?: () => void;
    children: import('svelte').Snippet;
  }

  let { variant = 'primary', size = 'md', onclick, children }: Props = $props();

  const classes = $derived(
    `btn btn-${variant} btn-${size}`
  );
</script>

<button class={classes} {onclick}>
  {@render children()}
</button>

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

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Build and review interfaces against WCAG 2.2 accessibility guidelines. Covers keyboard navigation, screen readers that read interface content aloud, accessible forms, mobile support, and display preferences, helping identify and fix barriers to using a website or app.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Audit an interface for accessibility issues
  • Add keyboard navigation and focus management
  • Improve screen reader support for forms
wshobson/agents4.1만2026년 10월 19일 업데이트

Review AI-generated code for problems hidden behind successful runs. Check failure handling, resource cleanup, unusual inputs, nonexistent dependencies, and departures from project conventions to identify missing safeguards before merging or accepting the work as complete.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Audit code after an AI generation session
  • Review an AI-generated pull request before merging
  • Investigate brittle code that appears to work
wshobson/agents4.1만2026년 10월 19일 업데이트

Build Apache Airflow workflows for data pipelines and scheduled jobs. The skill guides task dependencies, retries, waiting for conditions, testing, and deployment, with patterns for tasks that can be safely rerun.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Building scheduled data pipelines
  • Designing task order and dependencies
  • Implementing custom tasks and condition checks
wshobson/agents4.1만2026년 10월 19일 업데이트

Plan and carry out an AngularJS to Angular migration, from choosing a rewrite strategy to converting components, services, and routes. Includes a hybrid approach that runs both frameworks together while individual features are migrated.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Planning an AngularJS to Angular migration
  • Moving a large app one feature at a time
  • Converting directives into Angular components
wshobson/agents4.1만2026년 10월 19일 업데이트

Identify software protections that hinder inspection, such as debugger detection and obfuscation that makes code harder to understand. Support authorized binary analysis and CTF security challenges with protection findings, bypass strategies, reports, and analysis scripts.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Identify protections in an authorized malware sample
  • Plan analysis of a packed executable
  • Implement debugger detection for a CTF challenge
wshobson/agents4.1만2026년 10월 19일 업데이트

Design and review REST and GraphQL APIs with consistent naming, data structures, error responses, pagination for large result sets, and versioning strategies. Helps teams define shared standards and plan changes that existing clients can adopt gradually.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Designing a new REST or GraphQL API
  • Reviewing API specifications before implementation
  • Establishing shared API design standards
wshobson/agents4.1만2026년 10월 19일 업데이트

wshobson의 스킬 모두 보기

이 스킬의 문제 신고