Bind permanence stills to named lock keys instead of coded categories.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 09:52:27 -05:00
co-authored by Cursor
parent 727d895c10
commit 231c59a7a7
4 changed files with 89 additions and 44 deletions
+33 -13
View File
@@ -8,7 +8,7 @@
<div
v-for="(item, index) in refs"
:key="item.stillId + '-' + index"
class="flex w-14 flex-col items-center gap-0.5"
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" />
@@ -30,15 +30,21 @@
×
</button>
</span>
<select
class="w-full truncate rounded border border-white/10 bg-zinc-950 px-0.5 py-0 text-[10px] text-zinc-400"
<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"
@change="emit('updateLabel', index, ($event.target as HTMLSelectElement).value)"
:list="nameListId"
:title="item.label || 'Name'"
placeholder="Name"
maxlength="24"
autocomplete="off"
@input="emit('updateLabel', index, sanitizeRefLabel(($event.target as HTMLInputElement).value))"
>
<option v-for="option in labelOptions(item.label)" :key="option" :value="option">{{ option }}</option>
</select>
</div>
<datalist :id="nameListId">
<option v-for="option in listNames" :key="option" :value="option" />
</datalist>
<button
v-if="!disabled && refs.length < max"
type="button"
@@ -54,10 +60,12 @@
</template>
<script setup lang="ts">
import { PERMANENCE_REF_LABELS, type PermanenceRef } from '~/utils/globalLocks'
import { computed, useId } from 'vue'
import { sanitizeRefLabel, type PermanenceRef } from '~/utils/globalLocks'
withDefaults(defineProps<{
const props = withDefaults(defineProps<{
refs: PermanenceRef[]
nameOptions?: string[]
label?: string
hint?: string
hidden?: boolean
@@ -66,8 +74,9 @@ withDefaults(defineProps<{
addTitle?: string
cta?: string
}>(), {
nameOptions: () => [],
max: 6,
addTitle: 'Choose a still to label',
addTitle: 'Choose a still to name',
cta: 'Add still'
})
@@ -77,8 +86,19 @@ const emit = defineEmits<{
updateLabel: [index: number, label: string]
}>()
function labelOptions(current: string) {
if (PERMANENCE_REF_LABELS.includes(current as typeof PERMANENCE_REF_LABELS[number])) return [...PERMANENCE_REF_LABELS]
return [...PERMANENCE_REF_LABELS, current]
}
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>