前端代码

This commit is contained in:
2026-08-13 22:35:13 +08:00
parent 9044bafdff
commit f1a0b17bb0
412 changed files with 36769 additions and 6617 deletions
@@ -0,0 +1,110 @@
<template>
<div class="grid grid-cols-3 gap-3 px-1">
<div
v-for="item in tabModes"
:key="item.value"
class="relative flex flex-col items-center gap-1.5 p-1.5 bg-container border rounded-lg cursor-pointer transition-colors duration-150 ease-in-out hover:border-primary"
:class="modelValue === item.value ? '' : 'border-border'"
:style="
modelValue === item.value
? { borderColor: primaryColor, boxShadow: `0 0 0 1px ${primaryColor}` }
: {}
"
:title="item.label"
@click="handleChange(item.value)"
>
<!-- 默认风格:扁平药丸 + 短竖线分隔,选中项主色弱底 -->
<div
v-if="item.value === 'button'"
class="flex h-9 w-full items-center gap-1 overflow-hidden rounded bg-white px-1.5 dark:bg-gray-800"
>
<span class="h-4 w-9 rounded" :style="{ backgroundColor: primarySoft }" />
<span class="h-3 w-px bg-gray-200 dark:bg-gray-600" />
<span class="h-4 w-9 rounded bg-gray-100 dark:bg-gray-700" />
<span class="h-3 w-px bg-gray-200 dark:bg-gray-600" />
<span class="h-4 w-7 rounded bg-gray-100 dark:bg-gray-700" />
</div>
<!-- Chrome 风格:交叠标签,选中项抬升 + 主色弱底 -->
<div
v-else-if="item.value === 'chrome'"
class="flex h-9 w-full items-end overflow-hidden rounded bg-gray-100 px-1 dark:bg-gray-800"
>
<span class="h-5 w-9 rounded-t bg-gray-200 dark:bg-gray-700" />
<span
class="-ml-1 h-6 w-9 rounded-t"
:style="{ backgroundColor: primarySoft }"
/>
<span class="-ml-1 h-5 w-9 rounded-t bg-gray-200 dark:bg-gray-700" />
</div>
<!-- Slider 风格:底部 2px 主色指示条 + 激活弱底 -->
<div
v-else-if="item.value === 'slider'"
class="flex h-9 w-full items-end rounded bg-white px-1 dark:bg-gray-800"
>
<span class="mr-0.5 flex h-6 flex-1 items-center justify-center rounded-t-sm border-b-2 border-transparent bg-gray-50 dark:bg-gray-700">
<span class="h-2 w-5 rounded-sm bg-gray-200 dark:bg-gray-600" />
</span>
<span
class="mr-0.5 flex h-6 flex-1 items-center justify-center rounded-t-sm border-b-2"
:style="{ borderColor: primaryColor, backgroundColor: primarySoft }"
>
<span class="h-2 w-5 rounded-sm" :style="{ backgroundColor: primaryColor }" />
</span>
<span class="flex h-6 flex-1 items-center justify-center rounded-t-sm border-b-2 border-transparent bg-gray-50 dark:bg-gray-700">
<span class="h-2 w-4 rounded-sm bg-gray-200 dark:bg-gray-600" />
</span>
</div>
<span
class="text-xs"
:style="modelValue === item.value ? { color: primaryColor } : {}"
>
{{ item.label }}
</span>
<svg-icon
v-if="modelValue === item.value"
icon="lucide:check"
class="absolute top-1 right-1"
:style="{ color: primaryColor }"
/>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useThemeStore } from '@/pinia'
defineOptions({
name: 'TabModeSelector'
})
defineProps({
modelValue: {
type: String,
default: 'button'
}
})
const emit = defineEmits(['update:modelValue'])
const themeStore = useThemeStore()
const { settings } = storeToRefs(themeStore)
const primaryColor = computed(() => settings.value.themeColor)
// 主色弱底(真实合成色,跟随换肤;预览只示意,不必严格等于实际标签底色)
const primarySoft = 'rgb(var(--primary-color) / 0.15)'
const tabModes = [
{ value: 'button', label: '默认' },
{ value: 'chrome', label: 'Chrome' },
{ value: 'slider', label: '指示条' }
]
const handleChange = (value) => {
emit('update:modelValue', value)
}
</script>