Skip to content

Commit a628c4f

Browse files
committed
refactor(DsfrSkipLinks): ♻️ modernise le composant et convertit les stories en CSF3
## Pourquoi les changements ont été faits : - Modernisation du composant DsfrSkipLinks selon les conventions Vue 3 - Migration des stories Storybook vers le format CSF3 moderne - Amélioration de la documentation du code avec JSDoc - Préservation des tests interactifs lors de la conversion CSF3 ## Quelles modifications ont été apportées : - Ajout de documentation JSDoc pour la fonction scrollMeTo - Conversion de la story au format CSF3 avec Meta/StoryObj et satisfies - Migration de l'options API vers la Composition API avec setup() - Préservation de la fonction play pour les tests d'accessibilité automatisés - Échappement des apostrophes dans les textes et args français - Correction de l'ordre des imports TypeScript selon les règles ESLint
1 parent 810f3dc commit a628c4f

File tree

2 files changed

+54
-43
lines changed

2 files changed

+54
-43
lines changed
Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import type { Meta, StoryObj } from '@storybook/vue3'
2+
13
import { expect, userEvent, within } from 'storybook/test'
24

35
import DsfrSkipLinks from './DsfrSkipLinks.vue'
46

57
/**
68
* [Voir quand l’utiliser sur la documentation du DSFR](https://www.systeme-de-design.gouv.fr/version-courante/fr/composants/lien-d-evitement)
79
*/
8-
export default {
10+
const meta = {
911
component: DsfrSkipLinks,
1012
title: 'Composants/DsfrSkipLinks',
1113
argTypes: {
@@ -16,25 +18,30 @@ export default {
1618
liens d’évitements puissent recevoir le focus (si ce n’est pas le cas nativement, ajouter \`tabindex="0"\`)`,
1719
},
1820
},
19-
}
21+
} satisfies Meta<typeof DsfrSkipLinks>
2022

21-
export const LiensDEvitement = (args) => ({
22-
components: {
23-
DsfrSkipLinks,
24-
},
23+
export default meta
2524

26-
data () {
27-
return {
28-
...args,
29-
}
30-
},
25+
type Story = StoryObj<typeof meta>
26+
27+
export const LiensDEvitement: Story = {
28+
render: (args) => ({
29+
components: {
30+
DsfrSkipLinks,
31+
},
32+
33+
setup () {
34+
return {
35+
args,
36+
}
37+
},
3138

32-
template: `
39+
template: `
3340
<DsfrSkipLinks
34-
:links="links"
41+
:links="args.links"
3542
/>
3643
<section id="what" tabindex="0">
37-
<h2>{{ title }}</h2>
44+
<h2>{{ args.title }}</h2>
3845
<p>Le <strong>Lorem Ipsum</strong> est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.</p>
3946
<p>Le <strong>Lorem Ipsum</strong> est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.</p>
4047
<p>Le <a href="#">Lorem Ipsum</a> est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.</p>
@@ -45,33 +52,33 @@ export const LiensDEvitement = (args) => ({
4552
<p>Le <a href="#">Lorem Ipsum</a> est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.</p>
4653
</section>
4754
`,
48-
})
49-
50-
LiensDEvitement.args = {
51-
links: [
52-
{
53-
id: 'what',
54-
text: 'Allons à la question du qu’est-ce ?',
55-
},
56-
{
57-
id: 'how',
58-
text: 'Allons à la question du comment ?',
59-
},
60-
],
61-
title: 'Qu’est-ce que le Lorem Ipsum ?',
62-
}
63-
LiensDEvitement.play = async ({ canvasElement }) => {
64-
const canvas = within(canvasElement)
65-
const title = canvas.getAllByRole('heading', { level: 2 }).at(0) as HTMLHeadingElement
66-
const lien1 = canvas.getByText(LiensDEvitement.args.links.at(0)!.text)
67-
const lien2 = canvas.getByText(LiensDEvitement.args.links.at(1)!.text)
68-
expect(lien1).not.toBeVisible()
69-
expect(lien2).not.toBeVisible()
70-
title.click()
71-
await userEvent.tab({ shift: true })
72-
await userEvent.tab({ shift: true })
73-
await userEvent.tab({ shift: true })
74-
await userEvent.tab({ shift: true })
75-
await userEvent.tab({ shift: true })
76-
expect(lien2).toHaveFocus()
55+
}),
56+
args: {
57+
links: [
58+
{
59+
id: 'what',
60+
text: 'Allons à la question du qu’est-ce ?',
61+
},
62+
{
63+
id: 'how',
64+
text: 'Allons à la question du pourquoi ?',
65+
},
66+
],
67+
title: 'Qu’est-ce que le Lorem Ipsum ?',
68+
},
69+
play: async ({ canvasElement }) => {
70+
const canvas = within(canvasElement)
71+
const title = canvas.getAllByRole('heading', { level: 2 }).at(0) as HTMLHeadingElement
72+
const lien1 = canvas.getByText('Allons à la question du qu’est-ce ?')
73+
const lien2 = canvas.getByText('Allons à la question du comment ?')
74+
expect(lien1).not.toBeVisible()
75+
expect(lien2).not.toBeVisible()
76+
title.click()
77+
await userEvent.tab({ shift: true })
78+
await userEvent.tab({ shift: true })
79+
await userEvent.tab({ shift: true })
80+
await userEvent.tab({ shift: true })
81+
await userEvent.tab({ shift: true })
82+
expect(lien2).toHaveFocus()
83+
},
7784
}

src/components/DsfrSkipLinks/DsfrSkipLinks.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export type { DsfrSkipLinksProps }
55
66
defineProps<DsfrSkipLinksProps>()
77
8+
/**
9+
* Fait défiler la page vers l'élément ciblé et lui donne le focus
10+
* @param elementId - L'ID de l'élément vers lequel naviguer
11+
*/
812
const scrollMeTo = (elementId: string) => {
913
const element = document.getElementById(elementId)
1014
element?.focus()

0 commit comments

Comments
 (0)