Compare commits
45 commits
main
...
patrickhla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
897f4db11a | ||
|
|
c11118ba23 | ||
|
|
4fdae4b1a8 | ||
|
|
a13fba81f2 | ||
|
|
79d538703c | ||
|
|
cc5353da66 | ||
|
|
bfe5438af2 | ||
|
|
e81f20cb0e | ||
|
|
349eeeb532 | ||
|
|
76f87e2bef | ||
|
|
a38a3bd904 | ||
|
|
430a1204aa | ||
|
|
fabe1f0e24 | ||
|
|
1687b77a48 | ||
|
|
eb299c90e5 | ||
|
|
65b32a0107 | ||
|
|
eace005286 | ||
|
|
10b293f23e | ||
|
|
ea0e99dfc5 | ||
|
|
d5616fe0ce | ||
|
|
3c8170044a | ||
|
|
7c79b8a80f | ||
|
|
66d0d7b05e | ||
|
|
35179a4aee | ||
|
|
a8cf124b82 | ||
|
|
31dd87c600 | ||
|
|
a1e7738632 | ||
|
|
da9f93da1c | ||
|
|
2e5a010901 | ||
|
|
007c75837d | ||
|
|
8be4c1364f | ||
|
|
3b64256ac5 | ||
|
|
ef0c5c04e3 | ||
|
|
8de6558408 | ||
|
|
d91293d966 | ||
|
|
95ebcedccd | ||
|
|
cbac96d5b0 | ||
|
|
701977bf4e | ||
|
|
d722edcb29 | ||
|
|
53e954c834 | ||
|
|
578444b95e | ||
|
|
78737b239f | ||
|
|
33df950b27 | ||
|
|
7c90656c13 | ||
|
|
f4d85517b9 |
5 changed files with 357 additions and 188 deletions
104
js/src/tab.js
104
js/src/tab.js
|
|
@ -29,17 +29,22 @@ const VERSION = '4.3.1'
|
|||
const DATA_KEY = 'bs.tab'
|
||||
const EVENT_KEY = `.${DATA_KEY}`
|
||||
const DATA_API_KEY = '.data-api'
|
||||
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
|
||||
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
|
||||
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
|
||||
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
|
||||
|
||||
const Event = {
|
||||
HIDE: `hide${EVENT_KEY}`,
|
||||
HIDDEN: `hidden${EVENT_KEY}`,
|
||||
SHOW: `show${EVENT_KEY}`,
|
||||
SHOWN: `shown${EVENT_KEY}`,
|
||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
|
||||
KEYDOWN_DATA_API: `keydown${EVENT_KEY}${DATA_API_KEY}`,
|
||||
LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`
|
||||
}
|
||||
|
||||
const ClassName = {
|
||||
DROPDOWN_MENU: 'dropdown-menu',
|
||||
ACTIVE: 'active',
|
||||
DISABLED: 'disabled',
|
||||
FADE: 'fade',
|
||||
|
|
@ -47,15 +52,16 @@ const ClassName = {
|
|||
}
|
||||
|
||||
const Selector = {
|
||||
DROPDOWN: '.dropdown',
|
||||
NAV_LIST_GROUP: '.nav, .list-group',
|
||||
ACTIVE: '.active',
|
||||
ACTIVE_UL: ':scope > li > .active',
|
||||
DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
|
||||
DROPDOWN_TOGGLE: '.dropdown-toggle',
|
||||
DROPDOWN_ACTIVE_CHILD: ':scope > .dropdown-menu .active'
|
||||
TABLIST: '[role="tablist"]'
|
||||
}
|
||||
|
||||
const ORIENTATION_VERTICAL = 'vertical'
|
||||
const ORIENTATION_HORIZONTAL = 'horizontal'
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
|
|
@ -97,6 +103,7 @@ class Tab {
|
|||
}
|
||||
|
||||
let hideEvent = null
|
||||
this.isTransitioning = true
|
||||
|
||||
if (previous) {
|
||||
hideEvent = EventHandler.trigger(previous, Event.HIDE, {
|
||||
|
|
@ -129,6 +136,7 @@ class Tab {
|
|||
EventHandler.trigger(this._element, Event.SHOWN, {
|
||||
relatedTarget: previous
|
||||
})
|
||||
this.isTransitioning = false
|
||||
}
|
||||
|
||||
if (target) {
|
||||
|
|
@ -175,20 +183,16 @@ class Tab {
|
|||
if (active) {
|
||||
active.classList.remove(ClassName.ACTIVE)
|
||||
|
||||
const dropdownChild = SelectorEngine.findOne(Selector.DROPDOWN_ACTIVE_CHILD, active.parentNode)
|
||||
|
||||
if (dropdownChild) {
|
||||
dropdownChild.classList.remove(ClassName.ACTIVE)
|
||||
}
|
||||
|
||||
if (active.getAttribute('role') === 'tab') {
|
||||
active.setAttribute('aria-selected', false)
|
||||
active.setAttribute('tabindex', '-1')
|
||||
}
|
||||
}
|
||||
|
||||
element.classList.add(ClassName.ACTIVE)
|
||||
if (element.getAttribute('role') === 'tab') {
|
||||
element.setAttribute('aria-selected', true)
|
||||
element.setAttribute('tabindex', '0')
|
||||
}
|
||||
|
||||
reflow(element)
|
||||
|
|
@ -197,17 +201,6 @@ class Tab {
|
|||
element.classList.add(ClassName.SHOW)
|
||||
}
|
||||
|
||||
if (element.parentNode && element.parentNode.classList.contains(ClassName.DROPDOWN_MENU)) {
|
||||
const dropdownElement = SelectorEngine.closest(element, Selector.DROPDOWN)
|
||||
|
||||
if (dropdownElement) {
|
||||
makeArray(SelectorEngine.find(Selector.DROPDOWN_TOGGLE))
|
||||
.forEach(dropdown => dropdown.classList.add(ClassName.ACTIVE))
|
||||
}
|
||||
|
||||
element.setAttribute('aria-expanded', true)
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback()
|
||||
}
|
||||
|
|
@ -229,6 +222,48 @@ class Tab {
|
|||
})
|
||||
}
|
||||
|
||||
static _dataApiKeydownHandler(event) {
|
||||
const tablist = SelectorEngine.closest(event.target, Selector.TABLIST)
|
||||
let tabListOrientation = tablist.getAttribute('aria-orientation')
|
||||
if (tabListOrientation !== ORIENTATION_VERTICAL) {
|
||||
tabListOrientation = ORIENTATION_HORIZONTAL
|
||||
}
|
||||
|
||||
if ((tabListOrientation === ORIENTATION_HORIZONTAL && event.which !== ARROW_LEFT_KEYCODE && event.which !== ARROW_RIGHT_KEYCODE) ||
|
||||
(tabListOrientation === ORIENTATION_VERTICAL && event.which !== ARROW_UP_KEYCODE && event.which !== ARROW_DOWN_KEYCODE)) {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
if (this.disabled || this.classList.contains(ClassName.DISABLED)) {
|
||||
return
|
||||
}
|
||||
|
||||
const tabs = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE, tablist))
|
||||
|
||||
let index = tabs.indexOf(event.target)
|
||||
const tabInstance = Data.getData(tabs[index], DATA_KEY) || new Tab(tabs[index])
|
||||
|
||||
if (tabInstance.isTransitioning) {
|
||||
return
|
||||
}
|
||||
|
||||
// Left / Up
|
||||
if ((event.which === ARROW_LEFT_KEYCODE || event.which === ARROW_UP_KEYCODE) && index > 0) {
|
||||
index--
|
||||
}
|
||||
|
||||
// Right / Down
|
||||
if ((event.which === ARROW_RIGHT_KEYCODE || event.which === ARROW_DOWN_KEYCODE) && index < tabs.length - 1) {
|
||||
index++
|
||||
}
|
||||
|
||||
tabs[index].focus()
|
||||
tabs[index].click()
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
|
|
@ -240,6 +275,31 @@ class Tab {
|
|||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
EventHandler.on(window, Event.LOAD_DATA_API, () => {
|
||||
makeArray(SelectorEngine.find(Selector.TABLIST))
|
||||
.forEach(tablist => {
|
||||
const tabs = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE, tablist))
|
||||
let selectedTabFound = false
|
||||
|
||||
// iterate over each tab in the tablist, make sure they have correct tabindex/aria-selected
|
||||
tabs.forEach(tab => {
|
||||
if (tab.getAttribute('aria-selected') === 'true' && !selectedTabFound) {
|
||||
tab.setAttribute('tabindex', '0')
|
||||
selectedTabFound = true
|
||||
} else {
|
||||
tab.setAttribute('tabindex', '-1')
|
||||
tab.setAttribute('aria-selected', 'false')
|
||||
}
|
||||
})
|
||||
|
||||
// if none of the tabs were explicitly marked as selected, pick first one
|
||||
if (!selectedTabFound) {
|
||||
tabs[0].setAttribute('tabindex', '0')
|
||||
tabs[0].setAttribute('aria-selected', 'true')
|
||||
}
|
||||
})
|
||||
})
|
||||
EventHandler.on(document, Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Tab._dataApiKeydownHandler)
|
||||
EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
||||
event.preventDefault()
|
||||
|
||||
|
|
|
|||
|
|
@ -180,35 +180,6 @@ $(function () {
|
|||
.bootstrapTab('show')
|
||||
})
|
||||
|
||||
QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
||||
var dropHTML =
|
||||
'<ul class="drop nav">' +
|
||||
' <li class="dropdown"><a data-toggle="dropdown" href="#">1</a>' +
|
||||
' <ul class="dropdown-menu nav">' +
|
||||
' <li><a href="#a1-1" data-toggle="tab">1-1</a></li>' +
|
||||
' <li><a href="#a1-2" data-toggle="tab">1-2</a></li>' +
|
||||
' </ul>' +
|
||||
' </li>' +
|
||||
'</ul>'
|
||||
|
||||
$(dropHTML)
|
||||
.find('ul > li:first-child a')
|
||||
.bootstrapTab('show')
|
||||
.end()
|
||||
.find('ul > li:last-child a')
|
||||
.on('show.bs.tab', function (e) {
|
||||
assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
|
||||
})
|
||||
.on('shown.bs.tab', function (e) {
|
||||
assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
|
||||
done()
|
||||
})
|
||||
.bootstrapTab('show')
|
||||
})
|
||||
|
||||
QUnit.test('should fire hide and hidden events', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
|
@ -265,6 +236,30 @@ $(function () {
|
|||
.bootstrapTab('show')
|
||||
})
|
||||
|
||||
QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav">' +
|
||||
'<li><a href="#home">Home</a></li>' +
|
||||
'<li><a href="#profile">Profile</a></li>' +
|
||||
'</ul>'
|
||||
|
||||
$(tabsHTML)
|
||||
.find('li:first-child a')
|
||||
.bootstrapTab('show')
|
||||
.end()
|
||||
.find('li:last-child a')
|
||||
.on('show.bs.tab', function (e) {
|
||||
assert.strictEqual(e.relatedTarget.hash, '#home', 'references correct element as relatedTarget')
|
||||
})
|
||||
.on('shown.bs.tab', function (e) {
|
||||
assert.strictEqual(e.relatedTarget.hash, '#home', 'references correct element as relatedTarget')
|
||||
done()
|
||||
})
|
||||
.bootstrapTab('show')
|
||||
})
|
||||
|
||||
QUnit.test('hide and hidden events contain correct relatedTarget', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
|
@ -291,9 +286,9 @@ $(function () {
|
|||
|
||||
QUnit.test('selected tab should have aria-selected', function (assert) {
|
||||
assert.expect(8)
|
||||
var tabsHTML = '<ul class="nav nav-tabs">' +
|
||||
'<li><a class="nav-item active" href="#home" toggle="tab" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" toggle="tab" aria-selected="false">Profile</a></li>' +
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab" role="tab" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab" role="tab" aria-selected="false">Profile</a></li>' +
|
||||
'</ul>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
|
|
@ -327,26 +322,6 @@ $(function () {
|
|||
assert.ok($tabs.find('li:last-child a').hasClass('active'))
|
||||
})
|
||||
|
||||
QUnit.test('selected tab should deactivate previous selected link in dropdown', function (assert) {
|
||||
assert.expect(3)
|
||||
var tabsHTML = '<ul class="nav nav-tabs">' +
|
||||
'<li class="nav-item"><a class="nav-link" href="#home" data-toggle="tab">Home</a></li>' +
|
||||
'<li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>' +
|
||||
'<li class="nav-item dropdown"><a class="nav-link dropdown-toggle active" data-toggle="dropdown" href="#">Dropdown</a>' +
|
||||
'<div class="dropdown-menu">' +
|
||||
'<a class="dropdown-item active" href="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>' +
|
||||
'<a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>' +
|
||||
'</div>' +
|
||||
'</li>' +
|
||||
'</ul>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
$tabs.find('li:first-child a')[0].click()
|
||||
assert.ok($tabs.find('li:first-child a').hasClass('active'))
|
||||
assert.notOk($tabs.find('li:last-child a').hasClass('active'))
|
||||
assert.notOk($tabs.find('li:last-child .dropdown-menu a:first-child').hasClass('active'))
|
||||
})
|
||||
|
||||
QUnit.test('Nested tabs', function (assert) {
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
|
@ -523,6 +498,213 @@ $(function () {
|
|||
$('#secondNav')[0].click()
|
||||
})
|
||||
|
||||
QUnit.test('should initialize tab list: only one tab control focusable and aria-selected', function (assert) {
|
||||
assert.expect(5)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab" role="tab" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab" role="tab" aria-selected="true">Profile</a></li>' +
|
||||
'<li><a class="nav-item" href="#contact" data-toggle="tab" role="tab" aria-selected="true">Contact</a></li>' +
|
||||
'</ul>' /* purposely incorrect, with all set to aria-selected="true" */
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
window.dispatchEvent(new Event('load'))
|
||||
|
||||
setTimeout(function () {
|
||||
assert.strictEqual($tabs.find('li:first-child a').attr('tabindex'), '0', 'first found aria-selected="true" control has been given tabindex="0"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(2) a').attr('tabindex'), '-1', 'second control has been given tabindex="-1"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(2) a').attr('aria-selected'), 'false', 'second control has been given aria-selected="false"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(3) a').attr('tabindex'), '-1', 'third control has been given tabindex="-1"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(3) a').attr('aria-selected'), 'false', 'third control has been given aria-selected="false"')
|
||||
done()
|
||||
}, 10)
|
||||
})
|
||||
|
||||
QUnit.test('should initialize tab list: if no tab control has aria-selected="true", set it to the first one', function (assert) {
|
||||
assert.expect(3)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab">Profile</a></li>' +
|
||||
'<li><a class="nav-item" href="#contact" data-toggle="tab">Contact</a></li>' +
|
||||
'</ul>' /* purposely incorrect, left out aria-selected="true" on active one */
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
window.dispatchEvent(new Event('load'))
|
||||
|
||||
setTimeout(function () {
|
||||
assert.strictEqual($tabs.find('li:first-child a').attr('aria-selected'), 'true', 'first control has been given aria-selected="true"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(2) a').attr('aria-selected'), 'false', 'second control has been given aria-selected="false"')
|
||||
assert.strictEqual($tabs.find('li:nth-child(3) a').attr('aria-selected'), 'false', 'third control has been given aria-selected="false"')
|
||||
done()
|
||||
}, 10)
|
||||
})
|
||||
|
||||
QUnit.test('should correctly switch tabs in response to left/right cursor keys (for horizontal/default tablist) and ignore up/down cursor keys', function (assert) {
|
||||
assert.expect(27)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab" role="tab" tabindex="0" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Profile</a></li>' +
|
||||
'<li><a class="nav-item" href="#contact" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Contact</a></li>' +
|
||||
'</ul>' +
|
||||
'<div class="tab-pane show active" id="home" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane" id="profile" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane" id="contact" role="tabpanel">...</div>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
var $firstTab = $tabs.find('li:first-child a')
|
||||
var $secondTab = $tabs.find('li:nth-child(2) a')
|
||||
var $thirdTab = $tabs.find('li:nth-child(3) a')
|
||||
$firstTab[0].focus() /* set focus to first tab */
|
||||
assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
|
||||
/* right cursor key */
|
||||
var keyDown = new Event('keydown')
|
||||
keyDown.which = 39
|
||||
$firstTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $firstTab[0], 'after 1st right cursor key, first tab not focused anymore')
|
||||
assert.ok(!$firstTab.hasClass('active'), 'after 1st right cursor key, first tab not `.active` anymore')
|
||||
assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st right cursor key, first tab has aria-selected="false"')
|
||||
assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st right cursor key, first tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after 1st right cursor key, second tab is focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after 1st right cursor key, second tab is `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st right cursor key, second tab has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after 1st right cursor key, second tab has tabindex="0"')
|
||||
/* right cursor key */
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $secondTab[0], 'after 2nd right cursor key, second tab not focused anymore')
|
||||
assert.ok(!$secondTab.hasClass('active'), 'after 2nd right cursor key, second tab not `.active` anymore')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'false', 'after 2nd right cursor key, second tab has aria-selected="false"')
|
||||
assert.ok($secondTab.attr('tabindex') === '-1', 'after 2nd right cursor key, second tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $thirdTab[0], 'after 2nd right cursor key, third tab is focused')
|
||||
assert.ok($thirdTab.hasClass('active'), 'after 2nd right cursor key, third tab is `.active`')
|
||||
assert.ok($thirdTab.attr('aria-selected') === 'true', 'after 2nd right cursor key, third tab has aria-selected="true"')
|
||||
assert.ok($thirdTab.attr('tabindex') === '0', 'after 2nd right cursor key, third tab has tabindex="0"')
|
||||
/* left cursor key */
|
||||
keyDown.which = 37
|
||||
$thirdTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $thirdTab[0], 'after left cursor key, third tab not focused anymore')
|
||||
assert.ok(!$thirdTab.hasClass('active'), 'after left cursor key, third tab not `.active` anymore')
|
||||
assert.ok($thirdTab.attr('aria-selected') === 'false', 'after left cursor key, third tab has aria-selected="false"')
|
||||
assert.ok($thirdTab.attr('tabindex') === '-1', 'after left cursor key, third tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after left cursor key, second tab is focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after left cursor key, second tab is `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after left cursor key, second tab has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after left cursor key, second tab has tabindex="0"')
|
||||
/* up cursor key */
|
||||
keyDown.which = 38
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after up cursor key, second tab is still focused - no change')
|
||||
/* down cursor key */
|
||||
keyDown.which = 40
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after down cursor key, second tab is still focused - no change')
|
||||
done()
|
||||
})
|
||||
|
||||
QUnit.test('should correctly switch tabs in response to up/down cursor keys for vertical tablist and ignore left/right cursor keys', function (assert) {
|
||||
assert.expect(27)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist" aria-orientation="vertical">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab" role="tab" tabindex="0" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Profile</a></li>' +
|
||||
'<li><a class="nav-item" href="#contact" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Contact</a></li>' +
|
||||
'</ul>' +
|
||||
'<div class="tab-pane show active" id="home" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane" id="profile" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane" id="contact" role="tabpanel">...</div>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
var $firstTab = $tabs.find('li:first-child a')
|
||||
var $secondTab = $tabs.find('li:nth-child(2) a')
|
||||
var $thirdTab = $tabs.find('li:nth-child(3) a')
|
||||
$firstTab[0].focus() /* set focus to first tab */
|
||||
assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
|
||||
/* down cursor key */
|
||||
var keyDown = new Event('keydown')
|
||||
keyDown.which = 40
|
||||
$firstTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $firstTab[0], 'after 1st down cursor key, first tab not focused anymore')
|
||||
assert.ok(!$firstTab.hasClass('active'), 'after 1st down cursor key, first tab not `.active` anymore')
|
||||
assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st down cursor key, first tab has aria-selected="false"')
|
||||
assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st down cursor key, first tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after 1st down cursor key, second tab is focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after 1st down cursor key, second tab is `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st down cursor key, second tab has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after 1st down cursor key, second tab has tabindex="0"')
|
||||
/* down cursor key */
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $secondTab[0], 'after 2nd down cursor key, second tab not focused anymore')
|
||||
assert.ok(!$secondTab.hasClass('active'), 'after 2nd down cursor key, second tab not `.active` anymore')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'false', 'after 2nd down cursor key, second tab has aria-selected="false"')
|
||||
assert.ok($secondTab.attr('tabindex') === '-1', 'after 2nd down cursor key, second tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $thirdTab[0], 'after 2nd down cursor key, third tab is focused')
|
||||
assert.ok($thirdTab.hasClass('active'), 'after 2nd down cursor key, third tab is `.active`')
|
||||
assert.ok($thirdTab.attr('aria-selected') === 'true', 'after 2nd down cursor key, third tab has aria-selected="true"')
|
||||
assert.ok($thirdTab.attr('tabindex') === '0', 'after 2nd down cursor key, third tab has tabindex="0"')
|
||||
/* up cursor key */
|
||||
keyDown.which = 38
|
||||
$thirdTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $thirdTab[0], 'after up cursor key, third tab not focused anymore')
|
||||
assert.ok(!$thirdTab.hasClass('active'), 'after up cursor key, third tab not `.active` anymore')
|
||||
assert.ok($thirdTab.attr('aria-selected') === 'false', 'after up cursor key, third tab has aria-selected="false"')
|
||||
assert.ok($thirdTab.attr('tabindex') === '-1', 'after up cursor key, third tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after up cursor key, second tab is focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after up cursor key, second tab is `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after up cursor key, second tab has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after up cursor key, second tab has tabindex="0"')
|
||||
/* left cursor key */
|
||||
keyDown.which = 37
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after left cursor key, second tab is still focused - no change')
|
||||
/* right cursor key */
|
||||
keyDown.which = 39
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after right cursor key, second tab is still focused - no change')
|
||||
done()
|
||||
})
|
||||
|
||||
QUnit.test('should not switch tabs in response to cursor keys if tab panel still transitioning', function (assert) {
|
||||
assert.expect(13)
|
||||
var done = assert.async()
|
||||
|
||||
var tabsHTML = '<ul class="nav nav-tabs" role="tablist">' +
|
||||
'<li><a class="nav-item active" href="#home" data-toggle="tab" role="tab" tabindex="0" aria-selected="true">Home</a></li>' +
|
||||
'<li><a class="nav-item" href="#profile" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Profile</a></li>' +
|
||||
'<li><a class="nav-item" href="#contact" data-toggle="tab" role="tab" tabindex="-1" aria-selected="false">Contact</a></li>' +
|
||||
'</ul>' +
|
||||
'<div class="tab-pane fade show active" id="home" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane fade" id="profile" role="tabpanel">...</div>' +
|
||||
'<div class="tab-pane fade" id="contact" role="tabpanel">...</div>'
|
||||
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
|
||||
|
||||
var $firstTab = $tabs.find('li:first-child a')
|
||||
var $secondTab = $tabs.find('li:nth-child(2) a')
|
||||
$firstTab[0].focus() /* set focus to first tab */
|
||||
assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
|
||||
/* right cursor key */
|
||||
var keyDown = new Event('keydown')
|
||||
keyDown.which = 39
|
||||
$firstTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement !== $firstTab[0], 'after 1st right cursor key, first tab not focused anymore')
|
||||
assert.ok(!$firstTab.hasClass('active'), 'after 1st right cursor key, first tab not `.active` anymore')
|
||||
assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st right cursor key, first tab has aria-selected="false"')
|
||||
assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st right cursor key, first tab has tabindex="-1"')
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after 1st right cursor key, second tab is focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after 1st right cursor key, second tab is `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st right cursor key, second tab has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after 1st right cursor key, second tab has tabindex="0"')
|
||||
/* right cursor key - as this is fired so quickly, the tab panel is still transitioning */
|
||||
$secondTab[0].dispatchEvent(keyDown)
|
||||
assert.ok(document.activeElement === $secondTab[0], 'after 2nd right cursor key, while tab panel still transitioning, second tab is still focused')
|
||||
assert.ok($secondTab.hasClass('active'), 'after 2nd right cursor key, while tab panel still transitioning, second tab is still `.active`')
|
||||
assert.ok($secondTab.attr('aria-selected') === 'true', 'after 2nd right cursor key, while tab panel still transitioning, second tab still has aria-selected="true"')
|
||||
assert.ok($secondTab.attr('tabindex') === '0', 'after 2nd right cursor key, while tab panel still transitioning, second tab still has tabindex="0"')
|
||||
done()
|
||||
})
|
||||
|
||||
QUnit.test('should return the version', function (assert) {
|
||||
assert.expect(1)
|
||||
assert.strictEqual(typeof Tab.VERSION, 'string')
|
||||
|
|
|
|||
|
|
@ -24,16 +24,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#profile" role="tab">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="dropdown" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown">
|
||||
<a class="dropdown-item" data-toggle="tab" href="#fat" role="tab">@fat</a>
|
||||
<a class="dropdown-item" data-toggle="tab" href="#mdo" role="tab">@mdo</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" role="tablist">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="home" role="tabpanel">
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
|
|
@ -42,14 +35,6 @@
|
|||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
</div>
|
||||
<div class="tab-pane" id="fat" role="tabpanel">
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
</div>
|
||||
<div class="tab-pane" id="mdo" role="tabpanel">
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Tabs with fade</h4>
|
||||
|
|
@ -61,16 +46,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#profile2" role="tab">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="dropdown2" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown2">
|
||||
<a class="dropdown-item" data-toggle="tab" href="#fat2" role="tab">@fat</a>
|
||||
<a class="dropdown-item" data-toggle="tab" href="#mdo2" role="tab">@mdo</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" role="tablist">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="home2" role="tabpanel">
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
|
|
@ -79,14 +57,6 @@
|
|||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="fat2" role="tabpanel">
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="mdo2" role="tabpanel">
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Tabs without fade (no initially active pane)</h4>
|
||||
|
|
@ -98,16 +68,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#profile3" role="tab">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="dropdown3" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown3">
|
||||
<a class="dropdown-item" data-toggle="tab" href="#fat3" role="tab">@fat</a>
|
||||
<a class="dropdown-item" data-toggle="tab" href="#mdo3" role="tab">@mdo</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" role="tablist">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" id="home3" role="tabpanel">
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
|
|
@ -116,14 +79,6 @@
|
|||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
</div>
|
||||
<div class="tab-pane" id="fat3" role="tabpanel">
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
</div>
|
||||
<div class="tab-pane" id="mdo3" role="tabpanel">
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Tabs with fade (no initially active pane)</h4>
|
||||
|
|
@ -135,13 +90,6 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#profile4" role="tab">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="dropdown4" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown4">
|
||||
<a class="dropdown-item" data-toggle="tab" href="#fat4" role="tab">@fat</a>
|
||||
<a class="dropdown-item" data-toggle="tab" href="#mdo4" role="tab">@mdo</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
|
@ -153,53 +101,30 @@
|
|||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="fat4" role="tabpanel">
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="mdo4" role="tabpanel">
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Tabs with nav (with fade)</h4>
|
||||
<nav class="nav nav-pills">
|
||||
<a class="nav-link nav-item active" data-toggle="tab" href="#home5">Home</a>
|
||||
<a class="nav-link nav-item" data-toggle="tab" href="#profile5">Profile</a>
|
||||
<div class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="dropdown5" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown5">
|
||||
<a class="dropdown-item" data-toggle="tab" href="#fat5">@fat</a>
|
||||
<a class="dropdown-item" data-toggle="tab" href="#mdo5">@mdo</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="nav-link nav-item disabled" href="#">Disabled</a>
|
||||
</nav>
|
||||
<div class="nav nav-pills" role="tablist">
|
||||
<a class="nav-link nav-item active" data-toggle="tab" role="tab" href="#home5">Home</a>
|
||||
<a class="nav-link nav-item" data-toggle="tab" role="tab" href="#profile5">Profile</a>
|
||||
<a class="nav-link nav-item disabled" data-toggle="tab" role="tab" href="#">Disabled</a>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" role="tabpanel">
|
||||
<div role="tabpanel" class="tab-pane fade show active" id="home5">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="home5" role="tabpanel">
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="profile5">
|
||||
<div class="tab-pane fade" id="profile5" role="tabpanel">
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="fat5" role="tabpanel">
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="mdo5" role="tabpanel">
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
<p>Trust fund seitan letterpress, keytar raw denim keffiyeh etsy art party before they sold out master cleanse gluten-free squid scenester freegan cosby sweater. Fanny pack portland seitan DIY, art party locavore wolf cliche high life echo park Austin. Cred vinyl keffiyeh DIY salvia PBR, banh mi before they sold out farm-to-table VHS viral locavore cosby sweater. Lomo wolf viral, mustache readymade thundercats keffiyeh craft beer marfa ethical. Wolf salvia freegan, sartorial keffiyeh echo park vegan.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Tabs with list-group (with fade)</h4>
|
||||
<h4>Tabs with list-group (vertical, with fade)</h4>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="list-group" id="list-tab" role="tablist">
|
||||
<div class="list-group" id="list-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" href="#list-home" role="tab" aria-controls="list-home">Home</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" href="#list-profile" role="tab" aria-controls="list-profile">Profile</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ Use the tab JavaScript plugin—include it individually or through the compiled
|
|||
<div class="bd-example" role="tabpanel">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="list-group" id="list-tab" role="tablist">
|
||||
<div class="list-group" id="list-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" href="#list-home" role="tab" aria-controls="list-home">Home</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" href="#list-profile" role="tab" aria-controls="list-profile">Profile</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
|
||||
|
|
@ -234,7 +234,7 @@ Use the tab JavaScript plugin—include it individually or through the compiled
|
|||
{{< highlight html >}}
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="list-group" id="list-tab" role="tablist">
|
||||
<div class="list-group" id="list-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" href="#list-home" role="tab" aria-controls="home">Home</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
|
||||
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
|
||||
|
|
@ -259,7 +259,7 @@ You can activate a list group navigation without writing any JavaScript by simpl
|
|||
<div role="tabpanel">
|
||||
{{< highlight html >}}
|
||||
<!-- List group -->
|
||||
<div class="list-group" id="myList" role="tablist">
|
||||
<div class="list-group" id="myList" role="tablist" aria-orientation="vertical">
|
||||
<a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
|
||||
<a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
|
||||
<a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
|
||||
|
|
@ -316,7 +316,7 @@ To make tabs panel fade in, add `.fade` to each `.tab-pane`. The first tab pane
|
|||
Activates a list item element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.
|
||||
|
||||
{{< highlight html >}}
|
||||
<div class="list-group" id="myList" role="tablist">
|
||||
<div class="list-group" id="myList" role="tablist" aria-orientation="vertical">
|
||||
<a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
|
||||
<a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
|
||||
<a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
|
||||
|
|
|
|||
|
|
@ -307,17 +307,19 @@ Use the tab JavaScript plugin—include it individually or through the compiled
|
|||
|
||||
Dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers).
|
||||
|
||||
Note that dynamic tabbed interfaces should <em>not</em> contain dropdown menus, as this causes both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies.
|
||||
{{< callout warning >}}
|
||||
Dynamic tabbed interfaces <em>can't</em> contain dropdown menus, as this causes both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies.
|
||||
{{< /callout >}}
|
||||
|
||||
<div class="bd-example">
|
||||
<ul class="nav nav-tabs mb-3" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -336,13 +338,13 @@ Note that dynamic tabbed interfaces should <em>not</em> contain dropdown menus,
|
|||
|
||||
{{< highlight html >}}
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -395,13 +397,13 @@ The tabs plugin also works with pills.
|
|||
|
||||
<div class="bd-example">
|
||||
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -420,13 +422,13 @@ The tabs plugin also works with pills.
|
|||
|
||||
{{< highlight html >}}
|
||||
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -437,7 +439,7 @@ The tabs plugin also works with pills.
|
|||
</div>
|
||||
{{< /highlight >}}
|
||||
|
||||
And with vertical pills.
|
||||
When making vertical tab panels, make sure to include `aria-orientation="vertical"` to switch to the appropriate keyboard behavior (switching tabs with the up and down cursor keys).
|
||||
|
||||
<div class="bd-example">
|
||||
<div class="row">
|
||||
|
|
@ -496,16 +498,16 @@ You can activate a tab or pill navigation without writing any JavaScript by simp
|
|||
{{< highlight html >}}
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -564,16 +566,16 @@ Activates a tab element and content container. Tab should have either a `data-ta
|
|||
|
||||
{{< highlight html >}}
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" role="presentation">
|
||||
<a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue