fix. 버튼 컴포넌트 수정
This commit is contained in:
@@ -1,50 +1,123 @@
|
||||
<script setup lang="ts">
|
||||
type ButtonSize = 'large' | 'medium' | 'small' | 'extra-small'
|
||||
type ButtonVariant = 'primary' | 'secondary'
|
||||
|
||||
interface Props {
|
||||
size?: 'large' | 'medium' | 'small' | 'extra-small'
|
||||
size?: ButtonSize
|
||||
variant?: ButtonVariant
|
||||
disabled?: boolean
|
||||
icon?: string
|
||||
backgroundColor?: string
|
||||
textColor?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'medium',
|
||||
variant: 'primary',
|
||||
disabled: false,
|
||||
icon: '',
|
||||
backgroundColor: '',
|
||||
textColor: '',
|
||||
})
|
||||
|
||||
// 크기별 스타일 클래스
|
||||
const sizeClasses = {
|
||||
large: 'px-10 h-16 text-lg rounded-lg',
|
||||
medium: 'px-10 h-14 text-base rounded-lg',
|
||||
small: 'px-10 h-12 text-sm rounded-lg',
|
||||
'extra-small': 'px-6 h-10 text-sm rounded',
|
||||
const attrs = useAttrs()
|
||||
|
||||
// 버튼 크기별 설정
|
||||
const buttonConfig = {
|
||||
large: {
|
||||
padding: 'px-10',
|
||||
height: 'h-16',
|
||||
text: 'text-lg',
|
||||
rounded: 'rounded-lg',
|
||||
},
|
||||
medium: {
|
||||
padding: 'px-10',
|
||||
height: 'h-14',
|
||||
text: 'text-base',
|
||||
rounded: 'rounded-lg',
|
||||
},
|
||||
small: {
|
||||
padding: 'px-10',
|
||||
height: 'h-12',
|
||||
text: 'text-sm',
|
||||
rounded: 'rounded-lg',
|
||||
},
|
||||
'extra-small': {
|
||||
padding: 'px-6',
|
||||
height: 'h-10',
|
||||
text: 'text-sm',
|
||||
rounded: 'rounded',
|
||||
},
|
||||
} as const
|
||||
|
||||
// 버튼 변형별 기본 스타일
|
||||
const variantStyles = {
|
||||
primary: 'bg-game-primary text-game-text-primary',
|
||||
secondary: 'bg-[rgba(255, 255, 255, 0.5)] text-white',
|
||||
} as const
|
||||
|
||||
// 크기별 클래스 생성
|
||||
const getSizeClasses = (size: ButtonSize) => {
|
||||
const config = buttonConfig[size]
|
||||
return `${config.padding} ${config.height} ${config.text} ${config.rounded}`
|
||||
}
|
||||
|
||||
// 상태별 스타일 클래스
|
||||
// 상태별 클래스 생성
|
||||
const getStateClasses = (disabled: boolean) => {
|
||||
if (disabled) {
|
||||
return 'bg-white/10 text-gray-400 cursor-not-allowed'
|
||||
}
|
||||
return 'cursor-pointer'
|
||||
}
|
||||
|
||||
return 'bg-gray-700 text-white cursor-pointer'
|
||||
// 호버 효과 클래스 생성
|
||||
const getHoverEffectClasses = (
|
||||
size: ButtonSize,
|
||||
disabled: boolean,
|
||||
variant: ButtonVariant
|
||||
) => {
|
||||
const config = buttonConfig[size]
|
||||
if (disabled) {
|
||||
// disabled 상태에서 variant에 따라 다른 오버레이 색상
|
||||
const overlayColor = variant === 'primary' ? 'bg-black' : 'bg-white'
|
||||
return `absolute inset-0 -m-px ${overlayColor} opacity-20 transition-opacity duration-200 z-10 ${config.rounded}`
|
||||
}
|
||||
return `absolute inset-0 -m-px bg-white opacity-0 group-hover:opacity-20 transition-opacity duration-200 ${config.rounded}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:class="[
|
||||
'group relative inline-flex items-center font-medium transition-all duration-200 border border-gray-600/30 overflow-hidden',
|
||||
sizeClasses[size],
|
||||
// 기본 스타일
|
||||
'group relative inline-flex items-center justify-center font-medium transition-all duration-200 border border-gray-600/30 overflow-hidden',
|
||||
// 크기별 스타일
|
||||
getSizeClasses(props.size),
|
||||
// 변형별 스타일 (disabled 상태가 아닐 때만 적용, 커스텀 색상이 없을 때만)
|
||||
!props.disabled && !props.backgroundColor
|
||||
? variantStyles[props.variant]
|
||||
: '',
|
||||
// 상태별 스타일
|
||||
getStateClasses(props.disabled),
|
||||
// 외부 클래스 (최우선 적용)
|
||||
attrs.class,
|
||||
]"
|
||||
:disabled="disabled"
|
||||
:style="{
|
||||
backgroundColor: props.backgroundColor || undefined,
|
||||
color: props.textColor || undefined,
|
||||
}"
|
||||
:disabled="props.disabled"
|
||||
v-bind="attrs"
|
||||
>
|
||||
<!-- 호버 효과 / Disabled 오버레이 -->
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="absolute inset-0 bg-white opacity-0 group-hover:opacity-20 transition-opacity duration-200 rounded-inherit"
|
||||
:class="getHoverEffectClasses(props.size, props.disabled, props.variant)"
|
||||
/>
|
||||
<span class="relative">
|
||||
|
||||
<!-- 버튼 내용 -->
|
||||
<span class="relative flex items-center gap-2 z-20">
|
||||
<slot />
|
||||
<span v-if="icon" :class="['flex-shrink-0']" v-html="icon" />
|
||||
<span v-if="props.icon" class="flex-shrink-0" v-html="props.icon" />
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -18,13 +18,14 @@ const resourcesData = computed(() => {
|
||||
|
||||
<template>
|
||||
<template v-if="resourcesData">
|
||||
<AtomsButton v-for="button in resourcesData" :key="button.group_label">
|
||||
<AtomsButton
|
||||
v-for="button in resourcesData"
|
||||
:key="button.group_label"
|
||||
:background-color="button.btn_info?.color_code_btn"
|
||||
:text-color="button.btn_info?.color_code_txt"
|
||||
:disabled="button.btn_info?.disabled"
|
||||
>
|
||||
{{ button.btn_info?.txt_btn_name }}
|
||||
</AtomsButton>
|
||||
|
||||
<!-- :style="{
|
||||
backgroundColor: button.btn_info?.color_code_btn,
|
||||
color: button.btn_info?.color_code_txt,
|
||||
}" -->
|
||||
</template>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user