{% extends "root.html" %}
{% block width %}max-w-7xl{% endblock %}
{% block content %}
{# One form drives everything. The preview pane re-posts it to /preview as
you type; the download and save buttons submit it natively (hx-boost off)
to different endpoints via formaction. #}
<form id="card-form" method="post" action="/export?format=png" hx-boost="false"
class="grid grid-cols-1 lg:grid-cols-[20rem_minmax(0,1fr)] gap-6 items-start">
<aside class="space-y-3 order-2 lg:order-1">
<div>
<p class="font-mono text-xs uppercase tracking-[0.25em] text-accent">{{ app_name }}</p>
<h1 class="text-2xl font-bold">{% if slug %}Edit snippet{% else %}New card{% endif %}</h1>
</div>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Window title</span>
<input name="title" value="{{ spec.title }}" maxlength="200" class="input input-bordered input-sm w-full font-mono">
</label>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Language</span>
<select name="language" class="select select-bordered select-sm w-full py-0">
<option value="auto" {% if spec.language == "auto" %}selected{% endif %}>Auto-detect (from first line)</option>
{% for l in options.languages %}
<option value="{{ l.id }}" {% if spec.language == l.id %}selected{% endif %}>{{ l.name }}</option>
{% endfor %}
</select>
</label>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Window decoration</span>
<select name="chrome" class="select select-bordered select-sm w-full py-0">
{% for c in options.chromes %}
<option value="{{ c.id }}" {% if spec.chrome == c.id %}selected{% endif %}>{{ c.name }}</option>
{% endfor %}
</select>
</label>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Color scheme</span>
<select name="palette" class="select select-bordered select-sm w-full py-0">
<option value="auto" {% if spec.palette == "auto" %}selected{% endif %}>Match the decoration's era</option>
<optgroup label="KDE classics">
{% for p in options.palettes_kde %}
<option value="{{ p.id }}" {% if spec.palette == p.id %}selected{% endif %}>{{ p.name }}</option>
{% endfor %}
</optgroup>
<optgroup label="neiam">
{% for p in options.palettes_neiam %}
<option value="{{ p.id }}" {% if spec.palette == p.id %}selected{% endif %}>{{ p.name }}</option>
{% endfor %}
</optgroup>
</select>
</label>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Highlighting</span>
<select name="highlight" class="select select-bordered select-sm w-full py-0">
{% for t in options.hl_themes %}
<option value="{{ t.id }}" {% if spec.highlight == t.id %}selected{% endif %}>{{ t.name }}</option>
{% endfor %}
</select>
</label>
<label class="form-control">
<span class="label-text text-xs uppercase tracking-wider opacity-70">Padding</span>
<input type="range" name="padding" min="0" max="{{ max_padding }}" step="4" value="{{ spec.padding }}" class="range range-xs range-primary">
</label>
<div class="flex flex-wrap gap-x-5 gap-y-1">
<label class="label cursor-pointer gap-2 justify-start">
<input type="checkbox" name="line_numbers" class="checkbox checkbox-sm" {% if spec.line_numbers %}checked{% endif %}>
<span class="label-text">Line numbers</span>
</label>
<label class="label cursor-pointer gap-2 justify-start">
<input type="checkbox" name="transparent" class="checkbox checkbox-sm" {% if spec.transparent %}checked{% endif %}>
<span class="label-text">Transparent backdrop</span>
</label>
</div>
<div class="divider my-1"></div>
<div class="grid grid-cols-2 gap-2">
<button type="submit" formaction="/export?format=png" class="btn btn-sm btn-outline">
<i class="fas fa-image fa-fw"></i> PNG
</button>
<button type="submit" formaction="/export?format=svg" class="btn btn-sm btn-outline">
<i class="fas fa-bezier-curve fa-fw"></i> SVG
</button>
{% if user %}
{% if slug %}
<button type="submit" formaction="/snippets/{{ slug }}" class="btn btn-sm btn-primary">
<i class="fas fa-floppy-disk fa-fw"></i> Update
</button>
<button type="submit" formaction="/snippets" class="btn btn-sm btn-ghost">
<i class="fas fa-clone fa-fw"></i> Save as new
</button>
{% else %}
<button type="submit" formaction="/snippets" class="btn btn-sm btn-primary col-span-2">
<i class="fas fa-floppy-disk fa-fw"></i> Save & get embed links
</button>
{% endif %}
{% else %}
<a href="/login" class="btn btn-sm btn-ghost col-span-2" hx-boost="true">
<i class="fas fa-right-to-bracket fa-fw"></i> Log in to save & embed
</a>
{% endif %}
</div>
{% if slug %}
<a href="/s/{{ slug }}" class="link link-hover text-sm opacity-70" hx-boost="true">← back to the share page</a>
{% endif %}
</aside>
<section class="space-y-4 order-1 lg:order-2 min-w-0">
{# The named field the form submits. Hidden by default: you edit inside
the rendered window, which mirrors into this. Not `required`, since a
hidden required field blocks submission without showing why. #}
<textarea id="code-source" name="code" rows="14" data-code-input spellcheck="false" autocapitalize="off" autocomplete="off"
class="textarea textarea-bordered w-full font-mono text-sm leading-relaxed hidden"
placeholder="Paste some code…">{{ spec.code }}</textarea>
{# The preview swaps only #preview-inner, so the in-window textarea
beside it survives re-renders (and keeps focus and caret). That
textarea has no name: it mirrors the code box above, which is what the
form actually submits. See initInWindowEditing in f/js/src.js. #}
<div id="preview"
hx-post="/preview"
hx-trigger="input delay:150ms from:#card-form, change from:#card-form"
hx-sync="this:replace"
hx-target="#preview-inner"
hx-select="#preview-inner"
hx-swap="outerHTML"
class="relative rounded-box border border-base-300 bg-base-200 p-3 overflow-auto [&_svg]:max-w-full [&_svg]:h-auto [&_svg]:mx-auto [&_svg]:block">
<div id="preview-inner">{{ card_svg|safe }}</div>
<textarea data-in-window data-code-input aria-label="Edit the code inside the window"
spellcheck="false" autocapitalize="off" autocomplete="off" wrap="off"
class="absolute z-10 m-0 p-0 border-0 bg-transparent text-transparent shadow-none resize-none overflow-hidden whitespace-pre outline-none focus:outline-none focus:ring-0 selection:bg-primary/30"
style="font-family: 'B612 Mono', monospace; tab-size: 4; -moz-tab-size: 4; left: 0; top: 0; width: 0; height: 0;"></textarea>
</div>
<div class="flex flex-wrap items-center justify-between gap-2 text-xs">
<span class="opacity-60">Click into the window to edit the code in place.</span>
<button type="button" class="btn btn-xs btn-ghost"
onclick="const t = document.getElementById('code-source'); t.classList.toggle('hidden'); this.querySelector('span').textContent = t.classList.contains('hidden') ? 'Show plain text box' : 'Hide plain text box';">
<i class="fas fa-align-left fa-fw"></i> <span>Show plain text box</span>
</button>
</div>
</section>
</form>
{% endblock %}
neiam
/bismuth
MOTHER-FUCKING-BISMUTH
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
7.7 KiB · text
History
487bb12