feat(badges): add Hole Marker Inset control to badge template form

Exposes punch_holes.inset_x_mm in the badge template config UI under
the Punch-Out Hole Markers section. Visible whenever at least one slot
is enabled. Number input (0–8, step 0.5) with a Reset button that
clears back to the 2mm default. Saved to cfg_json on submit; parsed
back on load; omitted from the payload when left at default (null).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-08 20:13:07 -04:00
parent 955d28d9c5
commit 55f3e3a5a4

View File

@@ -86,6 +86,8 @@ let cfg_punch_holes_right_rainbow = $state(false);
let cfg_punch_holes_center_fg = $state('');
let cfg_punch_holes_center_bg = $state('');
let cfg_punch_holes_center_rainbow = $state(false);
// Horizontal inset per side (mm). null = use component default (2mm).
let cfg_punch_holes_inset_x_mm: number | null = $state(null);
// Applies to all rainbow slots: slow breathing pulse instead of fast cycle
let cfg_punch_holes_slow_pulse = $state(false);
// Header bottom border. Empty color = no border.
@@ -200,6 +202,7 @@ async function load_template(id: string) {
cfg_punch_holes_center_bg = parsed_cfg?.punch_holes?.center_bg ?? '';
cfg_punch_holes_center_rainbow = parsed_cfg?.punch_holes?.center_rainbow ?? false;
cfg_punch_holes_slow_pulse = parsed_cfg?.punch_holes?.slow_pulse ?? false;
cfg_punch_holes_inset_x_mm = parsed_cfg?.punch_holes?.inset_x_mm ?? null;
cfg_header_border_color = parsed_cfg.header_border_color ?? '';
cfg_header_border_width = parsed_cfg.header_border_width ?? '';
cfg_header_padding_top = parsed_cfg.header_padding_top ?? '';
@@ -301,6 +304,7 @@ async function handle_submit() {
if (cfg_punch_holes_center_bg.trim()) ph.center_bg = cfg_punch_holes_center_bg.trim();
if (cfg_punch_holes_center_rainbow) ph.center_rainbow = true;
if (cfg_punch_holes_slow_pulse) ph.slow_pulse = true;
if (cfg_punch_holes_inset_x_mm !== null && !isNaN(cfg_punch_holes_inset_x_mm)) ph.inset_x_mm = cfg_punch_holes_inset_x_mm;
cfg_obj.punch_holes = ph;
} else {
delete cfg_obj.punch_holes;
@@ -488,6 +492,41 @@ function toggle_cfg_controls_auth_editable(key: string) {
<span class="text-sm">Slow Pulse <span class="text-xs text-surface-400 italic">(gentle breathing instead of fast cycle)</span></span>
</label>
{/if}
{#if cfg_punch_holes_left || cfg_punch_holes_right || cfg_punch_holes_center}
<div class="pt-1 border-t border-surface-200-800">
<label class="label">
<span class="text-sm">Hole Marker Inset (mm per side)</span>
<div class="flex items-center gap-2">
<input
type="number"
min="0"
max="8"
step="0.5"
placeholder="2"
value={cfg_punch_holes_inset_x_mm ?? ''}
oninput={(e) => {
const v = parseFloat((e.target as HTMLInputElement).value);
cfg_punch_holes_inset_x_mm = isNaN(v) ? null : v;
}}
class="input w-24" />
{#if cfg_punch_holes_inset_x_mm !== null}
<button
type="button"
onclick={() => (cfg_punch_holes_inset_x_mm = null)}
class="btn btn-sm preset-tonal-surface">
Reset to default
</button>
{/if}
</div>
<p class="text-xs text-surface-400 italic">
Shrinks the printed marker width by this many mm on each horizontal side,
keeping it inside the physical hole slot. Default is 2mm. Increase if markers
bleed outside the hole on your printer or badge stock.
</p>
</label>
</div>
{/if}
</div>
<label class="label">