refactor(plugin-md-power): improve a11y in Abbreviation

This commit is contained in:
pengzhanbo 2025-04-01 21:26:51 +08:00
parent 86eefbab9b
commit dc331337b7
2 changed files with 33 additions and 8 deletions

View File

@ -1,11 +1,27 @@
<script setup lang="ts">
import type { CSSProperties } from 'vue'
import { onClickOutside, useMediaQuery, useToggle } from '@vueuse/core'
import { nextTick, ref, useTemplateRef, watch } from 'vue'
const show = ref(false)
import '@vuepress/helper/transition/fade-in.css'
const [show, toggle] = useToggle(false)
const el = useTemplateRef<HTMLSpanElement>('el')
const tooltip = useTemplateRef<HTMLSpanElement>('tooltip')
const styles = ref<CSSProperties>()
const isMobile = useMediaQuery('(max-width: 768px)')
const showTooltip = () => toggle(true)
const hiddenTooltip = () => toggle(false)
onClickOutside(el, () => {
if (isMobile.value)
hiddenTooltip()
}, {
ignore: [tooltip],
})
watch(show, () => nextTick(() => {
if (__VUEPRESS_SSR__)
return
@ -33,16 +49,23 @@ watch(show, () => nextTick(() => {
<template>
<span
ref="el"
class="vp-abbr"
@mouseenter="show = true"
@mouseleave="show = false"
@focus="show = true"
@blur="show = false"
role="tooltip"
tabindex="0"
v-bind="isMobile ? {
onClick: showTooltip,
} : {
onMouseenter: showTooltip,
onMouseleave: hiddenTooltip,
onFocus: showTooltip,
onBlur: hiddenTooltip,
}"
>
<slot />
<ClientOnly>
<Transition name="fade">
<span v-show="show" ref="tooltip" class="vp-abbr-tooltip ignore-header" :style="styles">
<Transition name="fade-in">
<span v-show="show" ref="tooltip" class="vp-abbr-tooltip ignore-header" :style="styles" aria-hidden="true">
<slot name="tooltip" />
</span>
</Transition>

View File

@ -177,6 +177,8 @@ export const abbrPlugin: PluginSimple = (md) => {
md.renderer.rules.abbreviation = (tokens, idx, _, env) => {
const { content, info } = tokens[idx]
return `<Abbreviation>${content}${info ? `<template #tooltip>${md.renderInline(info, cleanMarkdownEnv(env))}</template>` : ''}</Abbreviation>`
const rendered = md.renderInline(info, cleanMarkdownEnv(env))
const label = rendered.replace(/<[^>]*>/g, '')
return `<Abbreviation aria-label="${label}">${content}${info ? `<template #tooltip>${rendered}</template>` : ''}</Abbreviation>`
}
}