refactor(stage-web): providers ui
Co-authored-by: Rizumu Ayaka <19204772+LittleSound@users.noreply.github.com>
This commit is contained in:
co-authored by
Rizumu Ayaka
parent
9889767d22
commit
e993849a5f
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { TransitionVertical } from '@proj-airi/stage-ui/components'
|
||||
import { CollapsibleContent, CollapsibleRoot, CollapsibleTrigger } from 'radix-vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { Collapsable } from '@proj-airi/stage-ui/components'
|
||||
import { ref } from 'vue'
|
||||
|
||||
interface ModelProvider {
|
||||
id: string
|
||||
@@ -35,54 +34,50 @@ const providers = ref<ModelProvider[]>([
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const openedProviders = reactive<Record<string, boolean>>(Object.fromEntries(providers.value.map(provider => [provider.id, false])))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-2">
|
||||
<div v-for="(provider) in providers" :key="provider.id">
|
||||
<CollapsibleRoot :default-open="false" w-full>
|
||||
<CollapsibleTrigger
|
||||
bg="zinc-100 dark:zinc-800"
|
||||
hover="bg-zinc-200 dark:bg-zinc-700"
|
||||
transition="all ease-in-out duration-250"
|
||||
w-full flex items-center gap-1.5 rounded-lg px-4 py-3
|
||||
@click="openedProviders[provider.id] = !openedProviders[provider.id]"
|
||||
>
|
||||
<div flex="~ row 1" items-center gap-1.5>
|
||||
<div :class="provider.icon" class="size-6" />
|
||||
<div class="font-medium">
|
||||
{{ provider.name }} {{ openedProviders[provider.id] }}
|
||||
</div>
|
||||
</div>
|
||||
<div transform transition="transform duration-250" :class="{ 'rotate-180': openedProviders[provider.id] }">
|
||||
<div i-solar:alt-arrow-down-bold-duotone />
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<TransitionVertical>
|
||||
<div v-if="openedProviders[provider.id]" p-4>
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-sm font-medium">
|
||||
API Key
|
||||
</div>
|
||||
<input
|
||||
class="rounded bg-zinc-200 px-2 py-1 text-sm dark:bg-zinc-800"
|
||||
placeholder="Enter API key"
|
||||
>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm font-medium">
|
||||
Available Models
|
||||
</div>
|
||||
</div>
|
||||
<Collapsable w-full>
|
||||
<template #trigger="slotProps">
|
||||
<button
|
||||
bg="zinc-100 dark:zinc-800"
|
||||
hover="bg-zinc-200 dark:bg-zinc-700"
|
||||
transition="all ease-in-out duration-250"
|
||||
w-full flex items-center gap-1.5 rounded-lg px-4 py-3
|
||||
@click="slotProps.setVisible(!slotProps.visible)"
|
||||
>
|
||||
<div flex="~ row 1" items-center gap-1.5>
|
||||
<div :class="provider.icon" class="size-6" />
|
||||
<div class="font-medium">
|
||||
{{ provider.name }}
|
||||
</div>
|
||||
</div>
|
||||
</TransitionVertical>
|
||||
</CollapsibleContent>
|
||||
</CollapsibleRoot>
|
||||
<div transform transition="transform duration-250" :class="{ 'rotate-180': slotProps.visible }">
|
||||
<div i-solar:alt-arrow-down-bold-duotone />
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
<div p-4>
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-sm font-medium">
|
||||
API Key
|
||||
</div>
|
||||
<input
|
||||
class="rounded bg-zinc-200 px-2 py-1 text-sm dark:bg-zinc-800"
|
||||
placeholder="Enter API key"
|
||||
>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="text-sm font-medium">
|
||||
Available Models
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Collapsable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -7,30 +7,32 @@ const props = defineProps<{
|
||||
default?: boolean
|
||||
label?: string
|
||||
}>()
|
||||
const isVisible = defineModel<boolean>({ default: false })
|
||||
const visible = defineModel<boolean>({ default: false })
|
||||
watchEffect(() => {
|
||||
if (props.default != null) {
|
||||
isVisible.value = !!props.default
|
||||
visible.value = !!props.default
|
||||
}
|
||||
})
|
||||
|
||||
function setVisible(value: boolean) {
|
||||
visible.value = value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div flex="~ col" border="~ gray/25 rounded-lg" divide="y dashed gray/25" of-clip shadow-sm>
|
||||
<button
|
||||
sticky top-0 z-10 flex items-center justify-between px2 py1 text-sm backdrop-blur-xl
|
||||
@click="isVisible = !isVisible"
|
||||
>
|
||||
<span>
|
||||
<slot name="label">
|
||||
<div>
|
||||
<slot name="trigger" v-bind="{ visible, setVisible }">
|
||||
<button
|
||||
sticky top-0 z-10 flex items-center justify-between px2 py1 text-sm backdrop-blur-xl
|
||||
@click="visible = !visible"
|
||||
>
|
||||
<span>
|
||||
{{ props.label ?? 'Collapsable' }}
|
||||
</slot>
|
||||
</span> <span op50>{{ isVisible ? '▲' : '▼' }}</span>
|
||||
</button>
|
||||
</span> <span op50>{{ visible ? '▲' : '▼' }}</span>
|
||||
</button>
|
||||
</slot>
|
||||
<TransitionVertical>
|
||||
<div v-if="isVisible" w-full>
|
||||
<slot />
|
||||
</div>
|
||||
<slot v-if="visible" />
|
||||
</TransitionVertical>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -82,7 +82,7 @@ defineExpose({
|
||||
<div font-mono>
|
||||
<span>{{ $t('stage.viewers.debug-menu.vrm.model.title') }}</span>
|
||||
</div>
|
||||
<Collapsable h-fit w-full>
|
||||
<Collapsable h-fit w-full flex="~ col" border="~ gray/25 rounded-lg" divide="y dashed gray/25" of-clip shadow-sm>
|
||||
<template #label>
|
||||
<span font-mono>{{ $t('stage.viewers.debug-menu.vrm.camera') }}</span>
|
||||
</template>
|
||||
@@ -118,7 +118,7 @@ defineExpose({
|
||||
</div>
|
||||
</div>
|
||||
</Collapsable>
|
||||
<Collapsable h-fit w-full>
|
||||
<Collapsable h-fit w-full flex="~ col" border="~ gray/25 rounded-lg" divide="y dashed gray/25" of-clip shadow-sm>
|
||||
<template #label>
|
||||
<span font-mono>{{ $t('stage.viewers.debug-menu.vrm.model.title') }}</span>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user