feat: 쿠폰등록
This commit is contained in:
99
layers/components/atoms/Select.vue
Normal file
99
layers/components/atoms/Select.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
options: Array<any>
|
||||
labelName: string | number
|
||||
modelValue?: object
|
||||
placeholder?: string
|
||||
defaultLabel?: string
|
||||
placement?: string | 'top' | 'bottom'
|
||||
className?: string
|
||||
selectedColor?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: null,
|
||||
placeholder: null,
|
||||
defaultLabel: null,
|
||||
placement: 'bottom',
|
||||
className: '',
|
||||
selectedColor: '#333333',
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:modelValue'])
|
||||
|
||||
const isActive = ref(false)
|
||||
const isSelected = ref(props.defaultLabel !== null)
|
||||
const selectedOption = ref<string>(props.placeholder || props.defaultLabel)
|
||||
|
||||
const onToggleOpen = () => {
|
||||
isActive.value = !isActive.value
|
||||
}
|
||||
|
||||
const onSelectOption = (option: { [key: string | number]: any }): void => {
|
||||
isActive.value = false
|
||||
isSelected.value = true
|
||||
selectedOption.value = option[props.labelName]
|
||||
emits('update:modelValue', option)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full max-w-[432px]">
|
||||
<button
|
||||
type="button"
|
||||
class="relative flex items-center justify-between gap-[12px] w-full py-[12px] px-[16px] bg-white border border-solid border-[1px] border-[#D9D9D9] rounded-[8px]"
|
||||
@click="onToggleOpen"
|
||||
>
|
||||
<span
|
||||
class="inline-flex items-center justify-left text-left text-[14px] font-[400] leading-[20px] tracking-[-0.42px]"
|
||||
:class="isSelected ? 'text-[#333333]' : 'text-[#999999]'"
|
||||
>
|
||||
{{ selectedOption }}
|
||||
</span>
|
||||
<i
|
||||
class="inline-flex items-center justify-center w-[14px] h-[14px] shrink-0"
|
||||
>
|
||||
<AtomsIconsSelectArrowDownFill
|
||||
:size="12"
|
||||
color="#333333"
|
||||
:class="isActive ? 'rotate-180' : ''"
|
||||
/>
|
||||
</i>
|
||||
</button>
|
||||
<div
|
||||
v-if="isActive"
|
||||
:data-placement="props.placement"
|
||||
class="absolute z-[10] top-full left-0 translate-y-[4px] w-full py-[8px] border border-solid border-[1px] border-[rgba(0,0,0,0.3)] rounded-[8px] bg-white shadow-[0_4px_10px_0_rgba(0,0,0,0.10)]"
|
||||
>
|
||||
<ul class="relative flex flex-col items-center justify-start w-full">
|
||||
<li
|
||||
v-for="(option, index) in props.options"
|
||||
:key="String(option[props.labelName])"
|
||||
class="relative flex items-center justify-left w-full"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="relative flex items-center justify-left w-full py-[8px] pl-[40px] pr-[16px] bg-white text-left text-left text-[14px] font-[400] leading-[24px] tracking-[-0.42px] hover:bg-[rgba(0,0,0,0.04)]"
|
||||
:class="
|
||||
selectedColor ? `text-[${selectedColor}]` : 'text-[#333333]'
|
||||
"
|
||||
@click="onSelectOption(option)"
|
||||
>
|
||||
<template v-if="option[props.labelName] === selectedOption">
|
||||
<i
|
||||
class="absolute top-1/2 left-[12px] translate-y-[-50%] flex items-center justify-center w-[20px] h-[20px]"
|
||||
>
|
||||
<AtomsIconsCheckLine :size="16" :color="selectedColor" />
|
||||
</i>
|
||||
</template>
|
||||
<span>
|
||||
{{ option[props.labelName] }}
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user