mirror of https://github.com/vuejs/vitepress
fix(theme): preserve alt overrides for themed images (#5457)
parent
23361e2493
commit
61c0cbbefe
@ -0,0 +1,38 @@
|
|||||||
|
describe('themeable image alt overrides', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await goto('/theme-image/')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.each(['light', 'dark'])('uses the alt prop in %s mode', async (mode) => {
|
||||||
|
await page.evaluate((mode) => {
|
||||||
|
document.documentElement.classList.toggle('dark', mode === 'dark')
|
||||||
|
}, mode)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await page.locator('.image-override img:visible').getAttribute('alt')
|
||||||
|
).toBe('Override description')
|
||||||
|
expect(
|
||||||
|
await page.locator('.image-decorative img:visible').getAttribute('alt')
|
||||||
|
).toBe('')
|
||||||
|
expect(
|
||||||
|
await page.locator('.image-fallback img:visible').getAttribute('alt')
|
||||||
|
).toBe('Image description')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('updates both images when the alt prop changes', async () => {
|
||||||
|
const descriptions = () =>
|
||||||
|
page
|
||||||
|
.locator('.image-override img')
|
||||||
|
.evaluateAll((images) =>
|
||||||
|
images.map((image) => image.getAttribute('alt'))
|
||||||
|
)
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Update description' }).click()
|
||||||
|
await expect
|
||||||
|
.poll(descriptions)
|
||||||
|
.toEqual(['Updated description', 'Updated description'])
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Clear description' }).click()
|
||||||
|
await expect.poll(descriptions).toEqual(['', ''])
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { VPImage } from 'vitepress/theme'
|
||||||
|
|
||||||
|
const description = ref('Override description')
|
||||||
|
const image = {
|
||||||
|
light: '/pwa_light.svg',
|
||||||
|
dark: '/pwa_dark.svg',
|
||||||
|
alt: 'Image description'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# Themeable image descriptions
|
||||||
|
|
||||||
|
<div class="image-override">
|
||||||
|
<VPImage :image :alt="description" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="image-decorative">
|
||||||
|
<VPImage :image alt="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="image-fallback">
|
||||||
|
<VPImage :image />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button @click="description = 'Updated description'">Update description</button>
|
||||||
|
<button @click="description = ''">Clear description</button>
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
// @ts-expect-error the unit typecheck uses tsc; Vite compiles this SFC at runtime
|
||||||
|
import VPImage from 'client/theme-default/components/VPImage.vue'
|
||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
import { renderToString } from 'vue/server-renderer'
|
||||||
|
|
||||||
|
vi.mock('vitepress', () => ({ withBase: (path: string) => path }))
|
||||||
|
|
||||||
|
const images = [
|
||||||
|
{ name: 'string', image: 'logo.svg', fallback: '', count: 1 },
|
||||||
|
{
|
||||||
|
name: 'single source',
|
||||||
|
image: { src: 'logo.svg', alt: 'Image description' },
|
||||||
|
fallback: 'Image description',
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'themed sources',
|
||||||
|
image: { light: 'light.svg', dark: 'dark.svg', alt: 'Image description' },
|
||||||
|
fallback: 'Image description',
|
||||||
|
count: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'themed sources without alt',
|
||||||
|
image: { light: 'light.svg', dark: 'dark.svg' },
|
||||||
|
fallback: '',
|
||||||
|
count: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
describe.each(images)('VPImage with $name', ({ image, fallback, count }) => {
|
||||||
|
test.each(['Override description', '', undefined])(
|
||||||
|
'respects the alt prop %j',
|
||||||
|
async (alt) => {
|
||||||
|
const html = await renderToString(createSSRApp(VPImage, { image, alt }))
|
||||||
|
const descriptions = [...html.matchAll(/ alt(?:="([^"]*)")?/g)].map(
|
||||||
|
([, value]) => value ?? ''
|
||||||
|
)
|
||||||
|
expect(descriptions).toEqual(Array(count).fill(alt ?? fallback))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
Loading…
Reference in new issue