feat. GR_VISUAL_03 컴포넌트 제작

This commit is contained in:
clkim
2025-09-19 14:43:21 +09:00
parent 792111f47b
commit 81bcca8e23
14 changed files with 277 additions and 154 deletions

View File

@@ -1,13 +1,14 @@
<script setup lang="ts">
import type {
ButtonSize,
ButtonConfig,
ButtonProps,
} from '#layers/types/components/button'
import type { GameDataKeyCodeCodes } from '#layers/types/api/gameData'
interface ButtonProps {
backgroundColor?: string
textColor?: string
icon?: string
disabled?: boolean
}
const props = withDefaults(defineProps<ButtonProps>(), {
size: 'medium',
backgroundColor: 'var(--primary)',
textColor: 'var(--alternative-02)',
icon: '',
@@ -23,63 +24,36 @@ const PARSED_KEY_CODE_CODES_KEYS: (keyof GameDataKeyCodeCodes)[] = [
'alternative-02',
]
// 버튼 크기별 설정 상수
const BUTTON_CONFIGS: Record<ButtonSize, 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
// 색상 값을 CSS 변수로 변환하는 헬퍼 함수
const getColorValue = (color: string) =>
PARSED_KEY_CODE_CODES_KEYS.includes(color as keyof GameDataKeyCodeCodes)
? `var(--${color})`
: color
const currentConfig = computed(() => BUTTON_CONFIGS[props.size])
const buttonClasses = computed(() => [
'group relative inline-flex items-center justify-center font-medium border border-gray-600/30 overflow-hidden',
`${currentConfig.value.padding} ${currentConfig.value.height} ${currentConfig.value.text} ${currentConfig.value.rounded}`,
'btn-base group relative inline-flex items-center justify-center font-medium border border-gray-600/30 overflow-hidden',
props.disabled ? 'cursor-default' : 'cursor-pointer',
])
const buttonStyles = computed(() => ({
backgroundColor: getColorValue(props.backgroundColor),
color: getColorValue(props.textColor),
}))
const overlayClasses = computed(() => [
'absolute inset-0 -m-px transition-opacity duration-200',
props.disabled
? 'opacity-20 z-10'
: 'bg-white opacity-0 group-hover:opacity-20',
currentConfig.value.rounded,
])
const overlayDisabledStyles = computed(
() =>
props.disabled && {
backgroundColor: props.textColor,
}
)
const contentDisabledStyles = computed(() => props.disabled && { opacity: 0.2 })
</script>

View File

@@ -72,7 +72,7 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits<Emits>()
// YouTube URL을 임베드 가능한 형태로 변환
// [TODO] YouTube URL을 임베드 가능한 형태로 변환
const embedUrl = computed(() => {
if (!props.youtubeUrl) return ''

View File

@@ -65,6 +65,7 @@ watchEffect(() => {
<component
:is="registry[template.template_code]?.component"
:components="template.components"
:page-ver-tmpl-seq="template.page_ver_tmpl_seq"
/>
</template>
</main>