import type { StoryObj } from '@storybook/vue3-vite' import { computed, ref } from 'vue' export default { title: 'Accessibilité/Kit de pré-audit/Outils/Tanaguru/Faux positifs', } export const FauxPositifsCards: StoryObj = { render: () => { return { setup() { const search = ref('') const tanaguruCategoryFilter = ref('all') const page = ref(1) const itemsPerPage = 8 const items = [ { tanaguruCategory: 'mandatory-elements', tanaguruIssue: 'Propriétés ARIA non autorisées sur leur élément.', component: 'DialogBox', explanation: 'Une boîte de dialogue de type modale doit posséder la balise aria-modal="true" pour indiquer qu’elle est modale (voir motif de conception \'Dialog\' du W3C).', }, { tanaguruCategory: 'mandatory-elements', tanaguruIssue: 'Propriétés ARIA non autorisées sur leur élément.', component: 'RatingPicker', explanation: 'Un élément de type \'Rating\' doit posséder la balise role="radiogroup" pour indiquer qu’il s’agit d’un groupe de boutons radio (voir motif de conception \'Rating\' du W3C). Il peux poseder un aria-disabled="true" pour indiquer qu’il est désactivé.', }, { tanaguruCategory: 'navigation', tanaguruIssue: 'Eléments intéractifs non atteignables en navigation clavier.', component: 'Tabs', explanation: 'D\'après le motif de conception \'Tabs\' du W3C, les onglets (autre que celui actif) doivent bien avoir un tabindex="-1". En revanche, il faudra s\'assurer que ce tabindex passe bien à 0 lorsque l\'onglet devient actif.', }, ] const tanaguruCategories = { 'colors': { label: 'Couleurs', color: '#f0b323', }, 'forms': { label: 'Formulaires', color: '#f97316', }, 'images': { label: 'Images', color: '#ddd', }, 'information-presentation': { label: 'Présentation de l’information', color: '#555555', }, 'information-structure': { label: 'Structure de l’information', color: '#a05bb6', }, 'links': { label: 'Liens', color: '#3b82f6', }, 'mandatory-elements': { label: 'Éléments obligatoires', color: '#cc3e50', }, 'navigation': { label: 'Navigation', color: '#4caf50', }, 'scripts': { label: 'Scripts', color: '#2f3e46', }, } // Options de filtrage par catégorie Tanaguru const tanaguruCategoryOptions = [ { title: 'Toutes les catégories', value: 'all' }, ...Object.entries(tanaguruCategories).map( ([value, { label }]) => ({ title: label, value }), ), ] // Filtrer les items en fonction de la recherche et du statut const filteredItems = computed(() => { let result = [...items] // Filtrage par statut if (tanaguruCategoryFilter.value !== 'all') { result = result.filter(({ tanaguruCategory }) => tanaguruCategory === tanaguruCategoryFilter.value) } // Filtrage par recherche if (search.value) { const searchTerm = search.value.toLowerCase() result = result.filter(({ tanaguruIssue, component }) => tanaguruIssue.toLowerCase().includes(searchTerm) || component.toLowerCase().includes(searchTerm)) } return result }) const totalItems = computed(() => items.length) // Calcul des éléments paginés const paginatedItems = computed(() => { const start = (page.value - 1) * itemsPerPage const end = start + itemsPerPage return filteredItems.value.slice(start, end) }) // Permet de mettre en évidence les correspondances dans le texte const highlightMatch = (text, search) => { if (!search) return text const escapedSearch = search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // Échappe les caractères spéciaux const regex = new RegExp(`(${escapedSearch})`, 'gi') return text.replace(regex, '$1') } return { filteredItems, highlightMatch, items, itemsPerPage, page, paginatedItems, search, tanaguruCategories, tanaguruCategoryFilter, tanaguruCategoryOptions, totalItems } }, template: `
{{ tanaguruCategories[item.tanaguruCategory].label }}
Problème Tanaguru :
Explication :
{{ item.explanation }}
Total : {{ totalItems }}
Dernière mise à jour: 05/08/2025
`, } }, tags: ['!dev'], }