Simplify generation controls with task navigation and settings drawer

This commit is contained in:
Towsty
2026-09-07 08:36:33 -05:00
parent 7a2069462e
commit 174d40a7dc
7 changed files with 177 additions and 13 deletions
+25
View File
@@ -0,0 +1,25 @@
<template>
<div>
<button v-if="!advanced" type="button" class="rounded-xl border border-white/20 px-4 py-3 text-sm text-zinc-200 hover:border-amber-300" @click="show">Generation settings</button>
<div v-if="advanced" class="space-y-5"><slot /></div>
<dialog v-else ref="panel" aria-label="Generation settings" class="settings-drawer fixed inset-y-0 left-auto right-0 m-0 h-dvh max-h-none w-full max-w-lg overflow-y-auto border-l border-white/15 bg-zinc-950 p-5 text-zinc-100 shadow-2xl backdrop:bg-black/60" @click="backdrop" @close="restoreFocus">
<div class="mb-6 flex items-center justify-between gap-4">
<h2 class="font-display text-xl font-bold">Generation settings</h2>
<button type="button" class="rounded-xl border border-white/20 px-4 py-2" @click="panel?.close()">Close</button>
</div>
<div class="space-y-5"><slot /></div>
</dialog>
</div>
</template>
<script setup lang="ts">
defineProps<{ advanced: boolean }>()
const panel = ref<HTMLDialogElement | null>(null)
let opener: HTMLElement | null = null
function show() { opener = document.activeElement as HTMLElement; panel.value?.showModal() }
function restoreFocus() { opener?.focus() }
function backdrop(event: MouseEvent) {
if (event.target !== panel.value) return
const rect = panel.value.getBoundingClientRect()
if (event.clientX < rect.left || event.clientX > rect.right) panel.value.close()
}
</script>
+4 -3
View File
@@ -1,6 +1,6 @@
<template>
<div class="space-y-3">
<div class="flex flex-wrap items-center gap-2">
<div v-if="!simple" class="flex flex-wrap items-center gap-2">
<KeepPromptMenu
:items="keepItems"
:heading="keepHeading"
@@ -23,7 +23,7 @@
<span class="text-[11px] text-zinc-500">Snippets go into {{ targetLabel }}.</span>
</div>
<label class="block text-sm">
<label v-if="!simple || pre.trim()" class="block text-sm">
<span class="mb-1 block text-xs font-medium text-zinc-400">Pre-text</span>
<textarea
:value="pre"
@@ -67,7 +67,7 @@
</button>
</label>
<label class="block text-sm">
<label v-if="!simple || post.trim()" class="block text-sm">
<span class="mb-1 block text-xs font-medium text-zinc-400">Post-text</span>
<textarea
:value="post"
@@ -126,6 +126,7 @@ const targets = [
]
const props = withDefaults(defineProps<{
simple?: boolean
pre?: string
prompt?: string
post?: string
+6 -1
View File
@@ -1,5 +1,9 @@
<template>
<div class="mb-4 grid grid-cols-3 gap-3">
<nav v-if="!advanced" aria-label="Generation type" class="grid grid-cols-3 gap-2 rounded-2xl border border-white/10 bg-zinc-950/50 p-2">
<button v-for="kind in ['image', 'video'] as const" :key="kind" type="button" :aria-pressed="current === kind" class="rounded-xl px-3 py-3 font-semibold capitalize" :class="current === kind ? 'bg-amber-400 text-zinc-950' : 'text-zinc-300 hover:bg-white/5'" @click="emit('select', kind)">{{ kind }}</button>
<NuxtLink to="/music" class="rounded-xl px-3 py-3 text-center font-semibold" :aria-current="current === 'music' ? 'page' : undefined" :class="current === 'music' ? 'bg-amber-400 text-zinc-950' : 'text-zinc-300 hover:bg-white/5'">Music</NuxtLink>
</nav>
<div v-else class="mb-4 grid grid-cols-3 gap-3">
<div
class="overflow-hidden rounded-3xl border transition"
:class="current === 'video' ? 'border-amber-300 bg-amber-400/10 text-amber-50' : 'border-white/10 text-zinc-400'"
@@ -122,6 +126,7 @@
<script setup lang="ts">
const props = withDefaults(defineProps<{
current: 'video' | 'image' | 'music'
advanced?: boolean
ltxEnabled?: boolean
videoEngine?: 'minimax' | 'ltx'
videoStart?: 'still' | 'text'