Skip to content

Commit 2030bd2

Browse files
authored
Ada 225: Function cannot be performed by keyboard alone (#17)
* Replace the checkbox and label with an option button for the galc form * Improve the appearance of the option button * Make deselection and facet sections flexible * Preserve facetsopen status * Use store for preserv facetsOpen status * Add ts test * Consolidate store ref
1 parent 8052356 commit 2030bd2

File tree

4 files changed

+77
-40
lines changed

4 files changed

+77
-40
lines changed

src/components/Facet.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ function onToggle (event: Event) {
4545
</template>
4646

4747
<style lang="scss">
48-
fieldset.galc-facet {
49-
display: inherit;
48+
.galc-facet {
49+
padding: 0 0.625em;
5050
border: none;
51+
display: inherit;
5152
5253
legend {
5354
position: absolute;
@@ -67,7 +68,7 @@ fieldset.galc-facet {
6768
font-size: 1.125rem;
6869
border-bottom: 1px solid #ddd5c7;
6970
width: 100%;
70-
margin-bottom: 0.5em;
71+
margin-bottom: 0.0em;
7172
cursor: pointer;
7273
7374
&::-webkit-details-marker {

src/components/Facets.vue

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { storeToRefs } from 'pinia'
3-
import { computed } from 'vue'
3+
import { computed, ref, onMounted, onUnmounted} from 'vue'
44
import { useFacetStore } from '../stores/facets'
55
import { useSessionStore } from '../stores/session'
66
import { useSearchStore } from '../stores/search'
@@ -12,10 +12,26 @@ import InternalFields from './InternalFields.vue'
1212
import Facet from './Facet.vue'
1313
import TermDeselection from './TermDeselection.vue'
1414
15-
const { facets } = storeToRefs(useFacetStore())
1615
const { isAdmin } = storeToRefs(useSessionStore())
17-
16+
const isMobile = ref(typeof window !== 'undefined' && window.innerWidth <= 700)
1817
const search = useSearchStore()
18+
19+
const facetStore = useFacetStore()
20+
const { facets, facetsOpen } = storeToRefs(facetStore)
21+
const { toggleFacets } = facetStore
22+
23+
function handleWindowResize() {
24+
isMobile.value = typeof window !== 'undefined' && window.innerWidth <= 700
25+
}
26+
27+
onMounted(() => {
28+
window.addEventListener('resize', handleWindowResize)
29+
handleWindowResize()
30+
})
31+
onUnmounted(() => {
32+
window.removeEventListener('resize', handleWindowResize)
33+
})
34+
1935
const liveMessage = computed(() => {
2036
const parts: string[] = []
2137
for (const facetName of search.activeFacetNames) {
@@ -33,12 +49,24 @@ const liveMessage = computed(() => {
3349
<template>
3450
<div class="galc-facets">
3551
<TermDeselection id-prefix="facets"/>
36-
<input id="show-facets" type="checkbox">
37-
<label class="show-facets-label" for="show-facets">
52+
53+
<button
54+
v-if="isMobile"
55+
class="show-facets-button"
56+
type="button"
57+
@click="toggleFacets"
58+
:aria-expanded="facetsOpen.toString()"
59+
aria-controls="facet-form"
60+
>
3861
Options
39-
<img alt="Options" :src="filter" class="show-facets-icon">
40-
</label>
41-
<form class="galc-facet-form">
62+
<img alt="" :src="filter" class="show-facets-icon">
63+
</button>
64+
65+
<form
66+
id="facet-form"
67+
class="galc-facet-form"
68+
v-show="facetsOpen || !isMobile"
69+
>
4270
<Suppressed v-if="isAdmin"/>
4371
<InternalFields v-if="isAdmin"/>
4472
<Facet
@@ -50,47 +78,34 @@ const liveMessage = computed(() => {
5078
</form>
5179

5280
<!-- Accessible live region -->
53-
<span class="sr-only" aria-live="polite" aria-atomic="true">{{ liveMessage }}</span>
54-
81+
<span class="sr-only" aria-live="polite" aria-atomic="true">
82+
{{ liveMessage }}
83+
</span>
5584
</div>
5685
</template>
5786

5887
<style lang="scss">
5988
div.galc-facets {
60-
61-
input#show-facets {
89+
.show-facets-button {
6290
display: none;
6391
}
64-
65-
@media only screen and (min-width: 700px) {
92+
93+
@media only screen and (min-width: 700px) {
6694
margin-right: 1em;
67-
6895
// TODO: less hacky way to place this differently on desktop and mobile
6996
.galc-term-deselection {
7097
display: none;
7198
}
72-
73-
label.show-facets-label {
99+
.show-facets-button {
74100
display: none;
75101
}
76-
77102
form.galc-facet-form {
78103
width: 150px;
79104
}
80105
}
81106
82107
@media only screen and (max-width: 700px) {
83-
input#show-facets {
84-
~ form.galc-facet-form {
85-
display: none;
86-
}
87-
88-
&:checked ~ form.galc-facet-form {
89-
display: grid;
90-
}
91-
}
92-
93-
label.show-facets-label {
108+
.show-facets-button {
94109
display: block;
95110
font-size: 1rem;
96111
line-height: 1.75rem;
@@ -101,6 +116,9 @@ div.galc-facets {
101116
margin: 6px 16px 6px 0;
102117
width: fit-content;
103118
cursor: pointer;
119+
border: none;
120+
border-radius: 4px;
121+
height: 33px;
104122
105123
img.show-facets-icon {
106124
height: 0.9rem;
@@ -178,6 +196,6 @@ div.galc-facets {
178196
white-space: nowrap;
179197
border-width: 0;
180198
}
181-
}
182199
183-
</style>
200+
}
201+
</style>

src/stores/facets.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,20 @@ export const useFacetStore = defineStore('facets', () => {
1111

1212
const facets: Ref<Facet[]> = ref([])
1313
const facetExpanded: Ref<{ [key: string]: boolean | undefined }> = ref({})
14-
const computedExpansionState: {[key: string]: WritableComputedRef<boolean> } = {}
14+
const computedExpansionState: { [key: string]: WritableComputedRef<boolean> } = {}
15+
const isMobile = typeof window !== 'undefined' && window.innerWidth <= 700
16+
const facetsOpen = ref(!isMobile)
1517

1618
// ------------------------------
1719
// Computed properties
1820

1921
const facetNames = computed(() => { return facets.value.map(f => f.name) })
2022

21-
function expanded (facetName: string) {
23+
function toggleFacets() {
24+
facetsOpen.value = !facetsOpen.value
25+
}
26+
27+
function expanded(facetName: string) {
2228
let expansionState = computedExpansionState[facetName]
2329
if (!expansionState) {
2430
expansionState = computed({
@@ -37,24 +43,24 @@ export const useFacetStore = defineStore('facets', () => {
3743
// ------------------------------
3844
// Actions
3945

40-
function expandAll (expandedNames = facetNames.value) {
46+
function expandAll(expandedNames = facetNames.value) {
4147
const expanded = { ...facetExpanded.value }
4248
for (const facetName of expandedNames) {
4349
expanded[facetName] = true
4450
}
4551
facetExpanded.value = expanded
4652
}
4753

48-
function collapseAll () {
54+
function collapseAll() {
4955
facetExpanded.value = {}
5056
}
5157

52-
function facetForName (name: string): Facet | undefined {
58+
function facetForName(name: string): Facet | undefined {
5359
return facets.value.find((f) => f.name === name)
5460
}
5561

5662
// ------------------------------
5763
// Store
5864

59-
return { facets, expanded, facetNames, facetForName, expandAll, collapseAll }
65+
return { facets, expanded, facetNames, facetForName, expandAll, collapseAll, facetsOpen, toggleFacets }
6066
})

test/stores/facets.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ describe('facets', () => {
1111
setActivePinia(createPinia())
1212
})
1313

14+
describe('test toggle funtion', () => {
15+
it('should toggle facetsOpen', () => {
16+
const store = useFacetStore()
17+
const initial = store.facetsOpen
18+
store.toggleFacets()
19+
expect(store.facetsOpen).toBe(!initial)
20+
21+
store.toggleFacets()
22+
expect(store.facetsOpen).toBe(initial)
23+
})
24+
})
25+
1426
describe('without data', () => {
1527
describe('facets', () => {
1628
it('is initially empty', () => {

0 commit comments

Comments
 (0)