Skip to content

Commit 080b6db

Browse files
committed
refactor(tabs): ♻️ modernise DsfrTabItem avec defineSlots et story CSF3
## Pourquoi les changements ont été faits : - Moderniser le composant DsfrTabItem pour utiliser les dernières conventions Vue 3 - Améliorer la documentation des slots et événements disponibles pour les développeurs - Convertir la story Storybook au format CSF3 moderne pour une meilleure maintenabilité ## Quelles modifications ont été apportées : - Ajout de defineSlots avec documentation du slot par défaut - Conversion de la story TitreDOnglet au format CSF3 avec Meta/StoryObj - Remplacement de data() par setup() - Utilisation de Meta et StoryObj pour le typage TypeScript - Ajout de JSDoc au-dessus de chaque événement dans defineEmits - Suppression des descriptions d'événements des argTypes (désormais dans la JSDoc du composant) - Conservation de toute la logique de gestion des événements et injection existante
1 parent 937a690 commit 080b6db

File tree

2 files changed

+43
-47
lines changed

2 files changed

+43
-47
lines changed
Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Meta, StoryObj } from '@storybook/vue3'
2+
13
import { setup } from '@storybook/vue3-vite'
24

35
import VIcon from '../VIcon/VIcon.vue'
@@ -9,84 +11,69 @@ setup((app) => {
911
app.component('VIcon', VIcon)
1012
})
1113

12-
export default {
14+
const meta = {
1315
component: DsfrTabItem,
1416
title: 'Composants/DsfrTabs',
1517
argTypes: {
1618
tabTitle: {
1719
control: 'object',
1820
description:
19-
'Props de `DsfrTabItem` : Titre de l’onglet `DsfrTabItem` - **Obligatoire**',
21+
'Titre de l’onglet `DsfrTabItem` - **Obligatoire**',
22+
23+
table: {
24+
category: 'Props du parent (DsfrTabs)'
25+
}
2026
},
2127
panelId: {
2228
control: 'text',
2329
description:
24-
'Props de `DsfrTabItem` et `DsfrTabContent` : Identifiant de l’élément correspondant au contenu de l’onglet à afficher; doit être identique à la props `tab-id` du `DsfrTabItem` correspondant - **Obligatoire**',
30+
'Props de `DsfrTabItem` et `DsfrTabContent` : Identifiant de l’élément correspondant au contenu de l’onglet à afficher ; doit être identique à la props `tab-id` du `DsfrTabItem` correspondant - **Obligatoire**',
2531
},
2632
tabId: {
2733
control: 'text',
2834
description:
29-
'Props de `DsfrTabItem` et `DsfrTabContent` : Identifiant du titre de l’onglet ̛ ; doit être identique à la props `panel-id` du `DsfrTabContent` correspondant - **Obligatoire**',
35+
'Props de `DsfrTabItem` et `DsfrTabContent` : Identifiant du titre de l’onglet ̛ ; doit être identique à la props `panel-id` du `DsfrTabContent` correspondant - **Obligatoire**',
3036
},
3137
icon: {
3238
control: 'text',
33-
description: 'Props de `DsfrTabItem` : Nom de l’icône à afficher',
34-
},
35-
selected: {
36-
control: 'boolean',
37-
description: 'Indique si le titre de cet onglet est celui qui est actif',
38-
},
39-
click: {
40-
description:
41-
'Événement déclenché au clic sur le titre de l’onglet. Passe en argument l’événement natif \'click\' (dans lequel on peut récuperer l’élément dans la propriété `target` et l’id dans `target.id`)',
42-
},
43-
next: {
44-
description:
45-
'Événement déclenché à la pression sur la touche Flèche droite ou Flèche bas si le focus est sur le bouton de ce titre d’onglet',
46-
},
47-
previous: {
48-
description:
49-
'Événement déclenché à la pression sur la touche Flèche gauche ou Flèche haut si le focus est sur le bouton de ce titre d’onglet',
50-
},
51-
first: {
52-
description:
53-
'Événement déclenché à la pression sur la touche `Début` (`Home`) si le focus est sur le bouton de ce titre d’onglet',
54-
},
55-
last: {
56-
description:
57-
'Événement déclenché à la pression sur la touche `End` (`Fin`) si le focus est sur le bouton de ce titre d’onglet',
39+
description: 'Props de `DsfrTabItem` : Nom de l’icône à afficher',
5840
},
5941
},
60-
}
42+
} satisfies Meta<typeof DsfrTabItem>
6143

62-
export const TitreDOnglet = (args) => ({
63-
components: {
64-
DsfrTabs,
65-
DsfrTabItem,
66-
},
44+
export default meta
6745

68-
data () {
69-
return args
70-
},
46+
type Story = StoryObj<typeof meta>
47+
48+
export const TitreDOnglet: Story = {
49+
render: (args) => ({
50+
components: {
51+
DsfrTabs,
52+
DsfrTabItem,
53+
},
54+
55+
setup () {
56+
return args
57+
},
7158

72-
template: `
59+
template: `
7360
<DsfrTabs :model-value="0">
7461
<template #tab-items>
7562
<DsfrTabItem
7663
:panel-id="panelId"
7764
:tab-id="tabId"
7865
:icon="icon"
79-
:selected="true"
8066
>
8167
{{ tabTitle }}
8268
</DsfrTabItem>
8369
</template>
8470
</DsfrTabs>
8571
`,
86-
})
87-
TitreDOnglet.args = {
88-
panelId: 'tab-content-0',
89-
tabId: 'tab-0',
90-
icon: 'ri-checkbox-circle-line',
91-
tabTitle: 'Titre onglet seul',
72+
}),
73+
args: {
74+
panelId: 'tab-content-0',
75+
tabId: 'tab-0',
76+
icon: 'ri-checkbox-circle-line',
77+
tabTitle: 'Titre onglet seul',
78+
},
9279
}

src/components/DsfrTabs/DsfrTabItem.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,23 @@ const props = withDefaults(defineProps<DsfrTabItemProps>(), {
1515
})
1616
1717
const emit = defineEmits<{
18+
/** Émis au clic sur le titre de l'onglet. Passe en argument l'événement natif 'click' (dans lequel on peut récuperer l'élément dans la propriété `target` et l'id dans `target.id`) */
1819
click: [tabId: string]
20+
/** Émis à la pression sur la touche Flèche droite ou Flèche bas si le focus est sur le bouton de ce titre d'onglet */
1921
next: []
22+
/** Émis à la pression sur la touche Flèche gauche ou Flèche haut si le focus est sur le bouton de ce titre d'onglet */
2023
previous: []
24+
/** Émis à la pression sur la touche `Début` (`Home`) si le focus est sur le bouton de ce titre d'onglet */
2125
first: []
26+
/** Émis à la pression sur la touche `End` (`Fin`) si le focus est sur le bouton de ce titre d'onglet */
2227
last: []
2328
}>()
2429
30+
defineSlots<{
31+
/** Slot par défaut pour le contenu de l’onglet. Sera dans `<button class="fr-tabs__tab">` */
32+
default?: () => any
33+
}>()
34+
2535
const button = ref<HTMLButtonElement | null>(null)
2636
2737
const keyToEventDict = {
@@ -78,7 +88,6 @@ watch(isVisible, () => {
7888
:name="icon"
7989
/>
8090
</span>
81-
<!-- @slot Slot par défaut pour le contenu de l’onglet. Sera dans `<button class="fr-tabs__tab">` -->
8291
<slot />
8392
</button>
8493
</li>

0 commit comments

Comments
 (0)