mirror of
https://github.com/primefaces/primevue.git
synced 2025-05-10 17:32:36 +00:00
Fixed #2895 - Improve Accordion implementation for Accessibility
This commit is contained in:
parent
67320fb0d8
commit
3bdaf4a2b9
7 changed files with 446 additions and 91 deletions
|
@ -28,6 +28,18 @@ const AccordionProps = [
|
||||||
type: "string",
|
type: "string",
|
||||||
default: "pi-chevron-down",
|
default: "pi-chevron-down",
|
||||||
description: "Icon of a expanded tab."
|
description: "Icon of a expanded tab."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tabindex",
|
||||||
|
type: "number",
|
||||||
|
default: "0",
|
||||||
|
description: "Index of the element in tabbing order."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "selectOnFocus",
|
||||||
|
type: "boolean",
|
||||||
|
default: "false",
|
||||||
|
description: "When enabled, the focused tab is activated."
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -63,6 +75,22 @@ const AccordionEvents = [
|
||||||
description: "Closed tab index"
|
description: "Closed tab index"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tab-click",
|
||||||
|
description: "Callback to invoke when an active tab is clicked.",
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
name: "originalEvent",
|
||||||
|
type: "object",
|
||||||
|
description: "Original event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "index",
|
||||||
|
type: "number",
|
||||||
|
description: "Index of the clicked tab"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,48 @@ const AccordionTabProps = [
|
||||||
default: "null",
|
default: "null",
|
||||||
description: "Orientation of tab headers."
|
description: "Orientation of tab headers."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "headerStyle",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Inline style of the tab header."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "headerClass",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Style class of the tab header."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "headerProps",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Uses to pass all properties of the HTMLDivElement to the tab header."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "headerActionProps",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Uses to pass all properties of the HTMLAnchorElement to the focusable anchor element inside the tab header."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contentStyle",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Inline style of the tab content."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contentClass",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Style class of the tab content."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contentProps",
|
||||||
|
type: "any",
|
||||||
|
default: "null",
|
||||||
|
description: "Uses to pass all properties of the HTMLDivElement to the tab content."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "disabled",
|
name: "disabled",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
|
|
18
src/components/accordion/Accordion.d.ts
vendored
18
src/components/accordion/Accordion.d.ts
vendored
|
@ -18,6 +18,11 @@ export interface AccordionTabOpenEvent {
|
||||||
*/
|
*/
|
||||||
export interface AccordionTabCloseEvent extends AccordionTabOpenEvent { }
|
export interface AccordionTabCloseEvent extends AccordionTabOpenEvent { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends AccordionTabOpenEvent
|
||||||
|
*/
|
||||||
|
export interface AccordionClickEvent extends AccordionTabOpenEvent { }
|
||||||
|
|
||||||
export interface AccordionProps {
|
export interface AccordionProps {
|
||||||
/**
|
/**
|
||||||
* When enabled, multiple tabs can be activated at the same time.
|
* When enabled, multiple tabs can be activated at the same time.
|
||||||
|
@ -39,6 +44,14 @@ export interface AccordionProps {
|
||||||
* Icon of an expanded tab.
|
* Icon of an expanded tab.
|
||||||
*/
|
*/
|
||||||
collapseIcon?: string | undefined;
|
collapseIcon?: string | undefined;
|
||||||
|
/**
|
||||||
|
* Index of the element in tabbing order.
|
||||||
|
*/
|
||||||
|
tabindex?: number | undefined;
|
||||||
|
/**
|
||||||
|
* When enabled, the focused tab is activated.
|
||||||
|
*/
|
||||||
|
selectOnFocus?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccordionSlots {
|
export interface AccordionSlots {
|
||||||
|
@ -64,6 +77,11 @@ export declare type AccordionEmits = {
|
||||||
* @param {AccordionTabCloseEvent} event - Custom tab close event.
|
* @param {AccordionTabCloseEvent} event - Custom tab close event.
|
||||||
*/
|
*/
|
||||||
'tab-close': (event: AccordionTabCloseEvent) => void;
|
'tab-close': (event: AccordionTabCloseEvent) => void;
|
||||||
|
/**
|
||||||
|
* Callback to invoke when an active tab is clicked.
|
||||||
|
* @param {AccordionClickEvent} event - Custom tab click event.
|
||||||
|
*/
|
||||||
|
'tab-click': (event: AccordionClickEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare class Accordion extends ClassComponent<AccordionProps, AccordionSlots, AccordionEmits> { }
|
declare class Accordion extends ClassComponent<AccordionProps, AccordionSlots, AccordionEmits> { }
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-accordion p-component">
|
<div class="p-accordion p-component">
|
||||||
<div v-for="(tab,i) of tabs" :key="getKey(tab,i)" :class="getTabClass(i)">
|
<div v-for="(tab,i) of tabs" :key="getKey(tab,i)" :class="getTabClass(i)" :data-index="i">
|
||||||
<div :class="getTabHeaderClass(tab, i)">
|
<div :style="getTabProp(tab, 'headerStyle')" :class="getTabHeaderClass(tab, i)" v-bind="getTabProp(tab, 'headerProps')">
|
||||||
<a role="tab" class="p-accordion-header-link" @click="onTabClick($event, tab, i)" @keydown="onTabKeydown($event, tab, i)" :tabindex="isTabDisabled(tab) ? null : '0'"
|
<a :id="getTabHeaderActionId(i)" class="p-accordion-header-link p-accordion-header-action" :tabindex="getTabProp(tab, 'disabled') ? -1 : tabindex"
|
||||||
:aria-expanded="isTabActive(i)" :id="getTabAriaId(i) + '_header'" :aria-controls="getTabAriaId(i) + '_content'">
|
role="button" :aria-disabled="getTabProp(tab, 'disabled')" :aria-expanded="isTabActive(i)" :aria-controls="getTabContentId(i)"
|
||||||
<span :class="isTabActive(i) ? getHeaderCollapseIcon() : getHeaderExpandIcon()"></span>
|
@click="onTabClick($event, tab, i)" @keydown="onTabKeyDown($event, tab, i)" v-bind="getTabProp(tab, 'headerActionProps')">
|
||||||
|
<span :class="getTabHeaderIconClass(i)" aria-hidden="true"></span>
|
||||||
<span class="p-accordion-header-text" v-if="tab.props && tab.props.header">{{tab.props.header}}</span>
|
<span class="p-accordion-header-text" v-if="tab.props && tab.props.header">{{tab.props.header}}</span>
|
||||||
<component :is="tab.children.header" v-if="tab.children && tab.children.header"></component>
|
<component :is="tab.children.header" v-if="tab.children && tab.children.header"></component>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<transition name="p-toggleable-content">
|
<transition name="p-toggleable-content">
|
||||||
<div class="p-toggleable-content" v-if="lazy ? isTabActive(i) : true" v-show="lazy ? true: isTabActive(i)"
|
<div v-if="lazy ? isTabActive(i) : true" v-show="lazy ? true: isTabActive(i)" :id="getTabContentId(i)" :style="getTabProp(tab, 'contentStyle')" :class="getTabContentClass(tab)"
|
||||||
role="region" :id="getTabAriaId(i) + '_content'" :aria-labelledby="getTabAriaId(i) + '_header'">
|
role="region" :aria-labelledby="getTabHeaderActionId(i)" v-bind="getTabProp(tab, 'contentProps')">
|
||||||
<div class="p-accordion-content">
|
<div class="p-accordion-content">
|
||||||
<component :is="tab"></component>
|
<component :is="tab"></component>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,11 +23,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {UniqueComponentId} from 'primevue/utils';
|
import {UniqueComponentId,DomHandler} from 'primevue/utils';
|
||||||
|
import Ripple from 'primevue/ripple';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Accordion',
|
name: 'Accordion',
|
||||||
emits: ['tab-close', 'tab-open', 'update:activeIndex'],
|
emits: ['update:activeIndex', 'tab-open', 'tab-close', 'tab-click'],
|
||||||
props: {
|
props: {
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -47,10 +49,19 @@ export default {
|
||||||
collapseIcon: {
|
collapseIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'pi-chevron-down'
|
default: 'pi-chevron-down'
|
||||||
|
},
|
||||||
|
tabindex: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
selectOnFocus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
id: UniqueComponentId(),
|
||||||
d_activeIndex: this.activeIndex
|
d_activeIndex: this.activeIndex
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -59,98 +70,186 @@ export default {
|
||||||
this.d_activeIndex = newValue;
|
this.d_activeIndex = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.id = this.$attrs.id || this.id;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onTabClick(event, tab, i) {
|
isAccordionTab(child) {
|
||||||
if (!this.isTabDisabled(tab)) {
|
return child.type.name === 'AccordionTab';
|
||||||
const active = this.isTabActive(i);
|
},
|
||||||
|
isTabActive(index) {
|
||||||
|
return this.multiple ? (this.d_activeIndex && this.d_activeIndex.includes(index)) : this.d_activeIndex === index;
|
||||||
|
},
|
||||||
|
getTabProp(tab, name) {
|
||||||
|
return tab.props ? tab.props[name] : undefined;
|
||||||
|
},
|
||||||
|
getKey(tab, index) {
|
||||||
|
return this.getTabProp(tab, 'header') || index;
|
||||||
|
},
|
||||||
|
getTabHeaderActionId(index) {
|
||||||
|
return `${this.id}_${index}_header_action`;
|
||||||
|
},
|
||||||
|
getTabContentId(index) {
|
||||||
|
return `${this.id}_${index}_content`;
|
||||||
|
},
|
||||||
|
onTabClick(event, tab, index) {
|
||||||
|
this.changeActiveIndex(event, tab, index);
|
||||||
|
this.$emit('tab-click', { originalEvent: event, index });
|
||||||
|
},
|
||||||
|
onTabKeyDown(event, tab, index) {
|
||||||
|
switch (event.code) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
this.onTabArrowDownKey(event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ArrowUp':
|
||||||
|
this.onTabArrowUpKey(event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Home':
|
||||||
|
this.onTabHomeKey(event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'End':
|
||||||
|
this.onTabEndKey(event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Enter':
|
||||||
|
case 'Space':
|
||||||
|
this.onTabEnterKey(event, tab, index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTabArrowDownKey(event) {
|
||||||
|
const nextHeaderAction = this.findNextHeaderAction(event.target.parentElement.parentElement);
|
||||||
|
|
||||||
|
nextHeaderAction ? this.changeFocusedTab(event, nextHeaderAction) : this.onTabHomeKey(event);
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
onTabArrowUpKey(event) {
|
||||||
|
const prevHeaderAction = this.findPrevHeaderAction(event.target.parentElement.parentElement);
|
||||||
|
|
||||||
|
prevHeaderAction ? this.changeFocusedTab(event, prevHeaderAction) : this.onTabEndKey(event);
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
onTabHomeKey(event) {
|
||||||
|
const firstHeaderAction = this.findFirstHeaderAction();
|
||||||
|
|
||||||
|
this.changeFocusedTab(event, firstHeaderAction);
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
onTabEndKey(event) {
|
||||||
|
const lastHeaderAction = this.findLastHeaderAction();
|
||||||
|
|
||||||
|
this.changeFocusedTab(event, lastHeaderAction);
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
onTabEnterKey(event, tab, index) {
|
||||||
|
this.changeActiveIndex(event, tab, index);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
findNextHeaderAction(tabElement, selfCheck = false) {
|
||||||
|
const nextTabElement = selfCheck ? tabElement : tabElement.nextElementSibling;
|
||||||
|
const headerElement = DomHandler.findSingle(nextTabElement, '.p-accordion-header');
|
||||||
|
|
||||||
|
return headerElement ? (DomHandler.hasClass(headerElement, 'p-disabled') ? this.findNextHeaderAction(headerElement.parentElement) : DomHandler.findSingle(headerElement, '.p-accordion-header-action')) : null;
|
||||||
|
},
|
||||||
|
findPrevHeaderAction(tabElement, selfCheck = false) {
|
||||||
|
const prevTabElement = selfCheck ? tabElement : tabElement.previousElementSibling;
|
||||||
|
const headerElement = DomHandler.findSingle(prevTabElement, '.p-accordion-header');
|
||||||
|
|
||||||
|
return headerElement ? (DomHandler.hasClass(headerElement, 'p-disabled') ? this.findPrevHeaderAction(headerElement.parentElement) : DomHandler.findSingle(headerElement, '.p-accordion-header-action')) : null;
|
||||||
|
},
|
||||||
|
findFirstHeaderAction() {
|
||||||
|
return this.findNextHeaderAction(this.$el.firstElementChild, true);
|
||||||
|
},
|
||||||
|
findLastHeaderAction() {
|
||||||
|
return this.findPrevHeaderAction(this.$el.lastElementChild, true);
|
||||||
|
},
|
||||||
|
changeActiveIndex(event, tab, index) {
|
||||||
|
if (!this.getTabProp(tab, 'disabled')) {
|
||||||
|
const active = this.isTabActive(index);
|
||||||
const eventName = active ? 'tab-close' : 'tab-open';
|
const eventName = active ? 'tab-close' : 'tab-open';
|
||||||
|
|
||||||
if (this.multiple) {
|
if (this.multiple) {
|
||||||
if (active) {
|
if (active) {
|
||||||
this.d_activeIndex = this.d_activeIndex.filter(index => index !== i);
|
this.d_activeIndex = this.d_activeIndex.filter(i => i !== index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.d_activeIndex)
|
if (this.d_activeIndex)
|
||||||
this.d_activeIndex.push(i);
|
this.d_activeIndex.push(index);
|
||||||
else
|
else
|
||||||
this.d_activeIndex = [i];
|
this.d_activeIndex = [index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.d_activeIndex = this.d_activeIndex === i ? null : i;
|
this.d_activeIndex = this.d_activeIndex === index ? null : index;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('update:activeIndex', this.d_activeIndex);
|
this.$emit('update:activeIndex', this.d_activeIndex);
|
||||||
|
this.$emit(eventName, { originalEvent: event, index });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeFocusedTab(event, element) {
|
||||||
|
if (element) {
|
||||||
|
element.focus();
|
||||||
|
|
||||||
this.$emit(eventName, {
|
if (this.selectOnFocus) {
|
||||||
originalEvent: event,
|
const index = parseInt(element.parentElement.parentElement.dataset.index, 10);
|
||||||
index: i
|
const tab = this.tabs[index];
|
||||||
});
|
|
||||||
|
this.changeActiveIndex(event, tab, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onTabKeydown(event, tab, i) {
|
|
||||||
if (event.which === 13) {
|
|
||||||
this.onTabClick(event, tab, i);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isTabActive(index) {
|
|
||||||
if (this.multiple)
|
|
||||||
return this.d_activeIndex && this.d_activeIndex.includes(index);
|
|
||||||
else
|
|
||||||
return index === this.d_activeIndex;
|
|
||||||
},
|
|
||||||
getKey(tab, i) {
|
|
||||||
return (tab.props && tab.props.header) ? tab.props.header : i;
|
|
||||||
},
|
|
||||||
isTabDisabled(tab) {
|
|
||||||
return tab.props && tab.props.disabled;
|
|
||||||
},
|
|
||||||
getTabClass(i) {
|
getTabClass(i) {
|
||||||
return ['p-accordion-tab', {'p-accordion-tab-active': this.isTabActive(i)}];
|
return ['p-accordion-tab', {
|
||||||
|
'p-accordion-tab-active': this.isTabActive(i)
|
||||||
|
}];
|
||||||
},
|
},
|
||||||
getTabHeaderClass(tab, i) {
|
getTabHeaderClass(tab, i) {
|
||||||
return ['p-accordion-header', {'p-highlight': this.isTabActive(i), 'p-disabled': this.isTabDisabled(tab)}];
|
return ['p-accordion-header', this.getTabProp(tab, 'headerClass'), {
|
||||||
|
'p-highlight': this.isTabActive(i),
|
||||||
|
'p-disabled': this.getTabProp(tab, 'disabled')
|
||||||
|
}];
|
||||||
},
|
},
|
||||||
getTabAriaId(i) {
|
getTabHeaderIconClass(i) {
|
||||||
return this.ariaId + '_' + i;
|
return ['p-accordion-toggle-icon pi', this.isTabActive(i) ? this.collapseIcon : this.expandIcon];
|
||||||
},
|
},
|
||||||
getHeaderCollapseIcon() {
|
getTabContentClass(tab) {
|
||||||
return ['p-accordion-toggle-icon pi', this.collapseIcon];
|
return ['p-toggleable-content', this.getTabProp(tab, 'contentClass')];
|
||||||
},
|
|
||||||
getHeaderExpandIcon() {
|
|
||||||
return ['p-accordion-toggle-icon pi', this.expandIcon];
|
|
||||||
},
|
|
||||||
isAccordionTab(child) {
|
|
||||||
return child.type.name === 'AccordionTab';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
tabs() {
|
tabs() {
|
||||||
const tabs = []
|
return this.$slots.default().reduce((tabs, child) => {
|
||||||
this.$slots.default().forEach(child => {
|
if (this.isAccordionTab(child)) {
|
||||||
if (this.isAccordionTab(child)) {
|
tabs.push(child);
|
||||||
tabs.push(child);
|
|
||||||
}
|
|
||||||
else if (child.children && child.children instanceof Array) {
|
|
||||||
child.children.forEach(nestedChild => {
|
|
||||||
if (this.isAccordionTab(nestedChild)) {
|
|
||||||
tabs.push(nestedChild)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
else if (child.children && child.children instanceof Array) {
|
||||||
return tabs;
|
child.children.forEach(nestedChild => {
|
||||||
},
|
if (this.isAccordionTab(nestedChild)) {
|
||||||
ariaId() {
|
tabs.push(nestedChild);
|
||||||
return UniqueComponentId();
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return tabs;
|
||||||
|
}, []);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'ripple': Ripple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.p-accordion-header-link {
|
.p-accordion-header-action {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -159,7 +258,7 @@ export default {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-accordion-header-link:focus {
|
.p-accordion-header-action:focus {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
src/components/accordiontab/AccordionTab.d.ts
vendored
30
src/components/accordiontab/AccordionTab.d.ts
vendored
|
@ -1,4 +1,4 @@
|
||||||
import { VNode } from 'vue';
|
import { AnchorHTMLAttributes, HTMLAttributes, VNode } from 'vue';
|
||||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||||
|
|
||||||
export interface AccordionTabProps {
|
export interface AccordionTabProps {
|
||||||
|
@ -6,6 +6,34 @@ export interface AccordionTabProps {
|
||||||
* Orientation of tab headers.
|
* Orientation of tab headers.
|
||||||
*/
|
*/
|
||||||
header?: string | undefined;
|
header?: string | undefined;
|
||||||
|
/**
|
||||||
|
* Inline style of the tab header.
|
||||||
|
*/
|
||||||
|
headerStyle?: any;
|
||||||
|
/**
|
||||||
|
* Style class of the tab header.
|
||||||
|
*/
|
||||||
|
headerClass?: any;
|
||||||
|
/**
|
||||||
|
* Uses to pass all properties of the HTMLDivElement to the tab header.
|
||||||
|
*/
|
||||||
|
headerProps?: HTMLAttributes | undefined;
|
||||||
|
/**
|
||||||
|
* Uses to pass all properties of the HTMLAnchorElement to the focusable anchor element inside the tab header.
|
||||||
|
*/
|
||||||
|
headerActionProps?: AnchorHTMLAttributes | undefined;
|
||||||
|
/**
|
||||||
|
* Inline style of the tab content.
|
||||||
|
*/
|
||||||
|
contentStyle?: any;
|
||||||
|
/**
|
||||||
|
* Style class of the tab content.
|
||||||
|
*/
|
||||||
|
contentClass?: any;
|
||||||
|
/**
|
||||||
|
* Uses to pass all properties of the HTMLDivElement to the tab content.
|
||||||
|
*/
|
||||||
|
contentProps?: HTMLAttributes | undefined;
|
||||||
/**
|
/**
|
||||||
* Whether the tab is disabled.
|
* Whether the tab is disabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,13 @@ export default {
|
||||||
name: 'AccordionTab',
|
name: 'AccordionTab',
|
||||||
props: {
|
props: {
|
||||||
header: null,
|
header: null,
|
||||||
|
headerStyle: null,
|
||||||
|
headerClass: null,
|
||||||
|
headerProps: null,
|
||||||
|
headerActionProps: null,
|
||||||
|
contentStyle: null,
|
||||||
|
contentClass: null,
|
||||||
|
contentProps: null,
|
||||||
disabled: Boolean
|
disabled: Boolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,18 +218,60 @@ export default {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>header</td>
|
<td>header</td>
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
<td>null</td>
|
<td>null</td>
|
||||||
<td>Orientation of tab headers.</td>
|
<td>Orientation of tab headers.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>disabled</td>
|
<td>headerStyle</td>
|
||||||
<td>boolean</td>
|
<td>string</td>
|
||||||
<td>false</td>
|
<td>null</td>
|
||||||
<td>Whether the tab is disabled.</td>
|
<td>Inline style of the tab header.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>headerClass</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Style class of the tab header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>headerProps</td>
|
||||||
|
<td>object</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Uses to pass all properties of the HTMLDivElement to the tab header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>headerActionProps</td>
|
||||||
|
<td>object</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Uses to pass all properties of the HTMLAnchorElement to the focusable anchor element inside the tab header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>contentStyle</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Inline style of the tab content.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>contentClass</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Style class of the tab content.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>contentProps</td>
|
||||||
|
<td>object</td>
|
||||||
|
<td>null</td>
|
||||||
|
<td>Uses to pass all properties of the HTMLDivElement to the tab content.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>disabled</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>false</td>
|
||||||
|
<td>Whether the tab is disabled.</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -276,6 +318,18 @@ export default {
|
||||||
<td>string</td>
|
<td>string</td>
|
||||||
<td>pi-chevron-down</td>
|
<td>pi-chevron-down</td>
|
||||||
<td>Icon of an expanded tab.</td>
|
<td>Icon of an expanded tab.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>tabindex</td>
|
||||||
|
<td>number</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Index of the element in tabbing order.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>selectOnFocus</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>false</td>
|
||||||
|
<td>When enabled, the focused tab is activated.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -305,6 +359,13 @@ export default {
|
||||||
event.index: Closed tab index
|
event.index: Closed tab index
|
||||||
</td>
|
</td>
|
||||||
<td>Callback to invoke when an active tab is collapsed by clicking on the header.</td>
|
<td>Callback to invoke when an active tab is collapsed by clicking on the header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>tab-click</td>
|
||||||
|
<td>event.originalEvent: Browser event <br/>
|
||||||
|
event.index: Index of the clicked tab
|
||||||
|
</td>
|
||||||
|
<td>Callback to invoke when an active tab is clicked.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -337,6 +398,78 @@ export default {
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h5>Accessibility</h5>
|
||||||
|
<h6>Screen Reader</h6>
|
||||||
|
<p>
|
||||||
|
Accordion header elements have a <i>button</i> role and use <i>aria-controls</i> to define the id of the content section along with <i>aria-expanded</i> for the visibility state. The value to read a header element defaults
|
||||||
|
to the value of the <i>header</i> property and can be customized by defining an <i>aria-label</i> or <i>aria-labelledby</i> via the <i>headerActionProps</i> property.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The content uses <i>region</i> role, defines an id that matches the <i>aria-controls</i> of the header and <i>aria-labelledby</i> referring to the id of the header.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h6>Header Keyboard Support</h6>
|
||||||
|
<div className="doc-tablewrapper">
|
||||||
|
<table className="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>tab</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the next the focusable element in the page tab sequence.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>shift</i> + <i>tab</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the previous the focusable element in the page tab sequence.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>enter</i>
|
||||||
|
</td>
|
||||||
|
<td>Toggles the visibility of the content.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>space</i>
|
||||||
|
</td>
|
||||||
|
<td>Toggles the visibility of the content.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>down arrow</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the next header. If focus is on the last header, moves focus to the first header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>up arrow</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the previous header. If focus is on the first header, moves focus to the last header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>home</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the first header.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i>end</i>
|
||||||
|
</td>
|
||||||
|
<td>Moves focus to the last header.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5>Dependencies</h5>
|
<h5>Dependencies</h5>
|
||||||
<p>None.</p>
|
<p>None.</p>
|
||||||
</AppDoc>
|
</AppDoc>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue