Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien DĂ©ramond <julien.deramond@orange.com>2022-05-06 05:26:15 +0300
committerGitHub <noreply@github.com>2022-05-06 05:26:15 +0300
commit5d9500bdfdd02b3b1d91df2be86b1723f517fc52 (patch)
tree74a29c6a0b05e22bb3efbc5520f19a3faa6ac6aa
parentcca801683dfbc54dc7ae7a6ef6ce4361b071bc36 (diff)
Handle disabled focused tabs with tab JavaScript plugin (#36169)
* Handle disabled tabs * Fix after feedback * Update js/src/tab.js Co-authored-by: GeoSot <geo.sotis@gmail.com> * Update js/src/tab.js Co-authored-by: GeoSot <geo.sotis@gmail.com> * Commit suggestions via GitHub broke the thing * Add some unit tests * Remove temp doc modification * Add tests for left arrow * Add disabled tabs in JavaScript Behavior section * Compact 4 tests to 2 tests * Compact 4 tests to 2 tests * Add 'disabled' attribute for all buttons * Change the disabled pane position only for the vertical version * Change ids for the confusing first example in JavaScript behavior * Use disabled attribute instead of the class for buttons in tabs Co-authored-by: GeoSot <geo.sotis@gmail.com>
-rw-r--r--js/src/tab.js7
-rw-r--r--js/tests/unit/tab.spec.js66
-rw-r--r--scss/_nav.scss9
-rw-r--r--site/content/docs/5.1/components/navs-tabs.md64
4 files changed, 127 insertions, 19 deletions
diff --git a/js/src/tab.js b/js/src/tab.js
index 135e929dda..3fa5e4c9e9 100644
--- a/js/src/tab.js
+++ b/js/src/tab.js
@@ -168,8 +168,11 @@ class Tab extends BaseComponent {
event.stopPropagation()// stopPropagation/preventDefault both added to support up/down keys without scrolling the page
event.preventDefault()
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key)
- const nextActiveElement = getNextActiveElement(this._getChildren(), event.target, isNext, true)
- Tab.getOrCreateInstance(nextActiveElement).show()
+ const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true)
+
+ if (nextActiveElement) {
+ Tab.getOrCreateInstance(nextActiveElement).show()
+ }
}
_getChildren() { // collection of inner elements
diff --git a/js/tests/unit/tab.spec.js b/js/tests/unit/tab.spec.js
index 4b8fb62de6..e6225b23db 100644
--- a/js/tests/unit/tab.spec.js
+++ b/js/tests/unit/tab.spec.js
@@ -548,6 +548,72 @@ describe('Tab', () => {
expect(Event.prototype.stopPropagation).toHaveBeenCalledTimes(2)
expect(Event.prototype.preventDefault).toHaveBeenCalledTimes(2)
})
+
+ it('if keydown event is right arrow and next element is disabled', () => {
+ fixtureEl.innerHTML = [
+ '<div class="nav">',
+ ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
+ ' <span id="tab2" class="nav-link" data-bs-toggle="tab" disabled></span>',
+ ' <span id="tab3" class="nav-link disabled" data-bs-toggle="tab"></span>',
+ ' <span id="tab4" class="nav-link" data-bs-toggle="tab"></span>',
+ '</div>'
+ ].join('')
+
+ const tabEl = fixtureEl.querySelector('#tab1')
+ const tabEl2 = fixtureEl.querySelector('#tab2')
+ const tabEl3 = fixtureEl.querySelector('#tab3')
+ const tabEl4 = fixtureEl.querySelector('#tab4')
+ const tab = new Tab(tabEl)
+ const tab2 = new Tab(tabEl2)
+ const tab3 = new Tab(tabEl3)
+ const tab4 = new Tab(tabEl4)
+ spyOn(tab, 'show').and.callThrough()
+ spyOn(tab2, 'show').and.callThrough()
+ spyOn(tab3, 'show').and.callThrough()
+ spyOn(tab4, 'show').and.callThrough()
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowRight'
+
+ tabEl.dispatchEvent(keydown)
+ expect(tab.show).not.toHaveBeenCalled()
+ expect(tab2.show).not.toHaveBeenCalled()
+ expect(tab3.show).not.toHaveBeenCalled()
+ expect(tab4.show).toHaveBeenCalledTimes(1)
+ })
+
+ it('if keydown event is left arrow and next element is disabled', () => {
+ fixtureEl.innerHTML = [
+ '<div class="nav">',
+ ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
+ ' <span id="tab2" class="nav-link" data-bs-toggle="tab" disabled></span>',
+ ' <span id="tab3" class="nav-link disabled" data-bs-toggle="tab"></span>',
+ ' <span id="tab4" class="nav-link" data-bs-toggle="tab"></span>',
+ '</div>'
+ ].join('')
+
+ const tabEl = fixtureEl.querySelector('#tab1')
+ const tabEl2 = fixtureEl.querySelector('#tab2')
+ const tabEl3 = fixtureEl.querySelector('#tab3')
+ const tabEl4 = fixtureEl.querySelector('#tab4')
+ const tab = new Tab(tabEl)
+ const tab2 = new Tab(tabEl2)
+ const tab3 = new Tab(tabEl3)
+ const tab4 = new Tab(tabEl4)
+ spyOn(tab, 'show').and.callThrough()
+ spyOn(tab2, 'show').and.callThrough()
+ spyOn(tab3, 'show').and.callThrough()
+ spyOn(tab4, 'show').and.callThrough()
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowLeft'
+
+ tabEl4.dispatchEvent(keydown)
+ expect(tab4.show).not.toHaveBeenCalled()
+ expect(tab3.show).not.toHaveBeenCalled()
+ expect(tab2.show).not.toHaveBeenCalled()
+ expect(tab.show).toHaveBeenCalledTimes(1)
+ })
})
describe('jQueryInterface', () => {
diff --git a/scss/_nav.scss b/scss/_nav.scss
index 21ee1b2b44..aa1468e944 100644
--- a/scss/_nav.scss
+++ b/scss/_nav.scss
@@ -74,7 +74,8 @@
border-color: var(--#{$prefix}nav-tabs-link-hover-border-color);
}
- &.disabled {
+ &.disabled,
+ &:disabled {
color: var(--#{$prefix}nav-link-disabled-color);
background-color: transparent;
border-color: transparent;
@@ -112,6 +113,12 @@
background: none;
border: 0;
@include border-radius(var(--#{$prefix}nav-pills-border-radius));
+
+ &:disabled {
+ color: var(--#{$prefix}nav-link-disabled-color);
+ background-color: transparent;
+ border-color: transparent;
+ }
}
.nav-link.active,
diff --git a/site/content/docs/5.1/components/navs-tabs.md b/site/content/docs/5.1/components/navs-tabs.md
index d43058b33e..b3d3067503 100644
--- a/site/content/docs/5.1/components/navs-tabs.md
+++ b/site/content/docs/5.1/components/navs-tabs.md
@@ -335,44 +335,54 @@ Use the tab JavaScript plugin—include it individually or through the compiled
<div class="bd-example">
<ul class="nav nav-tabs mb-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
+ <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
- <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Profile</button>
+ <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-tab-pane" type="button" role="tab" aria-controls="profile-tab-pane" aria-selected="false">Profile</button>
</li>
<li class="nav-item" role="presentation">
- <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Contact</button>
+ <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Contact</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="disabled-tab" data-bs-toggle="tab" data-bs-target="#disabled-tab-pane" type="button" role="tab" aria-controls="disabled-tab-pane" aria-selected="false" disabled>Disabled</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
- <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
+ <div class="tab-pane fade show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
<p>This is some placeholder content the <strong>Home tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
- <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">
+ <div class="tab-pane fade" id="profile-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">
<p>This is some placeholder content the <strong>Profile tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
- <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">
+ <div class="tab-pane fade" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
+ <div class="tab-pane fade" id="disabled-tab-pane" role="tabpanel" aria-labelledby="disabled-tab" tabindex="0">
+ <p>This is some placeholder content the <strong>Disabled tab's</strong> associated content.</p>
+ </div>
</div>
</div>
```html
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
+ <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
- <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Profile</button>
+ <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-tab-pane" type="button" role="tab" aria-controls="profile-tab-pane" aria-selected="false">Profile</button>
</li>
<li class="nav-item" role="presentation">
- <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Contact</button>
+ <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Contact</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="disabled-tab" data-bs-toggle="tab" data-bs-target="#disabled-tab-pane" type="button" role="tab" aria-controls="disabled-tab-pane" aria-selected="false" disabled>Disabled</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
- <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
- <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
- <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">...</div>
+ <div class="tab-pane fade show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="profile-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="disabled-tab-pane" role="tabpanel" aria-labelledby="disabled-tab" tabindex="0">...</div>
</div>
```
@@ -384,6 +394,7 @@ To help fit your needs, this works with `<ul>`-based markup, as shown above, or
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
<button class="nav-link" id="nav-profile-tab" data-bs-toggle="tab" data-bs-target="#nav-profile" type="button" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</button>
<button class="nav-link" id="nav-contact-tab" data-bs-toggle="tab" data-bs-target="#nav-contact" type="button" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</button>
+ <button class="nav-link" id="nav-disabled-tab" data-bs-toggle="tab" data-bs-target="#nav-disabled" type="button" role="tab" aria-controls="nav-disabled" aria-selected="false" disabled>Disabled</button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
@@ -396,6 +407,9 @@ To help fit your needs, this works with `<ul>`-based markup, as shown above, or
<div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
+ <div class="tab-pane fade" id="nav-disabled" role="tabpanel" aria-labelledby="nav-disabled-tab" tabindex="0">
+ <p>This is some placeholder content the <strong>Disabled tab's</strong> associated content.</p>
+ </div>
</div>
</div>
@@ -405,12 +419,14 @@ To help fit your needs, this works with `<ul>`-based markup, as shown above, or
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
<button class="nav-link" id="nav-profile-tab" data-bs-toggle="tab" data-bs-target="#nav-profile" type="button" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</button>
<button class="nav-link" id="nav-contact-tab" data-bs-toggle="tab" data-bs-target="#nav-contact" type="button" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</button>
+ <button class="nav-link" id="nav-disabled-tab" data-bs-toggle="tab" data-bs-target="#nav-disabled" type="button" role="tab" aria-controls="nav-disabled" aria-selected="false" disabled>Disabled</button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="nav-disabled" role="tabpanel" aria-labelledby="nav-disabled-tab" tabindex="0">...</div>
</div>
```
@@ -427,6 +443,9 @@ The tabs plugin also works with pills.
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-contact-tab" data-bs-toggle="pill" data-bs-target="#pills-contact" type="button" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</button>
</li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#pills-disabled" type="button" role="tab" aria-controls="pills-disabled" aria-selected="false" disabled>Disabled</button>
+ </li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" tabindex="0">
@@ -438,6 +457,9 @@ The tabs plugin also works with pills.
<div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
+ <div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">
+ <p>This is some placeholder content the <strong>Disabled tab's</strong> associated content.</p>
+ </div>
</div>
</div>
@@ -452,11 +474,15 @@ The tabs plugin also works with pills.
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-contact-tab" data-bs-toggle="pill" data-bs-target="#pills-contact" type="button" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</button>
</li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#pills-disabled" type="button" role="tab" aria-controls="pills-disabled" aria-selected="false" disabled>Disabled</button>
+ </li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">...</div>
</div>
```
@@ -467,21 +493,25 @@ And with vertical pills. Ideally, for vertical tabs, you should also add `aria-o
<div class="nav flex-column nav-pills me-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<button class="nav-link active" id="v-pills-home-tab" data-bs-toggle="pill" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</button>
<button class="nav-link" id="v-pills-profile-tab" data-bs-toggle="pill" data-bs-target="#v-pills-profile" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</button>
+ <button class="nav-link" id="v-pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#v-pills-disabled" type="button" role="tab" aria-controls="v-pills-disabled" aria-selected="false" disabled>Disabled</button>
<button class="nav-link" id="v-pills-messages-tab" data-bs-toggle="pill" data-bs-target="#v-pills-messages" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</button>
<button class="nav-link" id="v-pills-settings-tab" data-bs-toggle="pill" data-bs-target="#v-pills-settings" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</button>
</div>
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab" tabindex="0">
- <p>This is some placeholder content the <strong>Home tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
+ <p>This is some placeholder content the <strong>Home tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab" tabindex="0">
- <p>This is some placeholder content the <strong>Profile tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
+ <p>This is some placeholder content the <strong>Profile tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
+ </div>
+ <div class="tab-pane fade" id="v-pills-disabled" role="tabpanel" aria-labelledby="v-pills-disabled-tab" tabindex="0">
+ <p>This is some placeholder content the <strong>Disabled tab's</strong> associated content.</p>
</div>
<div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab" tabindex="0">
- <p>This is some placeholder content the <strong>Messages tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
+ <p>This is some placeholder content the <strong>Messages tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
<div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab" tabindex="0">
- <p>This is some placeholder content the <strong>Settings tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
+ <p>This is some placeholder content the <strong>Settings tab's</strong> associated content. Clicking another tab will toggle the visibility of this one for the next. The tab JavaScript swaps classes to control the content visibility and styling. You can use it with tabs, pills, and any other <code>.nav</code>-powered navigation.</p>
</div>
</div>
</div>
@@ -492,12 +522,14 @@ And with vertical pills. Ideally, for vertical tabs, you should also add `aria-o
<div class="nav flex-column nav-pills me-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<button class="nav-link active" id="v-pills-home-tab" data-bs-toggle="pill" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</button>
<button class="nav-link" id="v-pills-profile-tab" data-bs-toggle="pill" data-bs-target="#v-pills-profile" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</button>
+ <button class="nav-link" id="v-pills-disabled-tab" data-bs-toggle="pill" data-bs-target="#v-pills-disabled" type="button" role="tab" aria-controls="v-pills-disabled" aria-selected="false" disabled>Disabled</button>
<button class="nav-link" id="v-pills-messages-tab" data-bs-toggle="pill" data-bs-target="#v-pills-messages" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</button>
<button class="nav-link" id="v-pills-settings-tab" data-bs-toggle="pill" data-bs-target="#v-pills-settings" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</button>
</div>
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab" tabindex="0">...</div>
+ <div class="tab-pane fade" id="v-pills-disabled" role="tabpanel" aria-labelledby="v-pills-disabled-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab" tabindex="0">...</div>
</div>