Prayer Progress: a multi-tab bar is a tablist, and says which tab is selected

The research page now gives this map three tabs (engagement, prayer,
adoption). With two or more tabs the bar was a row of plain buttons: a screen
reader heard three buttons, with nothing saying they are tabs or which one is
showing. The bar is now role=tablist, each button is role=tab with
aria-selected, and the buttons are type=button. A one-tab instance shows no
bar, so it is unchanged.
This commit is contained in:
Doxa Maps 2026-09-29 18:56:53 +00:00
parent feb75f0f44
commit a85afc8b71

View file

@ -289,7 +289,8 @@ const tabs = computed(() => profileConfig?.value?.tabs ?? DEFAULT_TABS)
// profileConfig.tabs is the host's own words and is shown as given.
const DEFAULT_LABELS = Object.fromEntries(DEFAULT_TABS.map((d) => [d.id, d.label]))
const tabLabel = (tab) => ((!tab.label || tab.label === DEFAULT_LABELS[tab.id]) && te('tabs.' + tab.id)) ? t('tabs.' + tab.id) : tab.label
// before giving an instance a 2nd tab: the tab bar needs role="tablist"/"tab" + :aria-selected (the underline already marks the active tab by shape, not only colour)
// With 2+ tabs (the research page passes three) the bar is a tablist: a screen reader announces each
// button as a tab and which one is selected. The underline marks the active tab by shape, not only colour.
const showTabBar = computed(() => tabs.value.length > 1)
// ─── Tab state ────────────────────────────────────────────────────────────────
@ -1406,12 +1407,15 @@ onBeforeUnmount(() => {
>
<!-- In-map tab bar (only when 2+ tabs) -->
<div v-if="showTabBar" class="dsm-tab-bar">
<div v-if="showTabBar" class="dsm-tab-bar" role="tablist">
<button
v-for="tab in tabs"
:key="tab.id"
type="button"
role="tab"
class="dsm-tab"
:class="{ active: activeTabId === tab.id }"
:aria-selected="activeTabId === tab.id ? 'true' : 'false'"
@click="switchTab(tab.id)"
>
{{ tabLabel(tab) }}