feat. 버튼 액션별 아이콘 추가
This commit is contained in:
@@ -15,6 +15,10 @@
|
||||
after:bg-[var(--text-color)] after:opacity-20 after:z-[2];
|
||||
}
|
||||
|
||||
.btn-base .btn-content {
|
||||
@apply relative flex items-center gap-1 z-[1];
|
||||
}
|
||||
|
||||
.size-large {
|
||||
@apply px-10 h-16 text-lg;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { ButtonType } from '#layers/types/components/button'
|
||||
|
||||
interface ButtonProps {
|
||||
interface props {
|
||||
type?: ButtonType
|
||||
icon?: string
|
||||
target?: '_self' | '_blank'
|
||||
href?: string
|
||||
rel?: string
|
||||
@@ -11,35 +10,15 @@ interface ButtonProps {
|
||||
backgroundImage?: string
|
||||
textColor?: string
|
||||
disabled?: boolean
|
||||
class?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<ButtonProps>(), {
|
||||
const props = withDefaults(defineProps<props>(), {
|
||||
type: 'action',
|
||||
backgroundColor: 'var(--primary)',
|
||||
textColor: 'var(--alternative-02)',
|
||||
disabled: false,
|
||||
})
|
||||
|
||||
const buttonClasses = computed(() =>
|
||||
['btn-base group', props.class].filter(Boolean)
|
||||
)
|
||||
const buttonStyles = computed(() => {
|
||||
const styles: Record<string, string> = {
|
||||
backgroundColor: props.backgroundColor,
|
||||
color: props.textColor,
|
||||
'--text-color': props.textColor,
|
||||
}
|
||||
|
||||
if (props.backgroundImage) {
|
||||
styles.backgroundImage = `url(${props.backgroundImage})`
|
||||
styles.backgroundSize = 'contain'
|
||||
styles.backgroundPosition = 'center'
|
||||
styles.backgroundRepeat = 'no-repeat'
|
||||
}
|
||||
|
||||
return styles
|
||||
})
|
||||
const componentTag = computed((): string => {
|
||||
switch (props.type) {
|
||||
case 'download':
|
||||
@@ -72,18 +51,39 @@ const componentProps = computed(() => {
|
||||
|
||||
return baseProps
|
||||
})
|
||||
const buttonStyles = computed(() => {
|
||||
const styles: Record<string, string> = {
|
||||
backgroundColor: props.backgroundColor,
|
||||
color: props.textColor,
|
||||
}
|
||||
|
||||
if (props.backgroundImage) {
|
||||
styles.backgroundImage = `url(${props.backgroundImage})`
|
||||
styles.backgroundSize = 'contain'
|
||||
styles.backgroundPosition = 'center'
|
||||
styles.backgroundRepeat = 'no-repeat'
|
||||
}
|
||||
|
||||
return styles
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="componentTag"
|
||||
v-bind="componentProps"
|
||||
:class="buttonClasses"
|
||||
v-bind="{ ...componentProps, ...$attrs }"
|
||||
:class="['btn-base', $attrs?.class]"
|
||||
:style="buttonStyles"
|
||||
>
|
||||
<span class="relative flex items-center gap-2 z-[1]">
|
||||
<span class="btn-content">
|
||||
<slot />
|
||||
<span v-if="props.icon" class="flex-shrink-0" v-html="props.icon" />
|
||||
<AtomsIconsLongArrowRightLine v-if="props.type === 'internal'" />
|
||||
<AtomsIconsWebLinkLine
|
||||
v-if="props.type === 'external'"
|
||||
size="24"
|
||||
color="#ebebeb"
|
||||
/>
|
||||
<AtomsIconsDownloadLine v-if="props.type === 'download'" />
|
||||
</span>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
33
layers/components/atoms/icons/DownloadLine.vue
Normal file
33
layers/components/atoms/icons/DownloadLine.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
size?: number | string
|
||||
color?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: 24,
|
||||
color: '#EBEBEB',
|
||||
className: '',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
:width="size"
|
||||
:height="size"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
:class="className"
|
||||
>
|
||||
<path
|
||||
d="M10.75 3.25L10.75 12.2322L6.88391 8.36611C6.39576 7.87796 5.6043 7.87796 5.11615 8.36611C4.62799 8.85427 4.62799 9.64573 5.11615 10.1339L11.1161 16.1339C11.3506 16.3683 11.6685 16.5 12 16.5C12.3316 16.5 12.6495 16.3683 12.8839 16.1339L18.8839 10.1339C19.3721 9.64573 19.3721 8.85427 18.8839 8.36611C18.3958 7.87796 17.6043 7.87796 17.1161 8.36611L13.25 12.2322L13.25 3.25C13.25 2.55964 12.6904 2 12 2C11.3097 2 10.75 2.55964 10.75 3.25Z"
|
||||
:fill="color"
|
||||
/>
|
||||
<path
|
||||
d="M20 21C20.6904 21 21.25 20.4404 21.25 19.75L21.25 17.75C21.25 17.0596 20.6904 16.5 20 16.5C19.3097 16.5 18.75 17.0596 18.75 17.75L18.75 18.5L5.25003 18.5L5.25003 17.75C5.25003 17.0596 4.69039 16.5 4.00003 16.5C3.30967 16.5 2.75003 17.0596 2.75003 17.75L2.75003 19.75C2.75003 20.4404 3.30967 21 4.00003 21L20 21Z"
|
||||
:fill="color"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
29
layers/components/atoms/icons/LongArrowRightLine.vue
Normal file
29
layers/components/atoms/icons/LongArrowRightLine.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
size?: number | string
|
||||
color?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: 24,
|
||||
color: '#EBEBEB',
|
||||
className: '',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
:width="size"
|
||||
:height="size"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
:class="className"
|
||||
>
|
||||
<path
|
||||
d="M11.7929 18.2929C11.4024 18.6834 11.4024 19.3166 11.7929 19.7071C12.1834 20.0976 12.8166 20.0976 13.2071 19.7071L20.2071 12.7071C20.5976 12.3166 20.5976 11.6834 20.2071 11.2929L13.2071 4.29289C12.8166 3.90237 12.1834 3.90237 11.7929 4.29289C11.4024 4.68342 11.4024 5.31658 11.7929 5.70711L17.0858 11L4.5 11C3.94771 11 3.5 11.4477 3.5 12C3.5 12.5523 3.94771 13 4.5 13L17.0858 13L11.7929 18.2929Z"
|
||||
:fill="color"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -11,7 +11,6 @@ interface ButtonListProps {
|
||||
|
||||
const props = defineProps<ButtonListProps>()
|
||||
|
||||
// 상수 정의
|
||||
const BUTTON_TYPE_MAP = {
|
||||
URL: {
|
||||
_self: 'internal' as const,
|
||||
@@ -35,23 +34,6 @@ const getButtonType = (btnInfo: PageDataResourceGroupBtnInfo): ButtonType => {
|
||||
|
||||
return DEFAULT_BUTTON_TYPE
|
||||
}
|
||||
|
||||
const getButtonProps = (button: PageDataResourceGroup) => ({
|
||||
type: getButtonType(button.btn_info),
|
||||
target: button.btn_info?.detail?.action?.link_target,
|
||||
href: button.btn_info?.detail?.action?.url,
|
||||
rel: button.btn_info?.detail?.action?.rel,
|
||||
backgroundColor: getColorCode({
|
||||
colorName: button.btn_info?.color_name_btn,
|
||||
colorCode: button.btn_info?.color_code_btn,
|
||||
}),
|
||||
textColor: getColorCode({
|
||||
colorName: button.btn_info?.color_name_txt,
|
||||
colorCode: button.btn_info?.color_code_txt,
|
||||
}),
|
||||
disabled: button.btn_info?.disabled,
|
||||
text: button.btn_info?.txt_btn_name,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,7 +44,23 @@ const getButtonProps = (button: PageDataResourceGroup) => ({
|
||||
<AtomsButton
|
||||
v-for="(button, index) in props.resourcesData"
|
||||
:key="index"
|
||||
v-bind="getButtonProps(button)"
|
||||
:type="getButtonType(button.btn_info)"
|
||||
:target="button.btn_info?.detail?.action?.link_target"
|
||||
:href="button.btn_info?.detail?.action?.url"
|
||||
:rel="button.btn_info?.detail?.action?.rel"
|
||||
:background-color="
|
||||
getColorCode({
|
||||
colorName: button.btn_info?.color_name_btn,
|
||||
colorCode: button.btn_info?.color_code_btn,
|
||||
})
|
||||
"
|
||||
:text-color="
|
||||
getColorCode({
|
||||
colorName: button.btn_info?.color_name_txt,
|
||||
colorCode: button.btn_info?.color_code_txt,
|
||||
})
|
||||
"
|
||||
:disabled="button.btn_info?.disabled"
|
||||
class="size-extra-small md:size-medium"
|
||||
>
|
||||
{{ button.btn_info?.txt_btn_name }}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export type ButtonType = 'internal' | 'external' | 'download' | 'action'
|
||||
export type ButtonSize = 'large' | 'medium' | 'small' | 'extra-small'
|
||||
export type ButtonVariant = 'filled' | 'outlined'
|
||||
|
||||
Reference in New Issue
Block a user