调整,音乐模块
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { ChevronDown } from '@lucide/vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { sourceName } from './sources'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string[]
|
||||
/** 可选源(客户端名)列表 */
|
||||
options: string[]
|
||||
}>()
|
||||
const emit = defineEmits<{ 'update:model-value': [string[]] }>()
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
const checked = computed(() => new Set(props.modelValue))
|
||||
|
||||
const toggle = (code: string) => {
|
||||
const next = new Set(checked.value)
|
||||
if (next.has(code)) next.delete(code)
|
||||
else next.add(code)
|
||||
emit('update:model-value', [...next])
|
||||
}
|
||||
|
||||
const label = computed(() => {
|
||||
if (props.modelValue.length === 0) return '未选择'
|
||||
if (props.modelValue.length === 1) return sourceName(props.modelValue[0])
|
||||
return `已选 ${props.modelValue.length} 个源`
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover v-model:open="open">
|
||||
<PopoverTrigger as-child>
|
||||
<Button variant="outline" class="justify-between font-normal" size="sm">
|
||||
<span class="truncate">{{ label }}</span>
|
||||
<ChevronDown class="size-3.5 opacity-50 shrink-0" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-64 p-2" align="start">
|
||||
<!-- ScrollArea 的 viewport h-full 需要 root 有确定高度才滚动;max-h 不生效,用固定 h-72 -->
|
||||
<ScrollArea class="h-72">
|
||||
<div class="space-y-0.5 pr-2">
|
||||
<label
|
||||
v-for="code in options"
|
||||
:key="code"
|
||||
class="flex items-center gap-2 rounded-md px-2 py-1.5 cursor-pointer hover:bg-muted/50"
|
||||
>
|
||||
<Checkbox
|
||||
:model-value="checked.has(code)"
|
||||
@update:model-value="toggle(code)"
|
||||
/>
|
||||
<Label class="text-sm cursor-pointer truncate">{{ sourceName(code) }}</Label>
|
||||
</label>
|
||||
<p v-if="options.length === 0" class="px-2 py-3 text-xs text-muted-foreground">
|
||||
未获取到可用源,请先安装环境
|
||||
</p>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
<div class="mt-1 border-t pt-1.5 px-1 flex items-center justify-between">
|
||||
<span class="text-xs text-muted-foreground">{{ options.length }} 个可选源</span>
|
||||
<span class="text-xs text-muted-foreground">已选 {{ props.modelValue.length }}</span>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</template>
|
||||
Reference in New Issue
Block a user