Files
web-temp/layers/components/blocks/VisualContent.vue
2025-09-18 20:08:41 +09:00

88 lines
2.1 KiB
Vue

<script setup lang="ts">
import { getResponsiveSrc } from '#layers/utils/dataUtil'
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
interface Props {
resourcesData?: PageDataResourceGroup
}
const props = defineProps<Props>()
// 텍스트 데이터 추출
// [TODO] txt 대신 text 사용
const displayText = computed(() => {
return props.resourcesData?.display?.txt || ''
})
// 이미지 소스 추출
const imageSrc = computed(() => {
return getResponsiveSrc(props.resourcesData?.res_path)
})
// 색상 코드 추출 (우선순위: color_code_txt > color_code)
const colorCode = computed(() => {
return (
props.resourcesData?.display?.color_code_txt ||
props.resourcesData?.display?.color_code
)
})
// 색상 이름 추출 (우선순위: color_name_txt > color_name)
const colorName = computed(() => {
return (
props.resourcesData?.display?.color_name_txt ||
props.resourcesData?.display?.color_name
)
})
// 색상 스타일 계산
const textStyles = computed(() => {
const styles: Record<string, string> = {}
if (colorName.value) {
styles.color = `var(--${colorName.value})`
} else if (colorCode.value) {
styles.color = colorCode.value
}
return styles
})
// HTML 콘텐츠 정리 (줄바꿈 처리)
const sanitizedContent = computed(() => {
return displayText.value?.replace(/\n/g, '<br/>') || ''
})
// 이미지가 있는지 확인
const hasImage = computed(() => {
return imageSrc.value && (imageSrc.value.mobileSrc || imageSrc.value.pcSrc)
})
</script>
<template>
<!-- 이미지가 있는 경우 -->
<template v-if="hasImage">
<!-- 모바일 이미지 (sm 미만) -->
<img
v-if="imageSrc.mobileSrc"
:src="imageSrc.mobileSrc"
:alt="displayText"
class="sm:hidden w-full h-full object-contain"
/>
<!-- PC 이미지 (sm 이상) -->
<img
v-if="imageSrc.pcSrc"
:src="imageSrc.pcSrc"
:alt="displayText"
class="hidden sm:block w-full h-full object-contain"
/>
</template>
<!-- 텍스트가 있는 경우 -->
<span
v-else-if="displayText"
v-dompurify-html="sanitizedContent"
:style="textStyles"
/>
</template>