mirror of
https://github.com/open-webui/open-webui.git
synced 2026-02-24 04:00:31 +01:00
fix(a11y): improve accessibility of top-level auth and onboarding components (#21710)
Adds critical accessibility fixes across various app components: - auth/+page: provide alt text for logo, turn on screenReader support for password input, add aria-required, hide decorative SVGs from AT - AppSidebar: wrap navigation icons in a <nav> structure, provide ARIA labels for Home and Chat icons - s/[id]/+page: convert structural divs into semantically accurate h1 heading and time element, wrap message display in main region - OnBoarding: replace flawed aria-labelledby with direct aria-label on start button - NotificationToast: provide role='status' and aria-live='polite' for proper screen reader broadcasting - ChangelogModal: add required heading semantics for structure - AddFilesPlaceholder: provide heading element role for standalone text content - ImportModal: provide aria-label for close button Addresses WCAG 4.1.3, 1.1.1, 3.3.2, and 1.3.1.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
</script>
|
||||
|
||||
<div class="px-3">
|
||||
<div class="text-center dark:text-white text-2xl font-medium z-50">
|
||||
<div class="text-center dark:text-white text-2xl font-medium z-50" role="heading" aria-level="2">
|
||||
{#if title}
|
||||
{title}
|
||||
{:else}
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
<Modal bind:show size="xl">
|
||||
<div class="px-6 pt-5 dark:text-white text-black">
|
||||
<div class="flex justify-between items-start">
|
||||
<div class="text-xl font-medium">
|
||||
<h2 class="text-xl font-medium m-0">
|
||||
{$i18n.t("What's New in")}
|
||||
{$WEBUI_NAME}
|
||||
<Confetti x={[-1, -0.25]} y={[0, 0.5]} />
|
||||
</div>
|
||||
</h2>
|
||||
<button class="self-center" on:click={closeModal} aria-label={$i18n.t('Close')}>
|
||||
<XMark className={'size-5'}>
|
||||
<p class="sr-only">{$i18n.t('Close')}</p>
|
||||
@@ -64,9 +64,9 @@
|
||||
{#if changelog}
|
||||
{#each Object.keys(changelog) as version}
|
||||
<div class=" mb-3 pr-2">
|
||||
<div class="font-semibold text-xl mb-1 dark:text-white">
|
||||
<h3 class="font-semibold text-xl mb-1 dark:text-white m-0">
|
||||
v{version} - {changelog[version].date}
|
||||
</div>
|
||||
</h3>
|
||||
|
||||
<hr class="border-gray-50/50 dark:border-gray-850/50 my-2" />
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Import')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
aria-label={$i18n.t('Close')}
|
||||
on:click={() => {
|
||||
show = false;
|
||||
}}
|
||||
|
||||
@@ -82,9 +82,9 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
class="group relative flex gap-2.5 text-left min-w-[var(--width)] w-full dark:bg-gray-850 dark:text-white bg-white text-black border border-gray-100 dark:border-gray-800 rounded-3xl px-4 py-3.5 cursor-pointer select-none"
|
||||
on:dragstart|preventDefault
|
||||
on:pointerdown={onPointerDown}
|
||||
|
||||
@@ -87,15 +87,15 @@
|
||||
<div class="flex justify-center mt-8">
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<button
|
||||
aria-labelledby="get-started"
|
||||
aria-label={$i18n.t('Get started')}
|
||||
class="relative z-20 flex p-1 rounded-full bg-white/5 hover:bg-white/10 transition font-medium text-sm"
|
||||
on:click={() => {
|
||||
getStartedHandler();
|
||||
}}
|
||||
>
|
||||
<ArrowRightCircle className="size-6" />
|
||||
<ArrowRightCircle className="size-6" aria-hidden="true" />
|
||||
</button>
|
||||
<div id="get-started" class="mt-1.5 font-primary text-base font-medium">
|
||||
<div class="mt-1.5 font-primary text-base font-medium" aria-hidden="true">
|
||||
{$i18n.t(`Get started`)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
let selected = '';
|
||||
</script>
|
||||
|
||||
<div class="min-w-[4.5rem] bg-gray-50 dark:bg-gray-950 flex gap-2.5 flex-col pt-8">
|
||||
<nav aria-label="App navigation" class="min-w-[4.5rem] bg-gray-50 dark:bg-gray-950 flex gap-2.5 flex-col pt-8">
|
||||
<div class="flex justify-center relative">
|
||||
{#if selected === 'home'}
|
||||
<div class="absolute top-0 left-0 flex h-full">
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
<Tooltip content="Home" placement="right">
|
||||
<button
|
||||
aria-label="Home"
|
||||
class=" cursor-pointer {selected === 'home' ? 'rounded-2xl' : 'rounded-full'}"
|
||||
on:click={() => {
|
||||
selected = 'home';
|
||||
@@ -44,6 +45,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
<button
|
||||
aria-label="Chat"
|
||||
class=" cursor-pointer bg-transparent"
|
||||
on:click={() => {
|
||||
selected = '';
|
||||
@@ -63,4 +65,4 @@
|
||||
<Plus className="size-4" strokeWidth="2" />
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
crossorigin="anonymous"
|
||||
src="{WEBUI_BASE_URL}/static/favicon.png"
|
||||
class="size-24 rounded-full"
|
||||
alt=""
|
||||
alt="{$WEBUI_NAME} logo"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -342,8 +342,9 @@
|
||||
placeholder={$i18n.t('Enter Your Password')}
|
||||
autocomplete={mode === 'signup' ? 'new-password' : 'current-password'}
|
||||
name="password"
|
||||
screenReader={false}
|
||||
screenReader={true}
|
||||
required
|
||||
aria-required="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -439,6 +440,7 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 48 48"
|
||||
class="size-6 mr-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill="#EA4335"
|
||||
@@ -468,6 +470,7 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 21 21"
|
||||
class="size-6 mr-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect x="1" y="1" width="9" height="9" fill="#f25022" /><rect
|
||||
x="1"
|
||||
@@ -498,6 +501,7 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="size-6 mr-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
@@ -521,6 +525,7 @@
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-6 mr-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
|
||||
@@ -161,19 +161,22 @@
|
||||
: 'max-w-5xl'} mx-auto"
|
||||
>
|
||||
<div class="px-3">
|
||||
<div class=" text-2xl font-medium line-clamp-1">
|
||||
<h1 class=" text-2xl font-medium line-clamp-1 m-0">
|
||||
{title}
|
||||
</div>
|
||||
</h1>
|
||||
|
||||
<div class="flex text-sm justify-between items-center mt-1">
|
||||
<div class="text-gray-400">
|
||||
<time
|
||||
class="text-gray-400"
|
||||
datetime={new Date(chat?.chat?.timestamp || Date.now()).toISOString()}
|
||||
>
|
||||
{dayjs(chat.chat.timestamp).format('LLL')}
|
||||
</div>
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" h-full w-full flex flex-col py-2">
|
||||
<div class=" h-full w-full flex flex-col py-2" role="main">
|
||||
<div class="w-full">
|
||||
<Messages
|
||||
className="h-full flex pt-4 pb-8 "
|
||||
|
||||
Reference in New Issue
Block a user