generated from ttipo/project-base
Initial commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
// 공통 버튼 컴포넌트 — 모든 재사용 컴포넌트의 기준 패턴
|
||||
// (타입 지정 Props/Emits, scoped 스타일, rem 단위, 기본 접근성 속성)
|
||||
// 사용 예: <BaseButton label="저장" variant="primary" @click="onSave" />
|
||||
|
||||
// Props 정의
|
||||
interface Props {
|
||||
// 버튼 라벨 (접근성 aria-label 로도 사용)
|
||||
label: string
|
||||
// 시각 변형
|
||||
variant?: 'primary' | 'secondary'
|
||||
// 비활성화 여부
|
||||
disabled?: boolean
|
||||
// 네이티브 button type
|
||||
type?: 'button' | 'submit'
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
variant: 'primary',
|
||||
disabled: false,
|
||||
type: 'button',
|
||||
})
|
||||
|
||||
// Emits 정의
|
||||
interface Emits {
|
||||
// 클릭 이벤트
|
||||
(e: 'click', event: MouseEvent): void
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
// 클릭 핸들러 — 비활성화 상태에서는 이벤트를 전파하지 않음
|
||||
function handleClick(event: MouseEvent) {
|
||||
if (props.disabled) return
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
:class="['base-button', `base-button--${variant}`]"
|
||||
:disabled="disabled"
|
||||
:aria-label="label"
|
||||
:aria-disabled="disabled"
|
||||
@click="handleClick"
|
||||
>
|
||||
{{ label }}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 모든 치수는 rem 기준 (16px = 1rem) */
|
||||
.base-button {
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.base-button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.base-button--primary {
|
||||
background-color: #4f46e5;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.base-button--secondary {
|
||||
background-color: #e5e7eb;
|
||||
color: #111827;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user