web: add first focus functionality

element with `data-first-focus` will be focused first after navigation. extremely useful for screen readers.
This commit is contained in:
wukko 2024-07-23 13:53:43 +06:00
parent 314d3590ec
commit c9ca0d51d9
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2

View file

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import "@fontsource/ibm-plex-mono/400.css"; import { afterNavigate } from "$app/navigation";
import "@fontsource/ibm-plex-mono/500.css";
import env from "$lib/env"; import env from "$lib/env";
import settings from "$lib/state/settings"; import settings from "$lib/state/settings";
@ -8,34 +7,42 @@
import locale from "$lib/i18n/locale"; import locale from "$lib/i18n/locale";
import currentTheme, { statusBarColors } from "$lib/state/theme"; import currentTheme, { statusBarColors } from "$lib/state/theme";
import "@fontsource/ibm-plex-mono/400.css";
import "@fontsource/ibm-plex-mono/500.css";
import Sidebar from "$components/sidebar/Sidebar.svelte"; import Sidebar from "$components/sidebar/Sidebar.svelte";
import NotchSticker from "$components/misc/NotchSticker.svelte"; import NotchSticker from "$components/misc/NotchSticker.svelte";
import DialogHolder from "$components/dialog/DialogHolder.svelte"; import DialogHolder from "$components/dialog/DialogHolder.svelte";
$: reduceMotion = $: reduceMotion =
$settings.appearance.reduceMotion $settings.appearance.reduceMotion || device.prefers.reducedMotion;
|| device.prefers.reducedMotion;
$: reduceTransparency = $: reduceTransparency =
$settings.appearance.reduceTransparency $settings.appearance.reduceTransparency ||
|| device.prefers.reducedTransparency; device.prefers.reducedTransparency;
afterNavigate(() => {
const to_focus: HTMLElement | null =
document.querySelector("[data-first-focus]");
to_focus?.focus();
});
</script> </script>
<svelte:head> <svelte:head>
{#if device.is.mobile} {#if device.is.mobile}
<meta name="theme-color" content={statusBarColors[$currentTheme]}> <meta name="theme-color" content={statusBarColors[$currentTheme]} />
{/if} {/if}
{#if env.PLAUSIBLE_ENABLED} {#if env.PLAUSIBLE_ENABLED}
<script <script
defer defer
data-domain="{env.HOST}" data-domain={env.HOST}
src="https://{env.PLAUSIBLE_HOST}/js/script.js" src="https://{env.PLAUSIBLE_HOST}/js/script.js"
> >
</script> </script>
{/if} {/if}
</svelte:head> </svelte:head>
<div style="display: contents" data-theme={$currentTheme} lang="{$locale}"> <div style="display: contents" data-theme={$currentTheme} lang={$locale}>
<div <div
id="cobalt" id="cobalt"
data-iphone={device.is.iPhone} data-iphone={device.is.iPhone}
@ -99,9 +106,8 @@
--sidebar-font-size: 11px; --sidebar-font-size: 11px;
--sidebar-inner-padding: 4px; --sidebar-inner-padding: 4px;
--sidebar-height-mobile: calc( --sidebar-height-mobile: calc(
50px 50px + calc(var(--sidebar-inner-padding) * 2) +
+ calc(var(--sidebar-inner-padding) * 2) env(safe-area-inset-bottom)
+ env(safe-area-inset-bottom)
); );
--safe-area-inset-top: env(safe-area-inset-top); --safe-area-inset-top: env(safe-area-inset-top);
@ -215,9 +221,9 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
display: grid; display: grid;
grid-template-columns: calc( grid-template-columns:
var(--sidebar-width) + var(--sidebar-inner-padding) * 2 calc(var(--sidebar-width) + var(--sidebar-inner-padding) * 2)
) 1fr; 1fr;
overflow: hidden; overflow: hidden;
background-color: var(--sidebar-bg); background-color: var(--sidebar-bg);
color: var(--secondary); color: var(--secondary);
@ -228,9 +234,8 @@
#cobalt[data-iphone="true"] { #cobalt[data-iphone="true"] {
grid-template-columns: grid-template-columns:
calc( calc(
var(--sidebar-width) var(--sidebar-width) + var(--sidebar-inner-padding) * 2 +
+ var(--sidebar-inner-padding) * 2 env(safe-area-inset-left)
+ env(safe-area-inset-left)
) )
1fr; 1fr;
} }