Add live template preview (auto-updates as you type)
All checks were successful
Validate / Hassfest (push) Successful in 4s
All checks were successful
Validate / Hassfest (push) Successful in 4s
Preview now piggybacks on the validation debounce call — when the template renders successfully, the result is shown in a collapsible <details> section below the editor. Removes the manual Preview button since it's now automatic. Preview hides when there are errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
slotErrors = { ...slotErrors, [slotKey]: '' };
|
||||
slotErrorLines = { ...slotErrorLines, [slotKey]: null };
|
||||
slotErrorTypes = { ...slotErrorTypes, [slotKey]: '' };
|
||||
const { [slotKey]: _, ...rest } = slotPreview;
|
||||
slotPreview = rest;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,6 +47,13 @@
|
||||
slotErrors = { ...slotErrors, [slotKey]: res.error || '' };
|
||||
slotErrorLines = { ...slotErrorLines, [slotKey]: res.error_line || null };
|
||||
slotErrorTypes = { ...slotErrorTypes, [slotKey]: res.error_type || '' };
|
||||
// Live preview: show rendered result when no error
|
||||
if (res.rendered) {
|
||||
slotPreview = { ...slotPreview, [slotKey]: res.rendered };
|
||||
} else {
|
||||
const { [slotKey]: _, ...rest } = slotPreview;
|
||||
slotPreview = rest;
|
||||
}
|
||||
} catch {
|
||||
// Network error, don't show as template error
|
||||
slotErrors = { ...slotErrors, [slotKey]: '' };
|
||||
@@ -180,10 +189,6 @@
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<label class="text-xs text-[var(--color-muted-foreground)]">{t(`templateConfig.${slot.label}`)}</label>
|
||||
<div class="flex items-center gap-2">
|
||||
{#if (slot.rows || 2) > 2}
|
||||
<button type="button" onclick={() => previewSlot(slot.key)}
|
||||
class="text-xs text-[var(--color-muted-foreground)] hover:underline">{t('templateConfig.preview')}</button>
|
||||
{/if}
|
||||
{#if varsRef[slot.key]}
|
||||
<button type="button" onclick={() => showVarsFor = slot.key}
|
||||
class="text-xs text-[var(--color-muted-foreground)] hover:underline">{t('templateConfig.variables')}</button>
|
||||
@@ -199,10 +204,13 @@
|
||||
<p class="mt-1 text-xs" style="color: var(--color-error-fg);">✕ {t('common.syntaxError')}: {slotErrors[slot.key]}{slotErrorLines[slot.key] ? ` (${t('common.line')} ${slotErrorLines[slot.key]})` : ''}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if slotPreview[slot.key]}
|
||||
<div class="mt-1 p-2 bg-[var(--color-muted)] rounded text-sm">
|
||||
<pre class="whitespace-pre-wrap">{slotPreview[slot.key]}</pre>
|
||||
</div>
|
||||
{#if slotPreview[slot.key] && !slotErrors[slot.key]}
|
||||
<details class="mt-1">
|
||||
<summary class="text-xs text-[var(--color-muted-foreground)] cursor-pointer hover:underline">{t('templateConfig.preview')}</summary>
|
||||
<div class="mt-1 p-2 bg-[var(--color-muted)] rounded text-sm">
|
||||
<pre class="whitespace-pre-wrap">{slotPreview[slot.key]}</pre>
|
||||
</div>
|
||||
</details>
|
||||
{/if}
|
||||
{:else}
|
||||
<input bind:value={(form as any)[slot.key]}
|
||||
|
||||
Reference in New Issue
Block a user