Skip to content

Commit

Permalink
docs: accessibility improvement (element-plus#11825)
Browse files Browse the repository at this point in the history
* docs: accessibility improvement for navbar

* docs: accessibility improvement for demo

* refactor: replace ElPopover with ElDropdown

* docs: accessibility improvement for nav-full

* docs: accessibility improvement for back-to-top

* feat: add skip link that jump to the content
  • Loading branch information
tolking authored Mar 10, 2023
1 parent a67b52c commit a4063fd
Show file tree
Hide file tree
Showing 23 changed files with 325 additions and 84 deletions.
3 changes: 3 additions & 0 deletions docs/.vitepress/crowdin/en-US/component/api-typing.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"detail": "Type details"
}
4 changes: 4 additions & 0 deletions docs/.vitepress/crowdin/en-US/component/navbar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"mobile-nav": "mobile navigation",
"theme-toggler": "toggle dark mode"
}
3 changes: 3 additions & 0 deletions docs/.vitepress/crowdin/en-US/component/skip-link.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "Skip to content"
}
3 changes: 2 additions & 1 deletion docs/.vitepress/crowdin/en-US/component/translation.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"help": "Help Translate 😉"
"help": "Help Translate 😉",
"language": "Choose the language that you want"
}
4 changes: 2 additions & 2 deletions docs/.vitepress/vitepress/components/common/vp-switch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
</script>

<template>
<div class="switch" role="switch">
<button class="switch" role="switch">
<div class="switch__action">
<div class="switch__icon">
<slot />
</div>
</div>
</div>
</button>
</template>
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
<script setup lang="ts">
import CommonThemeToggler from '../common/vp-theme-toggler.vue'
import { toggleDark } from '../../composables/dark'
import { isDark, toggleDark } from '../../composables/dark'
import { useNavbarLocale } from '../../composables/navbar-locale'
const locale = useNavbarLocale()
</script>

<template>
<div class="full-screen-theme-toggler">
<span>Theme</span>
<CommonThemeToggler @click="toggleDark()" />
<CommonThemeToggler
:aria-label="locale['theme-toggler']"
:aria-checked="isDark"
@click="toggleDark()"
/>
</div>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ExpandIcon from '../icons/expand.vue'
const emit = defineEmits(['close'])
const { languageMap, langs, lang, switchLang, helpTranslate } = useTranslation()
const { languageMap, langs, lang, switchLang, locale } = useTranslation()
const [show, toggle] = useToggle()
Expand All @@ -19,9 +19,12 @@ const onSwitchLang = (lang: string) => {
<template>
<div class="full-screen-translation">
<ElButton
:aria-label="locale.language"
:aria-expanded="show"
aria-controls="translation-items"
style="width: 100%; color: var(--text-color)"
text
@click="toggle"
@click="toggle()"
>
<div class="translation-toggler">
<span> Translations </span>
Expand All @@ -35,14 +38,18 @@ const onSwitchLang = (lang: string) => {
v-for="l in langs"
:key="l"
:class="{ active: l === lang }"
tabindex="0"
role="link"
class="translation-item"
@click="onSwitchLang(l)"
@keydown.prevent.enter="onSwitchLang(l)"
@keydown.prevent.space="onSwitchLang(l)"
>
{{ languageMap[l] }}
</p>
<p class="translation-item">
<VPLink :href="`/${lang}/guide/translation`">
{{ helpTranslate }}
{{ locale.help }}
</VPLink>
</p>
</div>
Expand Down
13 changes: 12 additions & 1 deletion docs/.vitepress/vitepress/components/globals/vp-api-typing.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
<script setup lang="ts">
import { computed } from 'vue'
import { Warning } from '@element-plus/icons-vue'
import { useLang } from '../../composables/lang'
import apiTypingLocale from '../../../i18n/component/api-typing.json'
defineProps({
type: String,
details: String,
})
const lang = useLang()
const detail = computed(() => apiTypingLocale[lang.value].detail)
</script>

<template>
Expand All @@ -14,7 +20,12 @@ defineProps({
</code>
<ClientOnly>
<ElTooltip v-if="details" effect="light" trigger="click">
<ElButton text :icon="Warning" class="p-2 text-4" />
<ElButton
text
:icon="Warning"
:aria-label="detail"
class="p-2 text-4"
/>
<template #content>
<slot>
<div class="m-1">
Expand Down
14 changes: 12 additions & 2 deletions docs/.vitepress/vitepress/components/navbar/vp-hamburger.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
<script setup lang="ts">
import { useNavbarLocale } from '../../composables/navbar-locale'
defineProps<{
active: boolean
}>()
const locale = useNavbarLocale()
</script>

<template>
<div :class="{ 'menu-hamburger': true, active }" role="button">
<button
:class="{ active }"
:aria-label="locale['mobile-nav']"
:aria-expanded="active"
aria-controls="full-screen"
class="reset-btn menu-hamburger"
>
<span class="hamburger-1" />
<span class="hamburger-2" />
<span class="hamburger-3" />
</div>
</button>
</template>
11 changes: 9 additions & 2 deletions docs/.vitepress/vitepress/components/navbar/vp-theme-toggler.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
<script setup lang="ts">
import { toggleDark } from '../../composables/dark'
import { isDark, toggleDark } from '../../composables/dark'
import { useNavbarLocale } from '../../composables/navbar-locale'
import CommonThemeToggler from '../common/vp-theme-toggler.vue'
const locale = useNavbarLocale()
</script>

<template>
<div class="theme-toggler-content">
<CommonThemeToggler @click="() => toggleDark()" />
<CommonThemeToggler
:aria-label="locale['theme-toggler']"
:aria-checked="isDark"
@click="() => toggleDark()"
/>
</div>
</template>

Expand Down
82 changes: 45 additions & 37 deletions docs/.vitepress/vitepress/components/navbar/vp-translation.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
<script setup lang="ts">
import VPLink from '../common/vp-link.vue'
import { useRouter } from 'vitepress'
import { useTranslation } from '../../composables/translation'
const { switchLang, languageMap, langs, lang, helpTranslate } = useTranslation()
const router = useRouter()
const { switchLang, languageMap, langs, lang, locale } = useTranslation()
const toTranslation = () => {
router.go(`/${lang.value}/guide/translation`)
}
</script>

<template>
<div class="translation-container">
<ClientOnly>
<ElPopover
:show-arrow="false"
trigger="hover"
popper-class="translation-popup"
>
<template #reference>
<ElIcon :size="24">
<i-ri-translate-2 />
</ElIcon>
<ElDropdown popper-class="translation-popup" role="navigation">
<ElIcon :size="24" :aria-label="locale.language">
<i-ri-translate-2 />
</ElIcon>
<template #dropdown>
<ElDropdownMenu>
<ElDropdownItem
v-for="l in langs"
:key="l"
:class="{ language: true, selected: l === lang }"
@click="switchLang(l)"
>
{{ languageMap[l] }}
</ElDropdownItem>
<ElDropdownItem class="language selected" @click="toTranslation">
{{ locale.help }}
</ElDropdownItem>
</ElDropdownMenu>
</template>
<div
v-for="l in langs"
:key="l"
:class="{ language: true, selected: l === lang }"
@click="switchLang(l)"
>
{{ languageMap[l] }}
</div>
<div class="language">
<VPLink :href="`/${lang}/guide/translation`">
{{ helpTranslate }}
</VPLink>
</div>
</ElPopover>
</ElDropdown>
</ClientOnly>
</div>
</template>
Expand All @@ -46,21 +47,28 @@ const { switchLang, languageMap, langs, lang, helpTranslate } = useTranslation()
@include respond-to('md') {
display: block;
}
}
</style>

<style lang="scss">
.el-dropdown__popper.translation-popup {
--el-bg-color-overlay: var(--bg-color);
--el-popper-border-radius: 8px;
--el-border-color-light: transparent;
@at-root .translation-popup.el-popper {
box-shadow: var(--el-box-shadow);
padding: 7px 0;
min-width: 192px;
transition: background-color 0.5s;
.language {
cursor: pointer;
padding: 0 16px;
line-height: 28px;
&.selected {
color: var(--brand-color);
}
.el-popper__arrow {
display: none;
}
.link-item {
font-weight: 500;
}
.language {
padding: 0 16px;
line-height: 28px;
&.selected {
--el-text-color-regular: var(--brand-color);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import ToggleButton from '../icons/toggle-button.vue'
</script>

<template>
<div class="sidebar-button flex items-center">
<button class="reset-btn sidebar-button flex items-center">
<ElIcon :size="20" class="mr-2">
<ToggleButton />
</ElIcon>
<span class="leading-6">Menu</span>
</div>
</button>
</template>

<style>
Expand Down
18 changes: 16 additions & 2 deletions docs/.vitepress/vitepress/components/vp-app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { onMounted } from 'vue'
import { ElMessageBox } from 'element-plus'
import nprogress from 'nprogress'
import dayjs from 'dayjs'
import { isClient, useStorage, useToggle } from '@vueuse/core'
import { isClient, useEventListener, useStorage, useToggle } from '@vueuse/core'
import { useSidebar } from '../composables/sidebar'
import { useToggleWidgets } from '../composables/toggle-widgets'
import { useLang } from '../composables/lang'
import { breakpoints } from '../constant'
import VPOverlay from './vp-overlay.vue'
import VPSkipLink from './vp-skip-link.vue'
import VPNav from './vp-nav.vue'
import VPSubNav from './vp-subnav.vue'
import VPSidebar from './vp-sidebar.vue'
Expand All @@ -33,6 +34,14 @@ useToggleWidgets(isSidebarOpen, () => {
}
})
useEventListener('keydown', (e) => {
if (!isClient) return
if (e.key === 'Escape' && isSidebarOpen.value) {
toggleSidebar(false)
document.querySelector<HTMLButtonElement>('.sidebar-button')?.focus()
}
})
const userPrefer = useStorage<boolean | string>(USER_PREFER_GITHUB_PAGE, null)
onMounted(async () => {
Expand Down Expand Up @@ -107,13 +116,18 @@ onMounted(async () => {

<template>
<div class="App">
<VPSkipLink />
<VPOverlay
class="overlay"
:show="isSidebarOpen"
@click="toggleSidebar(false)"
/>
<VPNav />
<VPSubNav v-if="hasSidebar" @open-menu="toggleSidebar(true)" />
<VPSubNav
v-if="hasSidebar"
:is-sidebar-open="isSidebarOpen"
@open-menu="toggleSidebar(true)"
/>
<VPSidebar :open="isSidebarOpen" @close="toggleSidebar(false)">
<template #top>
<VPSponsors />
Expand Down
5 changes: 4 additions & 1 deletion docs/.vitepress/vitepress/components/vp-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ onUpdated(() => {
</script>

<template>
<main :class="{ 'page-content': true, 'has-sidebar': hasSidebar }">
<main
id="page-content"
:class="{ 'page-content': true, 'has-sidebar': hasSidebar }"
>
<VPNotFound v-if="isNotFound" />
<VPHeroContent v-else-if="isHeroPost" />
<VPDocContent v-else>
Expand Down
Loading

0 comments on commit a4063fd

Please sign in to comment.