SHIFT + D

Tablist

Updated on September 7, 2024Source codeTests

useTablist is a composable that implements the UI logic needed for a reactive, accessible tablist interface.

It follows WAI-ARIA authoring practices and allows you to easily customize accessibility features.

Example

Example source code

Turn, developed by Praekelt.org, creates software that gives social sector organizations unprecedented interactive connection with their clients. In healthcare, this means real time, private, two-way conversations that impart information, guide people to better care, deliver nudges, and ultimately improve health. Many of the best social organizations already use text and voice message platforms to push information to clients: the ability to have a two-way conversation opens whole new worlds of impact. As data gets cheap (already a reality in India), WhatsApp and similar tools enable much more sophisticated communication, including video and personalized information. The use of artificial intelligence and machine learning means that these connections can become more effective and (surprisingly) more personalized. Whatever the organization does, with Turn its relationship to clients and beneficiaries can be even richer and more productive.

0
0

Create a tablist

To create a tablist, call the useTablist function, which accepts one optional options object as its only parameter.

<!-- MyComponent.vue -->
<template>...</template>

<script setup>
import { useTablist } from '@baleada/vue-features'

const tablist = useTablist([options])
</script>

Here's a breakdown of the options object:

Property
Type
Required
Default
Description
transition
Object
no
none

An object with one property: panel.

Pass an object to transition.panel, specifying a transition or animation that useTablist should apply to each tab panel as they enter and leave visibility.

See the How to format enter/leave transitions section of the show docs for more guidance.

initialSelected
Number
no
0
The index-based position of the tab that should be initially selected.
ability
StatusOption
no
() => 'enabled'

A status option that should resolve to enabled for each enabled tab, and disabled for each disabled tab.

useTablist uses this information to decide which tabs are eligible to receive focus and/or be selected.

orientation
String
no
horizontal
Indicates the orientation of the tablist. For horizontal tablists, left and right arrow keys will transfer focus, and for vertical tablists, up and down arrow keys will transfer focus.
selectsOnFocus
Boolean
no
true
Indicates whether or not tabs should be selected as soon as they are focused
loops
Boolean
no
true
Indicates whether or not your tablist should "loop around" to the beginning of the list after reaching the end, and vice versa.
disabledTabsReceiveFocus
Boolean
no
true

Indicates whether or not your tablist can transfer focus to disabled tabs.

If you set disabledTabsReceiveFocus to false, you should be confident that assistive tech users don't need or want to read the labels of disabled tabs, or that they have another way to access that content.

Note that even when disabledTabsReceiveFocus is true, it's never possible to select disabled tabs.

panelContentsFocusability
StatusOption

A status option that should resolve to focusable when tab panel contents can receive focus, and not focusable when tab panel contents cannot receive focus.

useTablist uses this information to implement an accessibility feature for you: the tab panel should only be included in the page's tab order when tab panel contents are not focusable.

Use your tablist

useTablist returns a tablist—an object with tools you can use to connect useTablist's UI logic to your markup.

Here's a breakdown of that object:

Property
Type
Description
root
Function

A single element API object.

root.ref should be bound to the DOM element that serves as your tablist's root.

tabs
Function

A multiple element API object.

Pass the index-based position (Number) of the current tab as the only argument for tabs.ref, and its returned function ref should be bound to the DOM element that serves as that tab.

It's recommended that you render the tabs with v-for, get the index from your v-for statement, and bind the function ref to the v-for element.

panels
Function

A multiple element API object.

Pass the index-based position (Number) of the current panel as the only argument for panels.ref, and its returned function ref should be bound to the DOM element that serves as that panel.

It's recommended that you render the panels with v-for, get the index from your v-for statement, and bind the function ref to the v-for element.

focused
Ref (Number)
A reactive reference to the index-based position of the currently focused tab
selected
Ref (Number)
A reactive reference to the index-based position of the currently selected tab
is
Object

An object with two properties: focused and selected.

Each property holds a method that requires an index (Number) as its only parameter.

Given the index, is.focused returns a boolean indicating whether or not that tab is focused, and is.selected returns a boolean indicating whether or not that tab is selected.

is.focused and is.selected read from reactive references, so their boolean return values are fully reactive when used in Vue templates, watchers, and computed references.

getStatuses(index)
Function

A function that requires an index (Number) as its only parameter, and returns a three-item array indicating the statuses (Strings) of the tab at that index.

The first item will be focused or blurred, the second item will be selected or deselected and the third item will be enabled or disabled.

focus
Object

An object containing all the methods described in the eligible focus guide.

You can use these methods to programmatically transfer focus in a smarter way, taking enabled/disabled state and other customizable conditions into account.

select
Functions

An object containing all the methods described in the eligible picking guide.

You can use these methods to programmatically select tabs in a smarter way, taking enabled/disabled state and other customizable conditions into account.

Note that tablists can never be multiselectable, so you can only pass a single index to the select.exact method—an array of selected indices is not possible.

Here's a more complete example of how to use your tablist and bind the various function refs:

<!-- MyComponent.vue -->
<template>
  <div :ref="tablist.root.ref()">
    <div
      v-for="({ tab }, index) in metadata"
      :key="tab"
      :ref="tablist.tabs.ref(index)"
    >
      {{ tab }}
    </div>
    <div
      v-for="({ tab, panel }, index) in metadata"
      :key="tab"
      :ref="tablist.panels.ref(index)"
    >
      {{ panel }}
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useTablist } from '@baleada/vue-features'

const metadata = ref([
  { tab: 'Educate Girls', panel: 'https://www.educategirls.ngo/' },
  { tab: 'Kheyti', panel: 'https://www.kheyti.com/' },
  { tab: 'One Heart Worldwide', panel: 'https://oneheartworldwide.org/' },
])

const tablist = useTablist()
</script>

Extend the tablist

The following extensions are compatible with your textbox:

SeparatorTextbox

Edit doc on GitHub

ON THIS PAGE

TablistExampleCreate a tablistUse your tablistExtend the tablist