16bd2cb92a
- 모노레포 구조 (Turborepo + pnpm): @relink/domain, @relink/shared, @relink/infrastructure, @relink/database, @relink/web - 도메인 레이어: 매장(store), 매칭(matching), 업체(vendor), 보조금(subsidy), 계약/에스크로(contract) TDD 완료 (158 단위 테스트) - 서비스 레이어: 전 도메인 서비스 함수 + 통합 테스트 (58 테스트) - 프론트엔드: Next.js 15 App Router, 13개 페이지 (사용자 6 + 관리자 7) - 인프라: PostgreSQL 16 + PostGIS, Prisma ORM, Docker Compose, AuditLog + OutboxEvent 패턴 - .env 파일 포함 (로컬 개발 기본값만 포함, 실제 시크릿 없음) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import type { ButtonHTMLAttributes } from 'react';
|
|
|
|
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
readonly variant?: 'primary' | 'secondary' | 'outline';
|
|
readonly size?: 'sm' | 'md' | 'lg';
|
|
}
|
|
|
|
export function Button({
|
|
variant = 'primary',
|
|
size = 'md',
|
|
className = '',
|
|
children,
|
|
...props
|
|
}: ButtonProps) {
|
|
const baseClasses = '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';
|
|
|
|
const variantClasses = {
|
|
primary: 'bg-blue-600 text-white hover:bg-blue-700',
|
|
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
|
|
outline: 'border border-gray-300 bg-transparent hover:bg-gray-100',
|
|
};
|
|
|
|
const sizeClasses = {
|
|
sm: 'h-8 px-3 text-sm',
|
|
md: 'h-10 px-4 text-sm',
|
|
lg: 'h-12 px-6 text-base',
|
|
};
|
|
|
|
return (
|
|
<button
|
|
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</button>
|
|
);
|
|
}
|