feat(theme): a11y improvements

pull/2104/head
Evan You 2 years ago
parent 6ca34c4236
commit 3b6a6d1abd

@ -5,7 +5,7 @@ describe('test multi sidebar sort root', () => {
test('using / sidebar', async () => { test('using / sidebar', async () => {
const sidebarLocator = page.locator( const sidebarLocator = page.locator(
'.VPSidebarItem.level-0 > .item > .link > .text' '.VPSidebarItem.level-0 > .item > .text'
) )
const sidebarContent = await sidebarLocator.allTextContents() const sidebarContent = await sidebarLocator.allTextContents()
@ -27,7 +27,7 @@ describe('test multi sidebar sort order', () => {
test('using /multi-sidebar/ sidebar', async () => { test('using /multi-sidebar/ sidebar', async () => {
const sidebarLocator = page.locator( const sidebarLocator = page.locator(
'.VPSidebarItem.level-0 > .item > .link > .text' '.VPSidebarItem.level-0 > .item > .text'
) )
const sidebarContent = await sidebarLocator.allTextContents() const sidebarContent = await sidebarLocator.allTextContents()

@ -29,7 +29,7 @@ const showFooter = computed(() => {
<div v-if="hasEditLink || hasLastUpdated" class="edit-info"> <div v-if="hasEditLink || hasLastUpdated" class="edit-info">
<div v-if="hasEditLink" class="edit-link"> <div v-if="hasEditLink" class="edit-link">
<VPLink class="edit-link-button" :href="editLink.url" :no-icon="true"> <VPLink class="edit-link-button" :href="editLink.url" :no-icon="true">
<VPIconEdit class="edit-link-icon" /> <VPIconEdit class="edit-link-icon" aria-label="edit icon"/>
{{ editLink.text }} {{ editLink.text }}
</VPLink> </VPLink>
</div> </div>

@ -24,6 +24,7 @@ const { page } = useData()
:href="item.link" :href="item.link"
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
tabindex="0"
> >
{{ item.text }} {{ item.text }}
</VPLink> </VPLink>

@ -100,11 +100,12 @@ function poll() {
<div v-if="theme.algolia" class="VPNavBarSearch"> <div v-if="theme.algolia" class="VPNavBarSearch">
<VPAlgoliaSearchBox v-if="loaded" :algolia="theme.algolia" /> <VPAlgoliaSearchBox v-if="loaded" :algolia="theme.algolia" />
<div v-else id="docsearch" @click="load"> <div v-else id="docsearch">
<button <button
type="button" type="button"
class="DocSearch DocSearch-Button" class="DocSearch DocSearch-Button"
aria-label="Search" aria-label="Search"
@click="load"
> >
<span class="DocSearch-Button-Container"> <span class="DocSearch-Button-Container">
<svg <svg
@ -112,6 +113,7 @@ function poll() {
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
aria-label="search icon"
> >
<path <path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"

@ -41,7 +41,10 @@ const classes = computed(() => [
{ 'has-active': hasActiveLink.value } { 'has-active': hasActiveLink.value }
]) ])
function onItemClick() { function onItemInteraction(e: MouseEvent | Event) {
if ('key' in e && e.key !== 'Enter') {
return
}
!props.item.link && toggle() !props.item.link && toggle()
} }
@ -52,14 +55,27 @@ function onCaretClick() {
<template> <template>
<component :is="sectionTag" class="VPSidebarItem" :class="classes"> <component :is="sectionTag" class="VPSidebarItem" :class="classes">
<div v-if="item.text" class="item" :role="itemRole" @click="onItemClick"> <div v-if="item.text"
class="item"
:role="itemRole"
v-on="item.items ? { click: onItemInteraction, keydown: onItemInteraction } : {}"
:tabindex="item.items && 0"
>
<div class="indicator" /> <div class="indicator" />
<VPLink :tag="linkTag" class="link" :href="item.link"> <VPLink v-if="item.link" :tag="linkTag" class="link" :href="item.link">
<component :is="textTag" class="text" v-html="item.text" /> <component :is="textTag" class="text" v-html="item.text" />
</VPLink> </VPLink>
<component v-else :is="textTag" class="text" v-html="item.text" />
<div v-if="item.collapsed != null" class="caret" role="button" @click="onCaretClick">
<div v-if="item.collapsed != null"
class="caret"
role="button"
aria-label="toggle section"
@click="onCaretClick"
@keydown.enter="onCaretClick"
tabindex="0"
>
<VPIconChevronRight class="caret-icon" /> <VPIconChevronRight class="caret-icon" />
</div> </div>
</div> </div>

@ -75,15 +75,16 @@ watch(checked, (newIsDark) => {
</script> </script>
<template> <template>
<label title="toggle dark mode">
<VPSwitch <VPSwitch
class="VPSwitchAppearance" class="VPSwitchAppearance"
aria-label="toggle dark mode"
:aria-checked="checked" :aria-checked="checked"
@click="toggle" @click="toggle"
> >
<VPIconSun class="sun" /> <VPIconSun class="sun" />
<VPIconMoon class="moon" /> <VPIconMoon class="moon" />
</VPSwitch> </VPSwitch>
</label>
</template> </template>
<style scoped> <style scoped>

@ -13,7 +13,7 @@
--vp-c-gray: #8e8e93; --vp-c-gray: #8e8e93;
--vp-c-text-light-1: rgba(60, 60, 67); --vp-c-text-light-1: rgba(60, 60, 67);
--vp-c-text-light-2: rgba(60, 60, 67, 0.7); --vp-c-text-light-2: rgba(60, 60, 67, 0.75);
--vp-c-text-light-3: rgba(60, 60, 67, 0.33); --vp-c-text-light-3: rgba(60, 60, 67, 0.33);
--vp-c-text-dark-1: rgba(255, 255, 245, 0.86); --vp-c-text-dark-1: rgba(255, 255, 245, 0.86);

@ -110,10 +110,15 @@ export async function highlight(
} }
const lineOptions = attrsToLines(attrs) const lineOptions = attrsToLines(attrs)
const cleanup = (str: string) => const cleanup = (str: string) => {
str return str
.replace(preRE, (_, attributes) => `<pre ${vPre}${attributes}>`) .replace(
preRE,
(_, attributes) =>
`<pre ${vPre}${attributes.replace(' tabindex="0"', '')}>`
)
.replace(styleRE, (_, style) => _.replace(style, '')) .replace(styleRE, (_, style) => _.replace(style, ''))
}
const mustaches = new Map<string, string>() const mustaches = new Map<string, string>()

Loading…
Cancel
Save