Files
openteam/web/src/components/ui/Select.vue
T
SakurasanandClaude Sonnet 5 489a79564c feat(web): management console frontend
Vue 3 + TS + Vite + Tailwind with self-built UI components. Landing,
auth, user dashboard (keys/usage/settings), and admin console
(overview/models/channels/users/usage/config). Theme system
(light/dark/system) with pre-paint boot script, theme-aware ECharts,
and a channel editor with multi-format (Anthropic/OpenAI) selection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 21:05:02 +08:00

36 lines
1.3 KiB
Vue

<script setup lang="ts">
export interface SelectOption {
label: string
value: string
}
withDefaults(
defineProps<{
modelValue: string
label?: string
options: SelectOption[]
disabled?: boolean
}>(),
{ label: '', disabled: false },
)
const emit = defineEmits<{ (e: 'update:modelValue', v: string): void }>()
const cls =
'w-full appearance-none rounded border border-line bg-bg px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-brand/40 disabled:opacity-60'
</script>
<template>
<label class="block">
<span v-if="label" class="mb-1.5 block text-xs font-medium text-ink-soft">{{ label }}</span>
<div class="relative">
<select :value="modelValue" :disabled="disabled" :class="cls" @change="emit('update:modelValue', ($event.target as HTMLSelectElement).value)">
<option v-for="o in options" :key="o.value" :value="o.value">{{ o.label }}</option>
</select>
<svg class="pointer-events-none absolute right-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-ink-mute" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.17l3.71-3.94a.75.75 0 1 1 1.08 1.04l-4.25 4.5a.75.75 0 0 1-1.08 0l-4.25-4.5a.75.75 0 0 1 .02-1.06z" clip-rule="evenodd" />
</svg>
</div>
</label>
</template>