11<script setup lang="ts">
2- import type { ComparisonFacet } from ' #shared/types'
3- import { FACET_INFO , FACETS_BY_CATEGORY , CATEGORY_ORDER } from ' #shared/types/comparison'
4-
5- const { isFacetSelected, toggleFacet, selectCategory, deselectCategory } = useFacetSelection ()
6-
7- // Enrich facets with their info for rendering
8- const facetsByCategory = computed (() => {
9- const result: Record <
10- string ,
11- { facet: ComparisonFacet ; info: (typeof FACET_INFO )[ComparisonFacet ] }[]
12- > = {}
13- for (const category of CATEGORY_ORDER ) {
14- result [category ] = FACETS_BY_CATEGORY [category ].map (facet => ({
15- facet ,
16- info: FACET_INFO [facet ],
17- }))
18- }
19- return result
20- })
2+ const {
3+ isFacetSelected,
4+ toggleFacet,
5+ selectCategory,
6+ deselectCategory,
7+ facetsByCategory,
8+ categoryOrder,
9+ getCategoryLabel,
10+ } = useFacetSelection ()
2111
2212// Check if all non-comingSoon facets in a category are selected
2313function isCategoryAllSelected(category : string ): boolean {
2414 const facets = facetsByCategory .value [category ] ?? []
25- const selectableFacets = facets .filter (f => ! f .info . comingSoon )
26- return selectableFacets .length > 0 && selectableFacets .every (f => isFacetSelected (f .facet ))
15+ const selectableFacets = facets .filter (f => ! f .comingSoon )
16+ return selectableFacets .length > 0 && selectableFacets .every (f => isFacetSelected (f .id ))
2717}
2818
2919// Check if no facets in a category are selected
3020function isCategoryNoneSelected(category : string ): boolean {
3121 const facets = facetsByCategory .value [category ] ?? []
32- const selectableFacets = facets .filter (f => ! f .info . comingSoon )
33- return selectableFacets .length > 0 && selectableFacets .every (f => ! isFacetSelected (f .facet ))
22+ const selectableFacets = facets .filter (f => ! f .comingSoon )
23+ return selectableFacets .length > 0 && selectableFacets .every (f => ! isFacetSelected (f .id ))
3424}
3525 </script >
3626
3727<template >
3828 <div class =" space-y-3" role =" group" :aria-label =" $t('compare.facets.group_label')" >
39- <div v-for =" category in CATEGORY_ORDER " :key =" category" >
29+ <div v-for =" category in categoryOrder " :key =" category" >
4030 <!-- Category header with all/none buttons -->
4131 <div class =" flex items-center gap-2 mb-2" >
4232 <span class =" text-[10px] text-fg-subtle uppercase tracking-wider" >
43- {{ $t(`compare.facets.categories.${ category}` ) }}
33+ {{ getCategoryLabel( category) }}
4434 </span >
4535 <button
4636 type =" button"
@@ -51,9 +41,7 @@ function isCategoryNoneSelected(category: string): boolean {
5141 : 'text-fg-muted/60 hover:text-fg-muted'
5242 "
5343 :aria-label ="
54- $t('compare.facets.select_category', {
55- category: $t(`compare.facets.categories.${category}`),
56- })
44+ $t('compare.facets.select_category', { category: getCategoryLabel(category) })
5745 "
5846 :disabled =" isCategoryAllSelected(category)"
5947 @click =" selectCategory(category)"
@@ -70,9 +58,7 @@ function isCategoryNoneSelected(category: string): boolean {
7058 : 'text-fg-muted/60 hover:text-fg-muted'
7159 "
7260 :aria-label ="
73- $t('compare.facets.deselect_category', {
74- category: $t(`compare.facets.categories.${category}`),
75- })
61+ $t('compare.facets.deselect_category', { category: getCategoryLabel(category) })
7662 "
7763 :disabled =" isCategoryNoneSelected(category)"
7864 @click =" deselectCategory(category)"
@@ -84,31 +70,31 @@ function isCategoryNoneSelected(category: string): boolean {
8470 <!-- Facet buttons -->
8571 <div class =" flex items-center gap-1.5 flex-wrap" role =" group" >
8672 <button
87- v-for =" { facet, info } in facetsByCategory[category]"
88- :key =" facet"
73+ v-for =" facet in facetsByCategory[category]"
74+ :key =" facet.id "
8975 type =" button"
90- :title =" info .comingSoon ? $t('compare.facets.coming_soon') : info .description"
91- :disabled =" info .comingSoon"
92- :aria-pressed =" isFacetSelected(facet)"
93- :aria-label =" info .label"
76+ :title =" facet .comingSoon ? $t('compare.facets.coming_soon') : facet .description"
77+ :disabled =" facet .comingSoon"
78+ :aria-pressed =" isFacetSelected(facet.id )"
79+ :aria-label =" facet .label"
9480 class =" inline-flex items-center gap-1 px-1.5 py-0.5 font-mono text-xs rounded border transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
9581 :class ="
96- info .comingSoon
82+ facet .comingSoon
9783 ? 'text-fg-subtle/50 bg-bg-subtle border-border-subtle cursor-not-allowed'
98- : isFacetSelected(facet)
84+ : isFacetSelected(facet.id )
9985 ? 'text-fg-muted bg-bg-muted border-border'
10086 : 'text-fg-subtle bg-bg-subtle border-border-subtle hover:text-fg-muted hover:border-border'
10187 "
102- @click =" !info .comingSoon && toggleFacet(facet)"
88+ @click =" !facet .comingSoon && toggleFacet(facet.id )"
10389 >
10490 <span
105- v-if =" !info .comingSoon"
91+ v-if =" !facet .comingSoon"
10692 class =" w-3 h-3"
107- :class =" isFacetSelected(facet) ? 'i-carbon:checkmark' : 'i-carbon:add'"
93+ :class =" isFacetSelected(facet.id ) ? 'i-carbon:checkmark' : 'i-carbon:add'"
10894 aria-hidden =" true"
10995 />
110- {{ info .label }}
111- <span v-if =" info .comingSoon" class =" text-[9px]"
96+ {{ facet .label }}
97+ <span v-if =" facet .comingSoon" class =" text-[9px]"
11298 >({{ $t('compare.facets.coming_soon') }})</span
11399 >
114100 </button >
0 commit comments