Files
aigen/components/PermanenceRefStrip.vue

105 lines
3.3 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<div v-if="label" class="mb-1.5 flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5">
<p class="text-[11px] font-medium uppercase tracking-wide text-zinc-500">{{ label }}</p>
<p v-if="hint" class="text-[11px] text-zinc-600">{{ hint }}</p>
</div>
<div class="flex flex-wrap items-start gap-1.5">
<div
v-for="(item, index) in refs"
:key="item.stillId + '-' + index"
class="flex w-16 flex-col items-center gap-0.5"
>
<span class="relative h-12 w-12 overflow-hidden rounded-lg bg-zinc-900">
<span v-if="hidden" class="sensitive-glow block h-full w-full" />
<img
v-else
:src="`/api/library/stills/${item.stillId}?thumb=1`"
alt=""
loading="lazy"
decoding="async"
class="h-full w-full object-cover"
>
<button
v-if="!disabled"
type="button"
class="absolute right-0 top-0 rounded-bl-md bg-zinc-950/80 px-1 text-[10px] leading-4 text-zinc-300 hover:text-red-200"
title="Remove"
@click.stop="emit('remove', index)"
>
×
</button>
</span>
<input
class="w-full truncate rounded border border-white/10 bg-zinc-950 px-0.5 py-0 text-center text-[10px] text-zinc-400 outline-none focus:border-amber-300/40"
:disabled="disabled"
:value="item.label"
:list="nameListId"
:title="item.label || 'Name'"
placeholder="Name"
maxlength="24"
autocomplete="off"
@input="emit('updateLabel', index, sanitizeRefLabel(($event.target as HTMLInputElement).value))"
>
</div>
<datalist :id="nameListId">
<option v-for="option in listNames" :key="option" :value="option" />
</datalist>
<button
v-if="!disabled && refs.length < max"
type="button"
class="flex min-h-12 items-center justify-center rounded-lg border border-dashed border-white/15 text-[10px] leading-tight text-zinc-400 hover:border-amber-300/40 hover:text-amber-100"
:class="refs.length ? 'h-12 w-12' : 'min-w-[8.5rem] px-2.5 py-1.5'"
:title="addTitle"
@click.stop="emit('addRef')"
>
{{ refs.length ? '+' : cta }}
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, useId } from 'vue'
import { sanitizeRefLabel, type PermanenceRef } from '~/utils/globalLocks'
const props = withDefaults(defineProps<{
refs: PermanenceRef[]
nameOptions?: string[]
label?: string
hint?: string
hidden?: boolean
disabled?: boolean
max?: number
addTitle?: string
cta?: string
}>(), {
nameOptions: () => [],
max: 6,
addTitle: 'Choose a still to name',
cta: 'Add still'
})
const emit = defineEmits<{
addRef: []
remove: [index: number]
updateLabel: [index: number, label: string]
}>()
const nameListId = useId()
const listNames = computed(() => {
const seen = new Set<string>()
const names: string[] = []
for (const name of [...props.nameOptions, ...props.refs.map(item => item.label)]) {
const trimmed = String(name || '').trim()
if (!trimmed) continue
const id = trimmed.toLowerCase()
if (seen.has(id)) continue
seen.add(id)
names.push(trimmed)
}
return names
})
</script>