agent: components — add accessibility controls panel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
107
src/lib/components/AccessibilityControls.svelte
Normal file
107
src/lib/components/AccessibilityControls.svelte
Normal file
@@ -0,0 +1,107 @@
|
||||
<script>
|
||||
import { getPreferences, updateAccessibility } from '$lib/stores/preferences.svelte.js';
|
||||
import Toggle from '$lib/components/Toggle.svelte';
|
||||
import SegmentedButton from '$lib/components/SegmentedButton.svelte';
|
||||
|
||||
const prefs = getPreferences();
|
||||
|
||||
const fontOptions = [
|
||||
{ id: 'lexend', label: 'Lexend' },
|
||||
{ id: 'atkinson', label: 'Atkinson' },
|
||||
{ id: 'opendyslexic', label: 'OpenDyslexic' },
|
||||
];
|
||||
|
||||
let bionicChecked = $state(prefs.accessibility.bionicReading || false);
|
||||
let motionValue = $state(
|
||||
prefs.accessibility.reduceMotion === 'on' ? 'On'
|
||||
: prefs.accessibility.reduceMotion === 'off' ? 'Off'
|
||||
: 'System'
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
if (bionicChecked !== prefs.accessibility.bionicReading) {
|
||||
updateAccessibility({ bionicReading: bionicChecked });
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
const mapped = motionValue === 'On' ? 'on' : motionValue === 'Off' ? 'off' : 'system';
|
||||
if (mapped !== prefs.accessibility.reduceMotion) {
|
||||
updateAccessibility({ reduceMotion: mapped });
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-5">
|
||||
<!-- Font family -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Body font</p>
|
||||
<div class="flex gap-2">
|
||||
{#each fontOptions as opt}
|
||||
<button
|
||||
class="flex-1 px-3 py-2 rounded-lg text-[12px] border
|
||||
{prefs.accessibility.fontFamily === opt.id
|
||||
? 'border-accent bg-accent-subtle text-text'
|
||||
: 'border-border-subtle text-text-secondary hover:border-border'}"
|
||||
style="font-family: {opt.id === 'lexend' ? "'Lexend'" : opt.id === 'atkinson' ? "'Atkinson Hyperlegible Next'" : "'OpenDyslexic'"}; transition-duration: var(--duration-ui)"
|
||||
onclick={() => updateAccessibility({ fontFamily: opt.id })}
|
||||
>
|
||||
{opt.label}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Font size -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Font size</p>
|
||||
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.fontSize}px</span>
|
||||
</div>
|
||||
<input type="range" min="16" max="24" step="1" value={prefs.accessibility.fontSize}
|
||||
oninput={(e) => updateAccessibility({ fontSize: Number(e.target.value) })}
|
||||
class="w-full accent-accent" />
|
||||
</div>
|
||||
|
||||
<!-- Letter spacing -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Letter spacing</p>
|
||||
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.letterSpacing.toFixed(2)}em</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="0.15" step="0.01" value={prefs.accessibility.letterSpacing}
|
||||
oninput={(e) => updateAccessibility({ letterSpacing: Number(e.target.value) })}
|
||||
class="w-full accent-accent" />
|
||||
</div>
|
||||
|
||||
<!-- Line height -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Line height</p>
|
||||
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.lineHeight.toFixed(1)}</span>
|
||||
</div>
|
||||
<input type="range" min="1.3" max="2.2" step="0.1" value={prefs.accessibility.lineHeight}
|
||||
oninput={(e) => updateAccessibility({ lineHeight: Number(e.target.value) })}
|
||||
class="w-full accent-accent" />
|
||||
</div>
|
||||
|
||||
<!-- Transcript font size -->
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Transcript font size</p>
|
||||
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.transcriptSize}px</span>
|
||||
</div>
|
||||
<input type="range" min="16" max="24" step="1" value={prefs.accessibility.transcriptSize}
|
||||
oninput={(e) => updateAccessibility({ transcriptSize: Number(e.target.value) })}
|
||||
class="w-full accent-accent" />
|
||||
</div>
|
||||
|
||||
<!-- Bionic reading -->
|
||||
<Toggle label="Bionic reading" description="Bold the first few characters of each word for faster scanning" bind:checked={bionicChecked} />
|
||||
|
||||
<!-- Reduce motion -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-[12px] text-text-secondary font-medium">Reduce motion</p>
|
||||
<SegmentedButton options={['System', 'On', 'Off']} bind:value={motionValue} size="small" />
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user