lx-music-desktop/src/renderer/components/base/Tab.vue
2023-08-07 18:49:14 +08:00

121 lines
2.2 KiB
Vue

<template>
<ul :class="[$style.list, $style[align]]" role="tablist">
<li
v-for="item in list"
:key="item[itemKey]" :class="[$style.listItem, {[$style.active]: modelValue == item[itemKey]}]" tabindex="-1" role="tab"
:aria-label="item[itemLabel]" ignore-tip :aria-selected="modelValue == item[itemKey]" @click="handleToggle(item[itemKey])"
>
<span :class="$style.label">{{ item[itemLabel] }}</span>
</li>
</ul>
</template>
<script>
export default {
props: {
list: {
type: Array,
default() {
return []
},
},
align: {
type: String,
default: 'left',
},
itemKey: {
type: String,
default: 'id',
},
itemLabel: {
type: String,
default: 'label',
},
modelValue: {
type: [String, Number],
default: '',
},
},
emits: ['update:modelValue', 'change'],
setup(props, { emit }) {
const handleToggle = id => {
if (id == props.modelValue) return
emit('update:modelValue', id)
emit('change', id)
}
return {
handleToggle,
}
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.list {
display: flex;
flex-flow: row nowrap;
font-size: 12px;
gap: 25px;
padding: 0 15px;
&.left {
justify-content: flex-start;
}
&.center {
justify-content: center;
}
&.right {
justify-content: flex-end;
}
}
.listItem {
display: block;
// padding: 5px 15px;
cursor: pointer;
transition: color @transition-normal;
&:hover {
color: var(--color-primary);
}
&.active {
color: var(--color-primary);
cursor: default;
>.label {
&:after {
// background-color: var(--color-primary);
opacity: 1;
transform: translateY(0);
}
}
}
}
.label {
display: block;
position: relative;
padding: 8px 0;
&:after {
.mixin-after;
left: 0;
bottom: 0;
width: 100%;
height: 2px;
border-radius: 20px;
background-color: transparent;
transform: translateY(-4px);
opacity: 0;
background-color: var(--color-primary-alpha-300);
transition: @transition-fast;
transition-property: transform, opacity;
}
}
</style>