Skip to content

Commit f250d98

Browse files
committed
refactor(DsfrButtonGroup): ♻️ migre vers Storybook 9 et utilise defineSlots
- Utilise defineSlots avec JSDoc pour la documentation du slot - Supprime le commentaire HTML - Améliore le typage TypeScript - Met à jour les imports pour utiliser les types Meta/StoryObj depuis @storybook/vue3-vite - Corrige l'import de @storybook/test au lieu de storybook/test - Transforme la story pour utiliser render() au lieu de data() - Supprime la prop inline dépréciée des argTypes et du template - Utilise setup() pour mapper les boutons avec onClick - Échappe correctement les apostrophes dans les descriptions - Assure la conformité TypeScript avec satisfies Meta<typeof DsfrButtonGroup>
1 parent a12e1de commit f250d98

File tree

2 files changed

+70
-69
lines changed

2 files changed

+70
-69
lines changed
Lines changed: 65 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
import { expect, fn, within } from 'storybook/test'
1+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
2+
3+
import { expect, within } from '@storybook/test'
24

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

57
import DsfrButtonGroup from './DsfrButtonGroup.vue'
68

79
/**
8-
* [Voir quand lutiliser sur la documentation du DSFR](https://www.systeme-de-design.gouv.fr/version-courante/fr/composants/groupe-de-boutons)
10+
* [Voir quand l'utiliser sur la documentation du DSFR](https://www.systeme-de-design.gouv.fr/version-courante/fr/composants/groupe-de-boutons)
911
*/
10-
export default {
12+
const meta = {
1113
component: DsfrButtonGroup,
1214
title: 'Composants/DsfrButtonGroup',
1315
tags: ['bouton'],
1416
argTypes: {
1517
buttons: {
1618
control: 'object',
1719
description:
18-
'Tableau d’objets, chaque objet contiendra les props à passer à DsfrButton',
19-
},
20-
inline: {
21-
control: 'boolean',
22-
deprecated: true,
23-
description:
24-
'**Déprécié:** Indique si le groupe de boutons doit toujours apparaître en empilement horizontal. *Utiliser `inlineLayoutWhen` à la place.*',
20+
'Tableau d\'objets, chaque objet contiendra les props à passer à DsfrButton',
2521
},
2622
inlineLayoutWhen: {
2723
control: 'radio',
@@ -52,68 +48,69 @@ export default {
5248
align: {
5349
control: 'radio',
5450
options: ['default', 'center', 'right'],
55-
description: 'Indique lalignement du groupe de boutons',
51+
description: 'Indique l\'alignement du groupe de boutons',
5652
},
57-
onClick: { action: fn() },
5853
},
59-
}
54+
} satisfies Meta<typeof DsfrButtonGroup>
6055

61-
export const GroupeDeBoutons = (args) => ({
62-
components: {
63-
DsfrButtonGroup,
64-
VIcon,
65-
},
66-
data () {
67-
return {
68-
...args,
69-
buttons: args.buttons.map((btn) => ({ ...btn, onClick: args.onClick })),
70-
}
56+
export default meta
57+
58+
type Story = StoryObj<typeof meta>
59+
60+
export const GroupeDeBoutons: Story = {
61+
args: {
62+
align: 'center',
63+
inlineLayoutWhen: 'never',
64+
reverse: false,
65+
iconRight: false,
66+
size: 'medium',
67+
buttons: [
68+
{
69+
label: 'Label 1',
70+
icon: 'ri-checkbox-circle-line',
71+
},
72+
{
73+
label: 'Label 2',
74+
secondary: true,
75+
icon: 'ri-checkbox-circle-line',
76+
},
77+
{
78+
label: 'Label 3',
79+
icon: 'ri-checkbox-circle-line',
80+
},
81+
{
82+
label: 'Label 4',
83+
secondary: true,
84+
icon: 'ri-checkbox-circle-line',
85+
},
86+
],
7187
},
72-
template: `
73-
<DsfrButtonGroup
74-
:buttons="buttons"
75-
:size="size"
76-
:align="align"
77-
:inline="inline"
78-
:inline-layout-when="inlineLayoutWhen"
79-
:icon-right="iconRight"
80-
:reverse="reverse"
81-
/>
82-
`,
83-
})
84-
GroupeDeBoutons.args = {
85-
align: 'center',
86-
inlineLayoutWhen: 'never',
87-
reverse: false,
88-
iconRight: false,
89-
size: 'medium',
90-
inline: undefined,
91-
buttons: [
92-
{
93-
label: 'Label 1',
94-
icon: 'ri-checkbox-circle-line',
95-
},
96-
{
97-
label: 'Label 2',
98-
secondary: true,
99-
icon: 'ri-checkbox-circle-line',
100-
},
101-
{
102-
label: 'Label 3',
103-
icon: 'ri-checkbox-circle-line',
88+
render: (args) => ({
89+
components: {
90+
DsfrButtonGroup,
91+
VIcon,
10492
},
105-
{
106-
label: 'Label 4',
107-
secondary: true,
108-
icon: 'ri-checkbox-circle-line',
93+
setup () {
94+
const buttons = (args.buttons || []).map((btn) => ({ ...btn, onClick: () => {} }))
95+
return { args, buttons }
10996
},
110-
],
111-
}
112-
GroupeDeBoutons.play = async ({ canvasElement }) => {
113-
const canvas = within(canvasElement)
114-
const buttons = canvas.getAllByRole('button')
115-
expect(buttons).toHaveLength(4)
116-
for (const button of buttons) {
117-
expect(button).toBeVisible()
118-
}
97+
template: `
98+
<DsfrButtonGroup
99+
:buttons="buttons"
100+
:size="args.size"
101+
:align="args.align"
102+
:inline-layout-when="args.inlineLayoutWhen"
103+
:icon-right="args.iconRight"
104+
:reverse="args.reverse"
105+
/>
106+
`,
107+
}),
108+
play: async ({ canvasElement }) => {
109+
const canvas = within(canvasElement)
110+
const buttons = canvas.getAllByRole('button')
111+
expect(buttons).toHaveLength(4)
112+
for (const button of buttons) {
113+
expect(button).toBeVisible()
114+
}
115+
},
119116
}

src/components/DsfrButton/DsfrButtonGroup.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ const props = withDefaults(defineProps<DsfrButtonGroupProps>(), {
1414
align: undefined,
1515
})
1616
17+
defineSlots<{
18+
/** Slot par défaut pour le contenu de la liste de boutons. Sera dans `<ul class="fr-btns-group">` */
19+
default: () => any
20+
}>()
21+
1722
const buttonsEl = ref<HTMLUListElement | null>(null)
1823
1924
const sm = computed(() => ['sm', 'small'].includes(props.size))
@@ -85,7 +90,6 @@ onMounted(async () => {
8590
@click="onClick"
8691
/>
8792
</li>
88-
<!-- @slot Slot par défaut pour le contenu de la liste de boutons. Sera dans `<ul class="fr-btns-group">` -->
8993
<slot />
9094
</ul>
9195
</template>

0 commit comments

Comments
 (0)