2025-12-10 20:52:44 +08:00
|
|
|
<template>
|
|
|
|
|
<button
|
|
|
|
|
:class="triggerClass"
|
|
|
|
|
:data-state="isActive ? 'active' : 'inactive'"
|
|
|
|
|
:data-value="props.value"
|
|
|
|
|
type="button"
|
2025-12-12 16:15:07 +08:00
|
|
|
@click="handleClick"
|
2025-12-10 20:52:44 +08:00
|
|
|
>
|
|
|
|
|
<slot />
|
|
|
|
|
</button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { computed, inject, type Ref } from 'vue'
|
|
|
|
|
import { cn } from '@/lib/utils'
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
value: string
|
|
|
|
|
class?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
|
|
|
|
|
|
const activeTab = inject<Ref<string>>('activeTab')
|
|
|
|
|
const setActiveTab = inject<(value: string) => void>('setActiveTab')
|
|
|
|
|
|
|
|
|
|
const isActive = computed(() => activeTab?.value === props.value)
|
|
|
|
|
|
|
|
|
|
const handleClick = () => {
|
|
|
|
|
setActiveTab?.(props.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const triggerClass = computed(() => {
|
|
|
|
|
return cn(
|
|
|
|
|
'relative z-10 inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
|
|
|
|
isActive.value
|
|
|
|
|
? 'text-foreground font-semibold'
|
|
|
|
|
: 'text-muted-foreground hover:text-foreground',
|
|
|
|
|
props.class
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
</script>
|