import { type Meta, type StoryObj } from '@storybook/vue3' import CookieBanner from './CookieBanner.vue' import { fn } from '@storybook/test' import { VBtn } from 'vuetify/components' import { ref, watch } from 'vue' const meta = { title: 'Composants/Feedback/CookieBanner', component: CookieBanner, argTypes: { 'headingLevel': { control: { type: 'select' }, options: [1, 2, 3, 4, 5, 6], }, 'headingLevelInformation': { control: { type: 'select' }, options: [1, 2, 3, 4, 5, 6], }, 'modelValue': { description: 'V-model, control la visibilité de la bannière', control: { type: 'boolean' }, table: { defaultValue: { summary: 'true' }, category: 'props', }, }, 'items': { description: 'Liste des cookies à afficher', control: 'object', table: { type: { summary: 'CookiesItems', detail: `{ essentials?: { name: string description?: string conservation: string }[], functional?: { name: string description?: string conservation: string }[], analytics?: { name: string description?: string conservation: string }[], }`, }, category: 'props', }, }, 'onAccept': { action: 'accept', description: 'Événement émis lors de l\'acceptation des cookies', table: { category: 'Events', type: { summary: 'Partial<{ functional: boolean; analytics: boolean }>' }, }, }, 'onReject': { action: 'reject', description: 'Événement émis lors du refus des cookies', table: { category: 'Events', type: { summary: 'Partial<{ functional: boolean; analytics: boolean }>' }, }, }, 'onCustomize': { action: 'customize', description: 'Événement émis lors de la personnalisation des cookies', table: { category: 'Events', type: { summary: '' }, }, }, 'onSubmit': { action: 'submit', description: 'Événement émis lors de la sauvegarde des préférences personnalisées', table: { category: 'Events', type: { summary: 'Partial' }, }, }, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore- Object literal may only specify known properties 'onUpdate:modelValue': { action: 'update:modelValue', description: 'Événement émis lors de la mise à jour de la visibilité de la bannière', table: { category: 'Events', type: { summary: 'Boolean' }, }, }, 'vuetifyOptions': { description: 'Options de personnalisation des composants Vuetify internes', control: { type: 'object' }, table: { defaultValue: { summary: '{}', detail: `{ banner: { width: '800px', maxWidth: '100%', rounded: true, elevation: 2, class: 'pa-8 ma-8', stacked: true, location: 'bottom', position: 'fixed', maxHeight: 'calc(100dvh - 64px)', density: 'compact', }, closeBtn: { icon: true, variant: 'text', width: '32px', height: '32px', class: 'ml-4', }, backBtn: { icon: true, variant: 'text', width: '32px', height: '32px', class: 'ml-4', }, customizeBtn: { color: 'primary', height: 'auto', minHeight: '44px', class: 'text-wrap ma-2', variant: 'outlined', }, rejectBtn: { color: 'primary', height: 'auto', minHeight: '44px', class: 'text-wrap ma-2', }, acceptBtn: { color: 'primary', height: 'auto', minHeight: '44px', class: 'text-wrap ma-2', }, }`, }, type: { summary: 'Record>', detail: `{ banner: VSheetOptions, closeBtn: VBtnOptions, customizeBtn: VBtnOptions, rejectBtn: VBtnOptions, acceptBtn: VBtnOptions, }`, }, category: 'props', }, }, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - 'default' storybook can't infer dynamic slot name 'default': { description: 'Description de la bannière', control: { type: 'text' }, table: { defaultValue: { summary: 'undefined' }, type: { summary: '{}' }, category: 'slots', }, }, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - 'cookie-description-${cookieName}' storybook can't infer dynamic slot name 'cookie-description-${cookieName}': { description: 'Slot pour personnaliser la description d’un cookie', control: 'none', table: { category: 'slots', type: { summary: 'Cookie', detail: `{ name: string description?: string conservation: string }`, }, }, }, }, parameters: { layout: 'fullscreen', controls: { exclude: ['reject', 'accept', 'customize', 'submit'], }, docs: { controls: { exclude: ['submit', 'slotName'] }, }, }, args: { modelValue: false, headingLevel: 2, headingLevelInformation: 2, }, } satisfies Meta export default meta type Story = StoryObj const items = { essentials: [ { name: 'session', description: 'Sauvegarde la session pour rester connecté.', conservation: '20 heures', }, { name: 'cookie_policy', description: 'Sauvegarde les préférences de cookies.', conservation: '1 an', }, ], functional: [ { name: 'contrast', description: 'Sauvegarde la personnalisation de l’affichage.', conservation: '1 an', }, ], analytics: [ { name: 'user_id', description: 'Sauvegarde l’identifiant unique de visiteur.', conservation: '6 mois', }, ], } export const Default: Story = { argTypes: { onAccept: { action: 'accept' }, onReject: { action: 'reject' }, onCustomize: { action: 'customize' }, onSubmit: { action: 'submit' }, }, args: { items, }, render: (args) => { return { components: { CookieBanner, VBtn }, setup() { const open = ref(false) watch(() => args.modelValue, (value) => { open.value = !!value }, { immediate: true }) return { args, open } }, template: `
Ouvrir la bannière
`, } }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, } export const WithoutCookiesItems: Story = { args: { onAccept: fn(), onReject: fn(), onCustomize: fn(), }, render: (args) => { return { components: { CookieBanner, VBtn }, setup() { const open = ref(false) watch(() => args.modelValue, (value) => { open.value = !!value }, { immediate: true }) return { args, open } }, template: `
Ouvrir la bannière
`, } }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, } export const BannerDescriptionSlot: Story = { args: { onAccept: fn(), onReject: fn(), onCustomize: fn(), items, }, render: (args) => { return { components: { CookieBanner, VBtn }, setup() { const open = ref(false) watch(() => args.modelValue, (value) => { open.value = !!value }, { immediate: true }) return { args, open } }, template: `
Ouvrir la bannière

Custom description

`, } }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, } export const CookiesDescriptionSlots: Story = { args: { onAccept: fn(), onReject: fn(), onCustomize: fn(), items: { functional: [ { name: 'contrast', conservation: '1 an', }, { name: 'privacy', conservation: '1 an', }, { name: 'cookie_policy', description: 'Sauvegarde les préférences de cookies.', conservation: '1 an', }, ], }, }, render: (args) => { return { components: { CookieBanner, VBtn }, setup() { const open = ref(false) watch(() => args.modelValue, (value) => { open.value = !!value }, { immediate: true }) return { args, open } }, template: `
Ouvrir la bannière
`, } }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, } export const Customization: Story = { args: { items, onAccept: fn(), onReject: fn(), onCustomize: fn(), vuetifyOptions: { banner: { color: '#ced9eb', }, customizeBtn: { variant: 'text', color: 'orange', }, rejectBtn: { variant: 'outlined', }, acceptBtn: { variant: 'outlined', }, }, }, render: (args) => { return { components: { CookieBanner, VBtn }, setup() { const open = ref(false) watch(() => args.modelValue, (value) => { open.value = !!value }, { immediate: true }) return { args, open } }, template: `
Ouvrir la bannière
`, } }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, }