v0.3 Phase 4a: Settings tab shell
Discovers that v0.2 SettingsPage.svelte was already structured as
eight numbered sections aligning almost 1:1 with the v0.3 plan. The
cheapest path to "one section visible at a time" is therefore a
tab-shell overlay rather than a file split. Behaviour stays identical
to v0.2 when quietware is off; with quietware on, only the active
tab's section renders.
Changes.
- NEW: src/lib/ui/LumotiaSettingsTabs.svelte. Tab list following
the WAI-ARIA "tabs (automatic activation)" pattern. Arrow / Home /
End keyboard navigation. Active tab uses the brand left-bar
accent (border-l-caution) — same grammar as the LumotiaNotice
refactor from Phase 3.
- MODIFIED: src/lib/pages/SettingsPage.svelte. Added an isQuietware
reactive flag, a MutationObserver watching <html data-design>,
an activeTab state, and eight {#if !isQuietware || activeTab ===
'X'} wrappers around the existing top-level SettingsGroup
sections. The settings tree is unchanged; only its top-level
rendering gate changed.
- v0.2 fallback: when data-design="quietware" is absent the
tablist does not render and all eight sections stack as before.
The search filter spans every section in v0.2 mode. Smallest-
possible behavioural change for "one section at a time".
Tab IDs in this commit map 1:1 to existing v0.2 section names
(start-here / transcription / models / tasks / accessibility /
privacy / advanced / help). Phase 4b will restructure to the plan's
canonical names (carving Output from Advanced and Vocabulary from
Transcription).
Phases 4b and 4c are logged as pending in the plan doc:
4b. Restructure to canonical tab names (Output, Vocabulary).
4c. Texture-opacity slider + high-contrast toggle in Accessibility.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
import HotkeyRecorder from "$lib/components/HotkeyRecorder.svelte";
|
||||
import ImplementationRulesEditor from "$lib/components/ImplementationRulesEditor.svelte";
|
||||
import SettingsGroup from "$lib/ui/LumotiaSettingsGroup.svelte";
|
||||
import SettingsTabs from "$lib/ui/LumotiaSettingsTabs.svelte";
|
||||
import StatusPill from "$lib/ui/LumotiaStatusPill.svelte";
|
||||
import ZonePicker from "$lib/components/ZonePicker.svelte";
|
||||
import AccessibilityControls from "$lib/components/AccessibilityControls.svelte";
|
||||
@@ -1212,6 +1213,42 @@
|
||||
saveTemplates();
|
||||
editingTemplate = -1;
|
||||
}
|
||||
|
||||
// v0.3 Phase 4a — sectional tab nav. The full 2 791 LOC settings tree
|
||||
// stays in this file; quietware mode shows ONE top-level section at a
|
||||
// time via {#if !isQuietware || activeTab === 'X'} wrappers below.
|
||||
// Without quietware (data-design unset on <html>) the page renders
|
||||
// exactly as v0.2 did (all eight sections stacked, search filter
|
||||
// active across all of them).
|
||||
let isQuietware = $state(false);
|
||||
let activeTab = $state("start-here");
|
||||
const settingsTabs = [
|
||||
{ id: "start-here", label: "Start Here" },
|
||||
{ id: "transcription", label: "Transcription" },
|
||||
{ id: "models", label: "Models" },
|
||||
{ id: "tasks", label: "Tasks" },
|
||||
{ id: "accessibility", label: "Accessibility" },
|
||||
{ id: "privacy", label: "Privacy" },
|
||||
{ id: "advanced", label: "Advanced" },
|
||||
{ id: "help", label: "Help" },
|
||||
];
|
||||
let quietwareObserver: MutationObserver | null = null;
|
||||
onMount(() => {
|
||||
if (typeof document === "undefined") return;
|
||||
const sync = () => {
|
||||
isQuietware = document.documentElement.dataset.design === "quietware";
|
||||
};
|
||||
sync();
|
||||
quietwareObserver = new MutationObserver(sync);
|
||||
quietwareObserver.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-design"],
|
||||
});
|
||||
});
|
||||
onDestroy(() => {
|
||||
quietwareObserver?.disconnect();
|
||||
quietwareObserver = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-full overflow-y-auto animate-fade-in">
|
||||
@@ -1253,6 +1290,18 @@
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if isQuietware}
|
||||
<!-- v0.3 Phase 4a — tab nav renders only when quietware is active.
|
||||
v0.2 behaviour (stacked sections) is unchanged when the flag
|
||||
is off. -->
|
||||
<div class="pt-3">
|
||||
<SettingsTabs
|
||||
tabs={settingsTabs}
|
||||
activeId={activeTab}
|
||||
onSelect={(id) => (activeTab = id)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="px-7 pt-5 pb-8">
|
||||
@@ -1298,6 +1347,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if !isQuietware || activeTab === 'start-here'}
|
||||
<!-- =====================================================
|
||||
1. Start Here — microphone, language, engine
|
||||
===================================================== -->
|
||||
@@ -1429,7 +1479,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'transcription'}
|
||||
<!-- =====================================================
|
||||
2. Transcription — format mode, cleanup, vocabulary
|
||||
===================================================== -->
|
||||
@@ -1837,7 +1889,9 @@
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'models'}
|
||||
<!-- =====================================================
|
||||
3. Models — download, switch, disk-space readout
|
||||
===================================================== -->
|
||||
@@ -2055,7 +2109,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'tasks'}
|
||||
<!-- =====================================================
|
||||
4. Tasks — WIP limit, energy-aware sequencing
|
||||
===================================================== -->
|
||||
@@ -2099,7 +2155,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'accessibility'}
|
||||
<!-- =====================================================
|
||||
5. Accessibility — motion, contrast, typography
|
||||
===================================================== -->
|
||||
@@ -2112,7 +2170,9 @@
|
||||
<AccessibilityControls />
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'privacy'}
|
||||
<!-- =====================================================
|
||||
6. Privacy — local-only badge, AI disclosure, activation log
|
||||
===================================================== -->
|
||||
@@ -2197,7 +2257,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
{#if !isQuietware || activeTab === 'advanced'}
|
||||
<!-- =====================================================
|
||||
7. Advanced — everything else, collapsed by default
|
||||
===================================================== -->
|
||||
@@ -2743,8 +2805,10 @@
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
|
||||
|
||||
{#if !isQuietware || activeTab === 'help'}
|
||||
<!-- 8. Help — first-run tutorial replay + support links. -->
|
||||
<SettingsGroup
|
||||
title="Help"
|
||||
@@ -2799,6 +2863,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
{/if}
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user