Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"sidebar_expand": "Seitenleiste ausklappen",
"sidebar_collapse": "Seitenleiste einklappen",
"sidebar_collapse_label": "Einklappen",
"skip_to_content": "Zum Hauptinhalt springen",
"header_open_nav": "Navigation öffnen",
"header_close_nav": "Navigation schließen",
"header_user_menu": "Benutzermenü",
Expand Down
1 change: 1 addition & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"sidebar_expand": "Expand sidebar",
"sidebar_collapse": "Collapse sidebar",
"sidebar_collapse_label": "Collapse",
"skip_to_content": "Skip to main content",
"header_open_nav": "Open navigation",
"header_close_nav": "Close navigation",
"header_user_menu": "User menu",
Expand Down
35 changes: 35 additions & 0 deletions src/lib/components/layout/sidebar/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { Component } from 'svelte';
import IconChevronLeft from 'virtual:icons/material-symbols/chevron-left';
import IconChevronRight from 'virtual:icons/material-symbols/chevron-right';
import { MediaQuery } from 'svelte/reactivity';
import type { NavItem } from '$lib/types/navigation.js';
import { getNavSections } from './nav-items.js';

Expand All @@ -20,6 +21,10 @@

const sections = $derived(getNavSections({ storageBrowserEnabled }));

// make mobile navbar not focusable if its hidden
const isDesktop = new MediaQuery('min-width: 64rem', true);
const hiddenFromUser = $derived(!isDesktop.current && !mobileOpen);

function isActive(href: string): boolean {
if (href === '/') return page.url.pathname === '/';
return page.url.pathname.startsWith(href);
Expand All @@ -40,8 +45,35 @@
}

let sidebarEl: HTMLElement | undefined = $state();

$effect(() => {
if (isDesktop.current || !mobileOpen || !sidebarEl) return;
sidebarEl.focus();
});

function handleWindowKeydown(event: KeyboardEvent) {
if (isDesktop.current || !mobileOpen) return;

if (event.key === 'Escape') {
event.preventDefault();
mobileOpen = false;
}
}

// Tabbing off either end of the open panel would land on the page behind the
// backdrop, so send focus back to the top of the panel instead.
function handleFocusOut(event: FocusEvent) {
if (isDesktop.current || !mobileOpen) return;

const next = event.relatedTarget as Node | null;
if (next && sidebarEl?.contains(next)) return;

sidebarEl?.focus();
}
</script>

<svelte:window onkeydown={handleWindowKeydown} />

{#snippet navIcon(IconComponent: Component)}
<IconComponent class="h-5 w-5 shrink-0" aria-hidden="true" />
{/snippet}
Expand All @@ -59,8 +91,11 @@
<!-- Sidebar -->
<aside
bind:this={sidebarEl}
onfocusout={handleFocusOut}
id="sidebar"
aria-label={m.sidebar_label()}
tabindex="-1"
inert={hiddenFromUser}
class="border-base-300 bg-base-200 fixed inset-y-0 left-0 z-50 flex flex-col border-r
transition-[transform,width] duration-200 ease-out
lg:relative lg:inset-auto lg:z-auto lg:translate-x-0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

<div class="ml-auto">
<button
class="btn btn-ghost btn-xs gap-1 text-white"
class="btn btn-ghost btn-xs gap-1"
title={m.storage_action_refresh()}
onclick={() => storage.refresh()}
disabled={storage.loading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
<button
class="
tooltip tooltip-bottom btn btn-ghost btn-xs group/pin z-60 size-5 p-0
{pinned ? 'hover:text-error' : 'hover:text-white'}
{pinned ? 'hover:text-error' : 'hover:text-primary'}
"
data-tip={pinned ? m.storage_action_unpin() : m.storage_action_pin()}
aria-label={pinned ? m.storage_action_unpin() : m.storage_action_pin()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<StorageConnectionSidebar onselect={selectConnection} />

<div class="min-w-0 flex-1">
<h1 class="mb-1 text-xl font-semibold">{m.storage_connect_title()}</h1>
<h2 class="mb-1 text-xl font-semibold">{m.storage_connect_title()}</h2>
<p class="text-base-content/60 mb-6 text-sm">{m.storage_connect_subtitle()}</p>

<form
Expand Down
2 changes: 2 additions & 0 deletions src/lib/components/trino/StatementResult.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,13 @@
{m.trino_export_csv()}
</button>
<label
for="{uid}-include-headers"
class="
flex cursor-pointer items-center gap-1 text-xs whitespace-nowrap
"
>
<input
id="{uid}-include-headers"
type="checkbox"
class="checkbox checkbox-xs checkbox-primary size-3.5"
checked={includeHeaders}
Expand Down
17 changes: 16 additions & 1 deletion src/routes/(app)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@
</svelte:head>

<div class="bg-base-100 flex h-dvh overflow-hidden">
<!-- Bypass block (WCAG 2.4.1): first tab stop on every page. -->
<a
href="#main-content"
class="
btn btn-primary btn-sm sr-only
focus:not-sr-only focus:absolute focus:top-3 focus:left-3 focus:z-100
"
>
{m.skip_to_content()}
</a>

<Sidebar
bind:collapsed={sidebarCollapsed}
bind:mobileOpen
Expand All @@ -57,7 +68,11 @@
onToggleMobile={() => (mobileOpen = !mobileOpen)}
/>

<main class="bg-base-200 flex-1 overflow-auto p-6">
<main
id="main-content"
tabindex="-1"
class="bg-base-200 flex-1 overflow-auto p-6 focus:outline-none"
>
{@render children()}
</main>
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/routes/(app)/storage/+error.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@
>
{m.storage_error_title()}
</p>
<h1 class="text-base-content text-3xl font-bold">
<p class="text-base-content text-3xl font-bold">
{page.status}
</h1>
<p class="text-base-content/70 mt-2 max-w-sm text-sm">
{errorMessage ?? page.error?.message ?? ''}
</p>
<h2 class="text-base-content/70 mt-2 max-w-sm text-sm">
{errorMessage ?? page.error?.message ?? ''}
</h2>
</div>

<div class="flex flex-wrap items-center justify-center gap-3">
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/storage/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<span class="loading loading-md loading-spinner text-primary" aria-hidden="true"></span>
</div>
{/if}
<h1 class="mb-1 text-xl font-semibold">{m.storage_buckets_label()}</h1>
<h2 class="mb-1 text-xl font-semibold">{m.storage_buckets_label()}</h2>
<p class="text-base-content/60 mb-6 text-sm">{m.storage_buckets_subtitle()}</p>
<BucketGrid buckets={storage.buckets} />
<RecentItems />
Expand Down
6 changes: 3 additions & 3 deletions src/routes/(app)/storage/[bucket]/[...prefix]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@
>
{m.storage_error_title()}
</p>
<h1 class="text-base-content text-3xl font-bold">403</h1>
<p class="text-base-content/70 mt-2 max-w-sm text-sm">
<p class="text-base-content text-3xl font-bold">403</p>
<h2 class="text-base-content/70 mt-2 max-w-sm text-sm">
{m.storage_error_access_denied({ bucket: data.bucket })}
</p>
</h2>
</div>

<div class="flex flex-wrap items-center justify-center gap-3">
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/storage/connections/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
{m.storage_connections_back()}
</a>

<h1 class="mb-1 text-xl font-semibold">{m.storage_connections_title()}</h1>
<h2 class="mb-1 text-xl font-semibold">{m.storage_connections_title()}</h2>
<p class="text-base-content/60 mb-6 text-sm">{m.storage_connections_subtitle()}</p>

{#if !loaded}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
</div>
</Modal>

<h1 class="mb-1 text-xl font-semibold">{m.storage_connection_edit_title()}</h1>
<h2 class="mb-1 text-xl font-semibold">{m.storage_connection_edit_title()}</h2>

{#if !loaded}
<div class="flex items-center justify-center py-12">
Expand Down
Loading