From 3a27031eba647e3e6a304c2c7d7f4526b8212836 Mon Sep 17 00:00:00 2001 From: Jake Date: Thu, 7 May 2026 10:07:39 +0100 Subject: [PATCH] feat(settings-group): add optional icon prop and tighten title/description rhythm Title bumped to font-semibold so it scans first; description gets tracking-wide plus mt-1 for cleaner rhythm. Chevron alignment shifted from mt-0.5 to mt-1 to match the new spacing. Optional `icon` prop renders a Lucide component between the chevron and the title block at 16x16, text-tertiary, no colour change on open. Layout is preserved exactly when no icon is passed. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/lib/components/SettingsGroup.svelte | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/components/SettingsGroup.svelte b/src/lib/components/SettingsGroup.svelte index 5bfb0fd..0fceec5 100644 --- a/src/lib/components/SettingsGroup.svelte +++ b/src/lib/components/SettingsGroup.svelte @@ -5,16 +5,18 @@ // (modern Chromium / WebKit), and falls back to instant open/close // elsewhere. prefers-reduced-motion disables both. import { ChevronRight } from "lucide-svelte"; + import type { Component } from "svelte"; interface Props { title: string; description?: string; open?: boolean; onopen?: () => void; + icon?: Component<{ size?: number; class?: string; "aria-hidden"?: boolean | "true" | "false" }>; children?: import("svelte").Snippet; } - let { title, description = "", open = false, onopen, children }: Props = $props(); + let { title, description = "", open = false, onopen, icon: Icon, children }: Props = $props(); // Fires once on the first transition from closed → open. Used by // sections that lazy-load expensive data (e.g. TTS voice enumeration). @@ -47,13 +49,16 @@ class="flex items-start gap-2 cursor-pointer list-none py-3 px-1 rounded hover:bg-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent" >