50 lines
1.0 KiB
Vue
50 lines
1.0 KiB
Vue
<script lang="ts">
|
|
export interface NavTertiaryItem {
|
|
label: string
|
|
to?: string
|
|
component?: string | Component
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts" setup>
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
navs: NavTertiaryItem[]
|
|
modelValue?: number
|
|
}>(),
|
|
{
|
|
modelValue: 0,
|
|
},
|
|
)
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', idx: number): void
|
|
}>()
|
|
|
|
const isActiveItem = (idx: number) => {
|
|
return props.modelValue === idx
|
|
}
|
|
|
|
const onClickItem = (idx: number) => {
|
|
emit('update:modelValue', idx)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col gap-2">
|
|
<div
|
|
v-for="(nav, i) in navs"
|
|
:key="i"
|
|
class="flex justify-center items-center gap-2 p-2.5 rounded-sm cursor-pointer select-none transition-colors duration-75"
|
|
:class="`${isActiveItem(i) ? 'bg-primary text-primary-foreground' : 'bg-accent text-foreground'}`"
|
|
@click="onClickItem(i)"
|
|
>
|
|
<span class="text-sm font-medium">
|
|
{{ nav.label }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped></style>
|