Claude-skill-registry frontend
프론트엔드 개발 스킬. React 컴포넌트, 커스텀 훅, Tailwind 스타일링. UI 작업 시 사용.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/frontend-mag123c-linkhub" ~/.claude/skills/majiayu000-claude-skill-registry-frontend && rm -rf "$T"
manifest:
skills/data/frontend-mag123c-linkhub/SKILL.mdsource content
Frontend Skill
Chrome Extension UI 구조
Popup (주요 UI)
src/popup/ ├── Popup.tsx # 메인 엔트리 ├── components/ │ ├── LinkCard.tsx # 링크 카드 컴포넌트 │ ├── TagFilter.tsx # 태그 필터 UI │ ├── SearchBar.tsx # 검색 바 │ └── LinkList.tsx # 링크 목록 └── hooks/ ├── useLinks.ts # 링크 CRUD 훅 ├── useTags.ts # 태그 관리 훅 └── useSearch.ts # 검색 훅
Options Page (설정)
src/options/ ├── Options.tsx # 설정 페이지 엔트리 └── components/ ├── ExportImport.tsx └── ThemeSelector.tsx
컴포넌트 규칙
함수형 컴포넌트만 사용
// Good export function LinkCard({ link, onDelete }: LinkCardProps) { return ( <div className="p-4 border rounded-lg"> {/* ... */} </div> ); } // Bad - 클래스 컴포넌트 class LinkCard extends React.Component { }
Props 타입 정의
interface LinkCardProps { link: Link; onDelete: (id: string) => void; onTagClick?: (tag: string) => void; }
커스텀 훅 패턴
// useLinks.ts export function useLinks() { const [links, setLinks] = useState<Link[]>([]); const [loading, setLoading] = useState(true); useEffect(() => { loadLinks(); }, []); async function loadLinks() { setLoading(true); const data = await getLinks(); setLinks(data); setLoading(false); } async function addLink(input: CreateLinkInput) { const newLink = createLink(input); await saveLink(newLink); setLinks(prev => [...prev, newLink]); } return { links, loading, addLink, /* ... */ }; }
Tailwind CSS 규칙
유틸리티 클래스 우선
// Good - Tailwind 유틸리티 <div className="flex items-center gap-2 p-4 bg-white rounded-lg shadow"> // Avoid - 커스텀 CSS <div className="link-card">
반응형 디자인
// Popup 크기 고려 (400px width 기준) <div className="w-full max-w-[400px]">
다크 모드 지원
<div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100">
에러 핸들링
로딩/에러 상태 표시
function LinkList() { const { links, loading, error } = useLinks(); if (loading) return <Spinner />; if (error) return <ErrorMessage message={error} />; if (links.length === 0) return <EmptyState />; return ( <div className="space-y-2"> {links.map(link => ( <LinkCard key={link.id} link={link} /> ))} </div> ); }
접근성 (A11y)
기본 규칙
- 버튼에
제공 (아이콘만 있는 경우)aria-label - 포커스 상태 표시 (
)focus:ring-2 - 시맨틱 HTML 사용 (
,<button>
,<nav>
)<main>
<button aria-label="Delete link" onClick={handleDelete} className="p-2 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 rounded" > <TrashIcon className="w-4 h-4" /> </button>
체크리스트
- 함수형 컴포넌트 사용
- Props 타입 정의
- 로딩/에러 상태 처리
- Tailwind 유틸리티 사용
- 접근성 고려
- 다크 모드 지원
상세 패턴은 코드베이스의 기존 구현 참조