feat: 로그인 화면
This commit is contained in:
20
src/shared/lib/colors.ts
Normal file
20
src/shared/lib/colors.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* VibeRoom 공통 색상 팔레트 (JS/TS 환경용)
|
||||
*
|
||||
* Tailwind CSS(globals.css)에 정의된 색상과 동일한 값을 가집니다.
|
||||
* 이 파일은 Tailwind 클래스를 사용할 수 없는 곳(Canvas, Three.js 3D 객체, 차트 라이브러리 등)이나
|
||||
* JS 로직 내에서 색상 코드가 직접 필요할 때 사용합니다.
|
||||
*/
|
||||
export const colors = {
|
||||
brand: {
|
||||
primary: '#63adf2', // 소프트 코발트 (핵심 액션, 포인트)
|
||||
dark: '#304d6d', // 딥 네이비 (메인 텍스트, 무게감 있는 배경)
|
||||
soft: '#a7cced', // 파스텔 스카이 (은은한 배경, 호버/체크마크)
|
||||
},
|
||||
base: {
|
||||
background: '#f8fafc', // slate-50 (서비스 기본 배경)
|
||||
white: '#ffffff',
|
||||
}
|
||||
} as const;
|
||||
|
||||
export type BrandColor = keyof typeof colors.brand;
|
||||
65
src/shared/ui/Button.tsx
Normal file
65
src/shared/ui/Button.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import React, { ButtonHTMLAttributes } from 'react';
|
||||
import Link, { LinkProps } from 'next/link';
|
||||
|
||||
// 1. 버튼 Variant(스타일) 및 Size 타입 정의
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
|
||||
export type ButtonSize = 'sm' | 'md' | 'lg' | 'full';
|
||||
|
||||
// 2. 공통 Props 인터페이스 정의 (HTML 버튼 속성 + Link 속성 혼합)
|
||||
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
href?: string; // href가 주어지면 Next.js Link 컴포넌트로 렌더링
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* VibeRoom 공통 버튼 컴포넌트
|
||||
* (3-Color System 엄격 적용: #304d6d, #63adf2, #a7cced)
|
||||
*/
|
||||
export const Button = React.forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonProps>(
|
||||
(
|
||||
{ variant = 'primary', size = 'md', href, className = '', children, ...props },
|
||||
ref
|
||||
) => {
|
||||
// 공통 베이스 스타일
|
||||
const baseStyle = "inline-flex items-center justify-center font-bold rounded-xl transition-all duration-200";
|
||||
|
||||
// Variant별 테마 (VibeRoom 3-Color System)
|
||||
const variants: Record<ButtonVariant, string> = {
|
||||
primary: "bg-brand-primary text-white hover:bg-brand-primary/90 shadow-sm",
|
||||
secondary: "bg-slate-50 text-brand-dark hover:bg-slate-100",
|
||||
outline: "bg-white/50 text-brand-dark border border-brand-dark/20 hover:bg-white shadow-sm",
|
||||
ghost: "bg-transparent text-brand-dark/80 hover:text-brand-primary",
|
||||
};
|
||||
|
||||
// 크기별 테마
|
||||
const sizes: Record<ButtonSize, string> = {
|
||||
sm: "px-4 py-2 text-sm",
|
||||
md: "px-5 py-2.5 text-base",
|
||||
lg: "px-8 py-4 text-lg",
|
||||
full: "w-full py-3 px-4 text-base",
|
||||
};
|
||||
|
||||
const combinedClassName = `${baseStyle} ${variants[variant]} ${sizes[size]} ${className}`;
|
||||
|
||||
// href 속성이 있으면 Next.js Link로 렌더링
|
||||
if (href) {
|
||||
return (
|
||||
<Link href={href} className={combinedClassName} ref={ref as React.Ref<HTMLAnchorElement>}>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// 기본은 HTML Button
|
||||
return (
|
||||
<button className={combinedClassName} ref={ref as React.Ref<HTMLButtonElement>} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Button.displayName = 'Button';
|
||||
Reference in New Issue
Block a user