mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
add: select component
This commit is contained in:
123
src/components/BewSelect.vue
Normal file
123
src/components/BewSelect.vue
Normal 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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user