add: select component

This commit is contained in:
Hakadao
2022-05-08 05:08:26 +08:00
parent cad077bea6
commit ce33767efc
2 changed files with 142 additions and 19 deletions

View File

@@ -0,0 +1,123 @@
<script lang="ts">
interface OptionType {
value: string
label: string
}
export default defineComponent({
props: {
modelValue: String,
options: Array as () => OptionType[],
},
emits: ['update:modelValue'],
data() {
return {
label: '' as string,
showOptions: false as boolean,
}
},
created() {
if (!this.options) return
this.label = `${this.options.find((item: OptionType) => item.value === this.modelValue)?.label}`
},
methods: {
onClickOption(val: {value: string; label: string}) {
window.removeEventListener('click', () => {})
this.label = val.label
this.$emit('update:modelValue', val.value)
this.showOptions = false
},
closeOptions() {
this.showOptions = false
},
/** when you click on it outside, the selection option will be turned off */
onMouseLeave() {
window.addEventListener('click', this.closeOptions)
},
onMouseEnter() {
window.removeEventListener('click', this.closeOptions)
},
},
})
</script>
<template>
<div
pos="relative"
w="full"
@mouseleave="onMouseLeave"
@mouseenter="onMouseEnter"
>
<div
p="x-4 y-2"
bg="$bew-fill-1"
rounded="$bew-radius"
text="center $bew-text-1"
cursor="pointer"
flex="~"
justify="between"
items="center"
@change="onChange"
@click="showOptions = !showOptions"
>
<div
text="space-nowrap overflow-ellipsis"
overflow="hidden"
m="r-2"
>
{{ label }}
</div>
<!-- arrow -->
<div
border="~ solid $bew-text-1 t-0 l-0 r-2 b-2"
p="3px"
m="l-2"
display="inline-block"
transform="~ rotate-45 -translate-y-1/4"
transition="all duration-300"
></div>
</div>
<transition>
<div
v-if="showOptions"
pos="absolute"
bg="$bew-content-1"
style="backdrop-filter: var(--bew-filter-glass); box-shadow: var(--bew-shadow-2);"
p="2"
m="t-2"
rounded="$bew-radius"
z="1"
w="full"
>
<div
v-for="option in options"
:key="option.value"
p="2"
m="not-last:b-1"
rounded="$bew-radius"
w="full"
bg="hover:$bew-fill-2"
transition="all duration-300"
cursor="pointer"
@click="onClickOption(option)"
>
{{ option.label }}
</div>
</div>
</transition>
</div>
</template>
<style lang="scss" scoped>
.v-enter-active,
.v-leave-active {
@apply transition-all duration-500;
}
.v-enter-from,
.v-leave-to {
@apply opacity-0 transform-gpu scale-95 -translate-y-4 filter blur-sm;
}
</style>

View File

@@ -4,7 +4,6 @@ import { language, isShowTopbar, accessKey } from '~/logic'
export default defineComponent({
emits: ['close'],
data() {
return {
isShowTopbar,
@@ -13,23 +12,28 @@ export default defineComponent({
langs: [
{
value: 'en',
label: 'settings.select_language_opt.english',
label: this.$t('settings.select_language_opt.english'),
},
{
value: 'cmn-SC',
label: 'settings.select_language_opt.mandarin_sc',
label: this.$t('settings.select_language_opt.mandarin_sc'),
},
{
value: 'cmn-TC',
label: 'settings.select_language_opt.mandarin_tc',
label: this.$t('settings.select_language_opt.mandarin_tc'),
},
{
value: 'jyut',
label: 'settings.select_language_opt.jyut',
label: this.$t('settings.select_language_opt.jyut'),
},
],
}
},
watch: {
language() {
this.$i18n.locale = this.language
},
},
methods: {
close() {
this.$emit('close')
@@ -41,9 +45,6 @@ export default defineComponent({
onRevoke() {
revokeAccessKey()
},
onChangeLocale() {
this.$i18n.locale = language.value
},
},
})
</script>
@@ -75,18 +76,13 @@ export default defineComponent({
<div>
{{ $t('settings.select_language') }}
</div>
<select
<bew-select
v-model="language"
@change="onChangeLocale()"
:options="langs"
w="full"
>
<option
v-for="lang in langs"
:key="lang.value"
:value="lang.value"
>
{{ $t(lang.label) }}
</option>
</select>
</bew-select>
</div>
<div class="settings-item">
@@ -140,7 +136,11 @@ export default defineComponent({
}
> *:first-child {
@apply w-4/5 mr-4;
@apply w-5/7 mr-4;
}
> *:last-child {
@apply w-2/7;
}
}
}