]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Nav & Tab docs updates, plus add Chip Input to JS bundle (#42214)
authorMark Otto <markd.otto@gmail.com>
Sat, 21 Mar 2026 16:03:17 +0000 (09:03 -0700)
committerGitHub <noreply@github.com>
Sat, 21 Mar 2026 16:03:17 +0000 (09:03 -0700)
* Document data attributes

* Split nav and tab docs

* Fix v6 todo: reduce selectors in JS tab plugin

* fix css lint

* bump bw

* fix ids

32 files changed:
.bundlewatch.config.json
js/index.js
js/src/tab.js
site/data/plugins.yml
site/data/sidebar.yml
site/src/assets/examples/cheatsheet/index.astro
site/src/content/docs/components/alert.mdx
site/src/content/docs/components/button-group.mdx
site/src/content/docs/components/buttons.mdx
site/src/content/docs/components/card.mdx
site/src/content/docs/components/carousel.mdx
site/src/content/docs/components/collapse.mdx
site/src/content/docs/components/dialog.mdx
site/src/content/docs/components/list-group.mdx
site/src/content/docs/components/menu.mdx
site/src/content/docs/components/nav-overflow.mdx
site/src/content/docs/components/nav.mdx [new file with mode: 0644]
site/src/content/docs/components/navs-tabs.mdx [deleted file]
site/src/content/docs/components/offcanvas.mdx
site/src/content/docs/components/popover.mdx
site/src/content/docs/components/scrollspy.mdx
site/src/content/docs/components/tab.mdx [new file with mode: 0644]
site/src/content/docs/components/toasts.mdx
site/src/content/docs/components/toggler.mdx
site/src/content/docs/components/tooltip.mdx
site/src/content/docs/forms/chip-input.mdx
site/src/content/docs/forms/combobox.mdx
site/src/content/docs/forms/datepicker.mdx
site/src/content/docs/forms/otp-input.mdx
site/src/content/docs/forms/password-strength.mdx
site/src/content/docs/getting-started/javascript.mdx
site/src/scss/_component-examples.scss

index f3919c52c74f9f41c5ea13b8ca916365d55acc13..305ddefb56155a0ded8e552c627b42725eac58e2 100644 (file)
     },
     {
       "path": "./dist/js/bootstrap.bundle.js",
-      "maxSize": "70.0 kB"
+      "maxSize": "72.5 kB"
     },
     {
       "path": "./dist/js/bootstrap.bundle.min.js",
-      "maxSize": "49.25 kB"
+      "maxSize": "51.0 kB"
     },
     {
       "path": "./dist/js/bootstrap.js",
-      "maxSize": "41.0 kB"
+      "maxSize": "43.5 kB"
     },
     {
       "path": "./dist/js/bootstrap.min.js",
-      "maxSize": "27.0 kB"
+      "maxSize": "28.75 kB"
     }
   ],
   "ci": {
index 45bd3086efa8aec96e024359807cac7b3a8135f8..abba7cd17fa18ac685f140d137998666d8171e3e 100644 (file)
@@ -17,6 +17,7 @@ export { default as NavOverflow } from './src/nav-overflow.js'
 export { default as Offcanvas } from './src/offcanvas.js'
 export { default as Strength } from './src/strength.js'
 export { default as OtpInput } from './src/otp-input.js'
+export { default as ChipInput } from './src/chip-input.js'
 export { default as Popover } from './src/popover.js'
 export { default as ScrollSpy } from './src/scrollspy.js'
 export { default as Tab } from './src/tab.js'
index b32e08236ff93ad0b1a72f398a9d4ec6e69badcb..f02519eb97b863eb8d3dd852b46e508e64c2334b 100644 (file)
@@ -43,10 +43,10 @@ const NOT_SELECTOR_MENU_TOGGLE = `:not(${SELECTOR_MENU_TOGGLE})`
 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'
 const SELECTOR_OUTER = '.nav-item, .list-group-item'
 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_MENU_TOGGLE}, .list-group-item${NOT_SELECTOR_MENU_TOGGLE}, [role="tab"]${NOT_SELECTOR_MENU_TOGGLE}`
-const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]' // TODO: could only be `tab` in v6
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"]'
 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`
 
-const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`
+const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"]`
 
 /**
  * Class definition
index 191740aaf0c2a32c1391df346e5fdad7ef001bc8..7333ce4d4d099063e877d89ef5871ff8007edc6f 100644 (file)
@@ -40,7 +40,7 @@
 
 - name: Tab
   description: Allow Bootstrap nav components to toggle contents.
-  link: components/navs-tabs/
+  link: components/tab/
 
 - name: Toast
   description: Show and hide notifications to your visitors.
index 0a17e0f3618bdc75d9b81620a62750cf71ac6172..143693eb727f72465b9e1bff9d9f2971daa8c5a0 100644 (file)
       pages:
         - title: Breadcrumb
         - title: Menu
-        - title: Navs & tabs
+        - title: Nav
+        - title: Tab
         - title: Nav overflow
         - title: Navbar
         - title: Pagination
index c4cc275804b9f779008fb6a4228c970f7cdc5052..19387f1dc7cbe22fb43a7df20066267f6209b852 100644 (file)
@@ -1118,7 +1118,7 @@ export const body_class = 'bg-body-tertiary'
     <article class="my-3" id="navs">
       <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
         <h3>Navs</h3>
-        <a class="d-flex align-items-center" href={getVersionedDocsPath('components/navs-tabs')}>Documentation</a>
+        <a class="d-flex align-items-center" href={getVersionedDocsPath('components/nav')}>Documentation</a>
       </div>
 
       <div>
index edfe19f75d55155bb076139de03122f3b7e8a1c2..7657979b56390dc319f8061da6b9df0138ddf633 100644 (file)
@@ -120,6 +120,14 @@ For the sole purpose of dismissing an alert, it isn’t necessary to initialize
 See the [triggers](#triggers) section for more details.
 </Callout>
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-dismiss="alert"` | On a close control, dismisses (and removes) the alert when activated. |
+</BsTable>
+
 ### Triggers
 
 <JsDismiss name="alert" />
index 44cb18257b93b8c7aa0151d24259821523e65068..c90584b121a8c374e7201b7fee4f414fed27fc3b 100644 (file)
@@ -18,7 +18,7 @@ Wrap a series of buttons in `.btn-group`.
 Button groups require an appropriate `role` attribute and explicit label to ensure assistive technologies like screen readers identify buttons as grouped and announce them. Use `role="group"` for button groups or `role="toolbar"` for button toolbars. Then use `aria-label` or `aria-labelledby` to label them.
 </Callout>
 
-These classes can also be added to groups of links, as an alternative to the [`.nav` navigation components]([[docsref:/components/navs-tabs]]).
+These classes can also be added to groups of links, as an alternative to the [`.nav` navigation components]([[docsref:/components/nav]]).
 
 <Example code={`<div class="btn-group">
     <a href="#" class="btn-solid theme-primary active" aria-current="page">Active link</a>
index 5248549755220b105cdc814c391e6ea07df7feb3..bfc57eee8efacb9e13aae7516b63bd37eb17b142 100644 (file)
@@ -248,6 +248,14 @@ Add `data-bs-toggle="button"` to toggle a button’s `active` state. If you’re
   <a href="#" class="btn-solid theme-primary active" role="button" data-bs-toggle="button" aria-pressed="true">Active toggle link</a>
   <a class="btn-solid theme-primary disabled" aria-disabled="true" role="button" data-bs-toggle="button">Disabled toggle link</a>`} />
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="button"` | Toggles the button’s active (`pressed`) state via the Button plugin. |
+</BsTable>
+
 ### Methods
 
 You can create a button instance with the button constructor, for example:
index 424a7bfbbf0cd2046ae25d738486b2f75c3c96bd..97ffba37905c566cafaa3370824b47c3f435f538 100644 (file)
@@ -257,7 +257,7 @@ Use custom CSS in your stylesheets or as inline styles to set a width.
 
 ## Navigation
 
-Add some navigation to a card’s header (or block) with Bootstrap’s [nav components]([[docsref:/components/navs-tabs]]).
+Add some navigation to a card’s header (or block) with Bootstrap’s [nav components]([[docsref:/components/nav]]).
 
 <Example code={`<div class="card text-center">
     <div class="card-header">
index b183875ec65dba576aed2400d1aab7d7b48356cd..0a1dea2a123ebd7053f3f28fd832e43df7c96fb8 100644 (file)
@@ -337,6 +337,15 @@ Tokens for the [dark carousel](#dark-carousel):
 
 Use data attributes to easily control the position of the carousel. `data-bs-slide` accepts the keywords `prev` or `next`, which alters the slide position relative to its current position. Alternatively, use `data-bs-slide-to` to pass a raw slide index to the carousel `data-bs-slide-to="2"`, which shifts the slide position to a particular index beginning with `0`.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-ride` | Starts autoplay after the first manual cycle (`true`) or on load (`carousel`). |
+| `data-bs-slide` | `prev` or `next` to move the carousel relative to the current slide. |
+| `data-bs-slide-to` | Zero-based index of the slide to show. |
+| `data-bs-interval` | Autoplay interval in milliseconds between slides. |
+</BsTable>
+
 ### Via JavaScript
 
 Call carousel manually with:
index 3c6ff9291f4ffa4c32a98bc30183c4f50f2a2331..e1640495854ea82c72707f642de8117ed01c01df 100644 (file)
@@ -118,6 +118,14 @@ Just add `data-bs-toggle="collapse"` and a `data-bs-target` to the element to au
 
 To add accordion-like group management to a collapsible area, add the data attribute `data-bs-parent="#selector"`. Refer to the [accordion page]([[docsref:/components/accordion]]) for more information.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="collapse"` | Initializes the collapse plugin on the trigger element. |
+| `data-bs-target` | CSS selector for the element(s) to expand and collapse. |
+| `data-bs-parent` | When set on the collapsible element, closes sibling collapses under the same parent (accordion behavior). |
+</BsTable>
+
 ### Via JavaScript
 
 Enable manually with:
index 9fe9133ac5204048089186ad1146ba4d6ec3f049..6f8f11dff9563f206bb868c747e6f34a48402041 100644 (file)
@@ -459,6 +459,14 @@ Dialog sizes are defined in the `$dialog-sizes` Sass map. Each size specifies th
 
 Toggle a dialog without writing JavaScript. Set `data-bs-toggle="dialog"` on a controller element, like a button, along with a `data-bs-target="#foo"` to target a specific dialog to toggle.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="dialog"` | Opens or toggles the dialog from the trigger element. |
+| `data-bs-target` | CSS selector for the dialog element to show or hide. |
+| `data-bs-dismiss="dialog"` | On a control inside the dialog, closes the dialog when activated. |
+</BsTable>
+
 ```html
 <button type="button" data-bs-toggle="dialog" data-bs-target="#myDialog">
   Launch dialog
index f5b41bedd3ec6a9da3e8c1279df67537c15d76eb..a0d5bdda442ce8a79a051cd81b147a65dd24252b 100644 (file)
@@ -259,168 +259,4 @@ You can use `.stretched-link` on `<label>`s to make the whole list group item cl
 
 ## JavaScript behavior
 
-Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our list group to create tabbable panes of local content.
-
-<div class="bd-example" role="tabpanel">
-  <div class="row">
-    <div class="col-4">
-      <div class="list-group" id="list-tab" role="tablist">
-        <a class="list-group-item list-group-item-action active" id="list-home-list" data-bs-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-bs-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-bs-toggle="tab" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
-        <a class="list-group-item list-group-item-action" id="list-settings-list" data-bs-toggle="tab" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
-      </div>
-    </div>
-    <div class="col-8">
-      <div class="tab-content" id="nav-tabContent">
-        <div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">
-          <p>Some placeholder content in a paragraph relating to "Home". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
-        </div>
-        <div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
-          <p>Some placeholder content in a paragraph relating to "Profile". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
-        </div>
-        <div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
-          <p>Some placeholder content in a paragraph relating to "Messages". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
-        </div>
-        <div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
-          <p>Some placeholder content in a paragraph relating to "Settings". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
-
-```html
-<div class="row">
-  <div class="col-4">
-    <div class="list-group" id="list-tab" role="tablist">
-      <a class="list-group-item list-group-item-action active" id="list-home-list" data-bs-toggle="list" 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-bs-toggle="list" 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-bs-toggle="list" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
-      <a class="list-group-item list-group-item-action" id="list-settings-list" data-bs-toggle="list" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
-    </div>
-  </div>
-  <div class="col-8">
-    <div class="tab-content" id="nav-tabContent">
-      <div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">...</div>
-      <div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">...</div>
-      <div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">...</div>
-      <div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">...</div>
-    </div>
-  </div>
-</div>
-```
-
-### Using data attributes
-
-You can activate a list group navigation without writing any JavaScript by simply specifying `data-bs-toggle="list"` or on an element. Use these data attributes on `.list-group-item`.
-
-```html
-<div role="tabpanel">
-  <!-- List group -->
-  <div class="list-group" id="myList" role="tablist">
-    <a class="list-group-item list-group-item-action active" data-bs-toggle="list" href="#home" role="tab">Home</a>
-    <a class="list-group-item list-group-item-action" data-bs-toggle="list" href="#profile" role="tab">Profile</a>
-    <a class="list-group-item list-group-item-action" data-bs-toggle="list" href="#messages" role="tab">Messages</a>
-    <a class="list-group-item list-group-item-action" data-bs-toggle="list" href="#settings" role="tab">Settings</a>
-  </div>
-
-  <!-- Tab panes -->
-  <div class="tab-content">
-    <div class="tab-pane active" id="home" role="tabpanel">...</div>
-    <div class="tab-pane" id="profile" role="tabpanel">...</div>
-    <div class="tab-pane" id="messages" role="tabpanel">...</div>
-    <div class="tab-pane" id="settings" role="tabpanel">...</div>
-  </div>
-</div>
-```
-
-### Via JavaScript
-
-Enable tabbable list item via JavaScript (each list item needs to be activated individually):
-
-```js
-const triggerTabList = document.querySelectorAll('#myTab a')
-triggerTabList.forEach(triggerEl => {
-  const tabTrigger = new bootstrap.Tab(triggerEl)
-
-  triggerEl.addEventListener('click', event => {
-    event.preventDefault()
-    tabTrigger.show()
-  })
-})
-```
-
-You can activate individual list item in several ways:
-
-```js
-const triggerEl = document.querySelector('#myTab a[href="#profile"]')
-bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
-
-const triggerFirstTabEl = document.querySelector('#myTab li:first-child a')
-bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab
-```
-
-### Fade effect
-
-To make tabs panel fade in, add `.fade` to each `.tab-pane`. The first tab pane must also have `.show` to make the initial content visible.
-
-```html
-<div class="tab-content">
-  <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="messages" role="tabpanel">...</div>
-  <div class="tab-pane fade" id="settings" role="tabpanel">...</div>
-</div>
-```
-
-### Methods
-
-<Callout name="danger-async-methods" type="danger" />
-
-Activates your content as a tab element.
-
-You can create a tab instance with the constructor, for example:
-
-```js
-const bsTab = new bootstrap.Tab('#myTab')
-```
-
-<BsTable>
-| Method | Description |
-| --- | --- |
-| `dispose` | Destroys an element’s tab. |
-| `getInstance` | Static method which allows you to get the tab instance associated with a DOM element, you can use it like this: `bootstrap.Tab.getInstance(element)`. |
-| `getOrCreateInstance` | Static method which returns a tab instance associated to a DOM element or create a new one in case it wasn’t initialized. You can use it like this: `bootstrap.Tab.getOrCreateInstance(element)`. |
-| `show` | Selects the given tab and shows its associated pane. Any other tab that was previously selected becomes unselected and its associated pane is hidden. **Returns to the caller before the tab pane has actually been shown** (i.e. before the `shown.bs.tab` event occurs). |
-</BsTable>
-
-### Events
-
-When showing a new tab, the events fire in the following order:
-
-1. `hide.bs.tab` (on the current active tab)
-2. `show.bs.tab` (on the to-be-shown tab)
-3. `hidden.bs.tab` (on the previous active tab, the same one as for the `hide.bs.tab` event)
-4. `shown.bs.tab` (on the newly-active just-shown tab, the same one as for the `show.bs.tab` event)
-
-If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
-
-<BsTable>
-| Event type | Description |
-| --- | --- |
-| `hide.bs.tab` | This event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use `event.target` and `event.relatedTarget` to target the current active tab and the new soon-to-be-active tab, respectively. |
-| `hidden.bs.tab` | This event fires after a new tab is shown (and thus the previous active tab is hidden). Use `event.target` and `event.relatedTarget` to target the previous active tab and the new active tab, respectively. |
-| `show.bs.tab` | This event fires on tab show, but before the new tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
-| `shown.bs.tab` | This event fires on tab show after a tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
-</BsTable>
-
-```js
-const tabElms = document.querySelectorAll('a[data-bs-toggle="list"]')
-tabElms.forEach(tabElm => {
-  tabElm.addEventListener('shown.bs.tab', event => {
-    event.target // newly activated tab
-    event.relatedTarget // previous active tab
-  })
-})
-```
+Use the [Tab plugin]([[docsref:/components/tab#list-groups]]) to create tabbable list group panes.
index 5045a91275735d497579ad01dc0458358e01de89..f0e381133ff25327fefb3b3b2b875bc75f1319ed 100644 (file)
@@ -576,6 +576,12 @@ On touch-enabled devices, opening a menu adds empty `mouseover` handlers to the
 
 Add `data-bs-toggle="menu"` to a link or button to toggle a menu.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="menu"` | Initializes the menu on the trigger and wires global close behavior. |
+</BsTable>
+
 ```html
 <button type="button" data-bs-toggle="menu" aria-expanded="false">
   Menu trigger
index f3417dc10484bf4efdc59cbb46db4712de1d7eb5..b8e09a22bf4cb5fc9cd2f97c9fb322ae8d3928c5 100644 (file)
@@ -222,6 +222,12 @@ new bootstrap.NavOverflow(nav, {
 
 Add `data-bs-toggle="nav-overflow"` to any `.nav` element to automatically enable the overflow behavior.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="nav-overflow"` | Enables responsive overflow handling on the `.nav` element. |
+</BsTable>
+
 ```html
 <ul class="nav nav-pills" data-bs-toggle="nav-overflow">
   <li class="nav-item"><a class="nav-link" href="#">Link 1</a></li>
diff --git a/site/src/content/docs/components/nav.mdx b/site/src/content/docs/components/nav.mdx
new file mode 100644 (file)
index 0000000..add7cef
--- /dev/null
@@ -0,0 +1,335 @@
+---
+title: Nav
+description: Add lists of links to your pages with various navigation components—tabs, pills, underline—and plenty of options to customize.
+aliases:
+  - "/docs/[[config:docs_version]]/components/navs/"
+  - "/docs/[[config:docs_version]]/components/navs-tabs/"
+toc: true
+---
+
+## Base nav
+
+Navigation available in Bootstrap share general markup and styles, from the base `.nav` class to the active and disabled states. Swap modifier classes to switch between each style.
+
+The base `.nav` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling.
+
+<Callout>
+To convey the active state to assistive technologies, use the `aria-current` attribute — using the `page` value for current page, or `true` for the current item in a set.
+</Callout>
+
+<Example code={`<ul class="nav">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+Classes are used throughout, so your markup can be super flexible. Use `<ul>`s like above, `<ol>` if the order of your items is important, or roll your own with a `<nav>` element. Because the `.nav` uses `display: flex`, the nav links behave the same as nav items would, but without the extra markup.
+
+<Example code={`<nav class="nav">
+    <a class="nav-link active" aria-current="page" href="#">Active</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+Where appropriate, you can also use `<button>` elements instead of `<a>` elements for the nav links. You can even mix and match—for example, by using buttons for menus.
+
+<Example code={`<nav class="nav">
+    <a class="nav-link active" aria-current="page" href="#">Active</a>
+    <a class="nav-link" href="#">Link</a>
+    <button class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</button>
+    <div class="menu">
+      <a class="menu-item" href="#">Action</a>
+      <a class="menu-item" href="#">Another action</a>
+      <hr class="menu-divider">
+      <a class="menu-item" href="#">Something else here</a>
+    </div>
+    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+## Tab JavaScript plugin
+
+Use the [tab JavaScript plugin]([[docsref:/components/tab#javascript-behavior]]) to create tabbable regions.
+
+## Available styles
+
+Change the style of `.nav`s component with modifiers and utilities. Mix and match as needed, or build your own.
+
+### Tabs
+
+Takes the basic nav from above and adds the `.nav-tabs` class to generate a tabbed interface.
+
+<Example code={`<ul class="nav nav-tabs">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+### Pills
+
+Take that same HTML, but use `.nav-pills` instead for a more themed appearance.
+
+<Example code={`<ul class="nav nav-pills">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+### Underline
+
+Take that same HTML, but use `.nav-underline` instead:
+
+<Example code={`<ul class="nav nav-underline">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+## Alignment
+
+Change the alignment of your nav with [flexbox utilities]([[docsref:/utilities/flex]]). By default, navs are horizontal and left-aligned, but you can easily modify them to center or right-aligned, and even stacked vertically.
+
+### Horizontal
+
+Centered with `.justify-content-center`:
+
+<Example code={`<ul class="nav justify-content-center">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+Right-aligned with `.justify-content-end`:
+
+<Example code={`<ul class="nav justify-content-end">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+### Vertical
+
+Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).
+
+<Example code={`<ul class="nav flex-column">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+As always, vertical navigation is possible without `<ul>`s, too.
+
+<Example code={`<nav class="nav flex-column">
+    <a class="nav-link active" aria-current="page" href="#">Active</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+### Fill and justify
+
+Force your `.nav`’s contents to extend the full available width with one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `.nav-fill`. Notice that all horizontal space is occupied, but not every nav item has the same width.
+
+<Example code={`<ul class="nav nav-pills nav-fill">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Much longer nav link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+When using a `<nav>`-based navigation, you can safely omit `.nav-item` as only `.nav-link` is required for styling `<a>` elements.
+
+<Example code={`<nav class="nav nav-pills nav-fill">
+    <a class="nav-link active" aria-current="page" href="#">Active</a>
+    <a class="nav-link" href="#">Much longer nav link</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+For equal-width elements, use `.nav-justified`. All horizontal space will be occupied by nav links, but unlike the `.nav-fill` above, every nav item will be the same width.
+
+<Example code={`<ul class="nav nav-pills nav-justified">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Much longer nav link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+Similar to the `.nav-fill` example using a `<nav>`-based navigation.
+
+<Example code={`<nav class="nav nav-pills nav-justified">
+    <a class="nav-link active" aria-current="page" href="#">Active</a>
+    <a class="nav-link" href="#">Much longer nav link</a>
+    <a class="nav-link" href="#">Link</a>
+    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+## Working with flex utilities
+
+If you need responsive nav variations, consider using a series of [flexbox utilities]([[docsref:/utilities/flex]]). While more verbose, these utilities offer greater customization across responsive breakpoints. In the example below, our nav will be stacked on the lowest breakpoint, then adapt to a horizontal layout that fills the available width starting from the small breakpoint.
+
+<Example code={`<nav class="nav nav-pills flex-column flex-sm-row">
+    <a class="flex-sm-fill text-sm-center nav-link active" aria-current="page" href="#">Active</a>
+    <a class="flex-sm-fill text-sm-center nav-link" href="#">Longer nav link</a>
+    <a class="flex-sm-fill text-sm-center nav-link" href="#">Link</a>
+    <a class="flex-sm-fill text-sm-center nav-link disabled" aria-disabled="true">Disabled</a>
+  </nav>`} />
+
+## Regarding accessibility
+
+If you’re using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the `<ul>`, or wrap a `<nav>` element around the whole navigation. Do not add the role to the `<ul>` itself, as this would prevent it from being announced as an actual list by assistive technologies.
+
+Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/). See the [Tab plugin]([[docsref:/components/tab]]) for dynamic tabbed interfaces. The `aria-current` attribute is not necessary on dynamic tabbed interfaces since our JavaScript handles the selected state by adding `aria-selected="true"` on the active tab.
+
+## Using menus
+
+Add menus with a little extra HTML and the [menus JavaScript plugin]([[docsref:/components/menus#usage]]).
+
+### Tabs with menus
+
+<Example code={`<ul class="nav nav-tabs">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</a>
+      <div class="menu">
+        <a class="menu-item" href="#">Action</a>
+        <a class="menu-item" href="#">Another action</a>
+        <a class="menu-item" href="#">Something else here</a>
+        <hr class="menu-divider">
+        <a class="menu-item" href="#">Separated link</a>
+      </div>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+### Pills with menus
+
+<Example code={`<ul class="nav nav-pills">
+    <li class="nav-item">
+      <a class="nav-link active" aria-current="page" href="#">Active</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</a>
+      <div class="menu">
+        <a class="menu-item" href="#">Action</a>
+        <a class="menu-item" href="#">Another action</a>
+        <a class="menu-item" href="#">Something else here</a>
+        <hr class="menu-divider">
+        <a class="menu-item" href="#">Separated link</a>
+      </div>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link" href="#">Link</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
+    </li>
+  </ul>`} />
+
+## CSS
+
+### Variables
+
+<CSSVariables component="Navs" className="nav" />
+
+On the `.nav` base class:
+
+<ScssDocs name="nav-tokens" file="scss/_nav.scss" />
+
+On the `.nav-tabs` modifier class:
+
+<ScssDocs name="nav-tabs-tokens" file="scss/_nav.scss" />
+
+On the `.nav-pills` modifier class:
+
+<ScssDocs name="nav-pills-tokens" file="scss/_nav.scss" />
+
+On the `.nav-underline` modifier class:
+
+<ScssDocs name="nav-underline-tokens" file="scss/_nav.scss" />
diff --git a/site/src/content/docs/components/navs-tabs.mdx b/site/src/content/docs/components/navs-tabs.mdx
deleted file mode 100644 (file)
index f613d3e..0000000
+++ /dev/null
@@ -1,669 +0,0 @@
----
-title: Navs and tabs
-description: Add lists of links to your pages with Bootstrap’s nav components and JavaScript-powered tabs.
-aliases: "/docs/[[config:docs_version]]/components/navs/"
-toc: true
----
-
-## Base nav
-
-Navigation available in Bootstrap share general markup and styles, from the base `.nav` class to the active and disabled states. Swap modifier classes to switch between each style.
-
-The base `.nav` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling.
-
-<Callout>
-To convey the active state to assistive technologies, use the `aria-current` attribute — using the `page` value for current page, or `true` for the current item in a set.
-</Callout>
-
-<Example code={`<ul class="nav">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-Classes are used throughout, so your markup can be super flexible. Use `<ul>`s like above, `<ol>` if the order of your items is important, or roll your own with a `<nav>` element. Because the `.nav` uses `display: flex`, the nav links behave the same as nav items would, but without the extra markup.
-
-<Example code={`<nav class="nav">
-    <a class="nav-link active" aria-current="page" href="#">Active</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-Where appropriate, you can also use `<button>` elements instead of `<a>` elements for the nav links. You can even mix and match—for example, by using buttons for menus.
-
-<Example code={`<nav class="nav">
-    <a class="nav-link active" aria-current="page" href="#">Active</a>
-    <a class="nav-link" href="#">Link</a>
-    <button class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</button>
-    <div class="menu">
-      <a class="menu-item" href="#">Action</a>
-      <a class="menu-item" href="#">Another action</a>
-      <hr class="menu-divider">
-      <a class="menu-item" href="#">Something else here</a>
-    </div>
-    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-## Available styles
-
-Change the style of `.nav`s component with modifiers and utilities. Mix and match as needed, or build your own.
-
-### Tabs
-
-Takes the basic nav from above and adds the `.nav-tabs` class to generate a tabbed interface. Use them to create tabbable regions with our [tab JavaScript plugin](#javascript-behavior).
-
-<Example code={`<ul class="nav nav-tabs">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-### Pills
-
-Take that same HTML, but use `.nav-pills` instead for a more themed appearance.
-
-<Example code={`<ul class="nav nav-pills">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-### Underline
-
-Take that same HTML, but use `.nav-underline` instead:
-
-<Example code={`<ul class="nav nav-underline">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-## Alignment
-
-Change the alignment of your nav with [flexbox utilities]([[docsref:/utilities/flex]]). By default, navs are horizontal and left-aligned, but you can easily modify them to center or right-aligned, and even stacked vertically.
-
-### Horizontal
-
-Centered with `.justify-content-center`:
-
-<Example code={`<ul class="nav justify-content-center">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-Right-aligned with `.justify-content-end`:
-
-<Example code={`<ul class="nav justify-content-end">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-### Vertical
-
-Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).
-
-<Example code={`<ul class="nav flex-column">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-As always, vertical navigation is possible without `<ul>`s, too.
-
-<Example code={`<nav class="nav flex-column">
-    <a class="nav-link active" aria-current="page" href="#">Active</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-### Fill and justify
-
-Force your `.nav`’s contents to extend the full available width with one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `.nav-fill`. Notice that all horizontal space is occupied, but not every nav item has the same width.
-
-<Example code={`<ul class="nav nav-pills nav-fill">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Much longer nav link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-When using a `<nav>`-based navigation, you can safely omit `.nav-item` as only `.nav-link` is required for styling `<a>` elements.
-
-<Example code={`<nav class="nav nav-pills nav-fill">
-    <a class="nav-link active" aria-current="page" href="#">Active</a>
-    <a class="nav-link" href="#">Much longer nav link</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-For equal-width elements, use `.nav-justified`. All horizontal space will be occupied by nav links, but unlike the `.nav-fill` above, every nav item will be the same width.
-
-<Example code={`<ul class="nav nav-pills nav-justified">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Much longer nav link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-Similar to the `.nav-fill` example using a `<nav>`-based navigation.
-
-<Example code={`<nav class="nav nav-pills nav-justified">
-    <a class="nav-link active" aria-current="page" href="#">Active</a>
-    <a class="nav-link" href="#">Much longer nav link</a>
-    <a class="nav-link" href="#">Link</a>
-    <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-## Working with flex utilities
-
-If you need responsive nav variations, consider using a series of [flexbox utilities]([[docsref:/utilities/flex]]). While more verbose, these utilities offer greater customization across responsive breakpoints. In the example below, our nav will be stacked on the lowest breakpoint, then adapt to a horizontal layout that fills the available width starting from the small breakpoint.
-
-<Example code={`<nav class="nav nav-pills flex-column flex-sm-row">
-    <a class="flex-sm-fill text-sm-center nav-link active" aria-current="page" href="#">Active</a>
-    <a class="flex-sm-fill text-sm-center nav-link" href="#">Longer nav link</a>
-    <a class="flex-sm-fill text-sm-center nav-link" href="#">Link</a>
-    <a class="flex-sm-fill text-sm-center nav-link disabled" aria-disabled="true">Disabled</a>
-  </nav>`} />
-
-## Regarding accessibility
-
-If you’re using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the `<ul>`, or wrap a `<nav>` element around the whole navigation. Do not add the role to the `<ul>` itself, as this would prevent it from being announced as an actual list by assistive technologies.
-
-Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example. The `aria-current` attribute is not necessary on dynamic tabbed interfaces since our JavaScript handles the selected state by adding `aria-selected="true"` on the active tab.
-
-## Using menus
-
-Add menus with a little extra HTML and the [menus JavaScript plugin]([[docsref:/components/menus#usage]]).
-
-### Tabs with menus
-
-<Example code={`<ul class="nav nav-tabs">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</a>
-      <div class="menu">
-        <a class="menu-item" href="#">Action</a>
-        <a class="menu-item" href="#">Another action</a>
-        <a class="menu-item" href="#">Something else here</a>
-        <hr class="menu-divider">
-        <a class="menu-item" href="#">Separated link</a>
-      </div>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-### Pills with menus
-
-<Example code={`<ul class="nav nav-pills">
-    <li class="nav-item">
-      <a class="nav-link active" aria-current="page" href="#">Active</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" data-bs-toggle="menu" href="#" role="button" aria-expanded="false">Menu</a>
-      <div class="menu">
-        <a class="menu-item" href="#">Action</a>
-        <a class="menu-item" href="#">Another action</a>
-        <a class="menu-item" href="#">Something else here</a>
-        <hr class="menu-divider">
-        <a class="menu-item" href="#">Separated link</a>
-      </div>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link" href="#">Link</a>
-    </li>
-    <li class="nav-item">
-      <a class="nav-link disabled" aria-disabled="true">Disabled</a>
-    </li>
-  </ul>`} />
-
-## CSS
-
-### Variables
-
-<CSSVariables component="Navs" className="nav" />
-
-On the `.nav` base class:
-
-<ScssDocs name="nav-tokens" file="scss/_nav.scss" />
-
-On the `.nav-tabs` modifier class:
-
-<ScssDocs name="nav-tabs-tokens" file="scss/_nav.scss" />
-
-On the `.nav-pills` modifier class:
-
-<ScssDocs name="nav-pills-tokens" file="scss/_nav.scss" />
-
-On the `.nav-underline` modifier class:
-
-<ScssDocs name="nav-underline-tokens" file="scss/_nav.scss" />
-
-## JavaScript behavior
-
-Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our navigational tabs and pills to create tabbable panes of local content.
-
-<Example showMarkup={false} code={`
-<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-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-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-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-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-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-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>
-`} />
-
-```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-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-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-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-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>
-```
-
-To help fit your needs, this works with `<ul>`-based markup, as shown above, or with any arbitrary “roll your own” markup. Note that if you’re using `<nav>`, you shouldn’t add `role="tablist"` directly to it, as this would override the element’s native role as a navigation landmark. Instead, switch to an alternative element (in the example below, a simple `<div>`) and wrap the `<nav>` around it.
-
-<Example showMarkup={false} code={`
-<nav>
-  <div class="nav nav-tabs mb-3" id="nav-tab" role="tablist">
-    <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">
-    <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="nav-profile" role="tabpanel" aria-labelledby="nav-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="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>
-`} />
-
-```html
-<nav>
-  <div class="nav nav-tabs" id="nav-tab" role="tablist">
-    <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>
-```
-
-The tabs plugin also works with pills.
-
-<Example showMarkup={false} code={`
-<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
-  <li class="nav-item" role="presentation">
-    <button class="nav-link active" id="pills-home-tab" data-bs-toggle="pill" data-bs-target="#pills-home" type="button" role="tab" aria-controls="pills-home" aria-selected="true">Home</button>
-  </li>
-  <li class="nav-item" role="presentation">
-    <button class="nav-link" id="pills-profile-tab" data-bs-toggle="pill" data-bs-target="#pills-profile" type="button" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</button>
-  </li>
-  <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">
-    <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="pills-profile" role="tabpanel" aria-labelledby="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>
-  </div>
-  <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>
-`} />
-
-```html
-<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
-  <li class="nav-item" role="presentation">
-    <button class="nav-link active" id="pills-home-tab" data-bs-toggle="pill" data-bs-target="#pills-home" type="button" role="tab" aria-controls="pills-home" aria-selected="true">Home</button>
-  </li>
-  <li class="nav-item" role="presentation">
-    <button class="nav-link" id="pills-profile-tab" data-bs-toggle="pill" data-bs-target="#pills-profile" type="button" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</button>
-  </li>
-  <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>
-```
-
-And with vertical pills. Ideally, for vertical tabs, you should also add `aria-orientation="vertical"` to the tab list container.
-
-<Example showMarkup={false} code={`
-<div class="d-flex align-items-start">
-  <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>
-    </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>
-    </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>
-    </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>
-    </div>
-  </div>
-</div>
-`} />
-
-```html
-<div class="d-flex align-items-start">
-  <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>
-</div>
-```
-
-### Accessibility
-
-Dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/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). As a best practice, we recommend using `<button>` elements for the tabs, as these are controls that trigger a dynamic change, rather than links that navigate to a new page or location.
-
-In line with the ARIA Authoring Practices pattern, only the currently active tab receives keyboard focus. When the JavaScript plugin is initialized, it will set `tabindex="-1"` on all inactive tab controls. Once the currently active tab has focus, the cursor keys activate the previous/next tab. The <kbd>Home</kbd> and <kbd>End</kbd> keys activate the first and last tabs, respectively. The plugin will change the [roving `tabindex`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/) accordingly. However, note that the JavaScript plugin does not distinguish between horizontal and vertical tab lists when it comes to cursor key interactions: regardless of the tab list’s orientation, both the up *and* left cursor go to the previous tab, and down *and* right cursor go to the next tab.
-
-<Callout type="warning">
-In general, to facilitate keyboard navigation, it’s recommended to make the tab panels themselves focusable as well, unless the first element containing meaningful content inside the tab panel is already focusable. The JavaScript plugin does not try to handle this aspect—where appropriate, you’ll need to explicitly make your tab panels focusable by adding `tabindex="0"` in your markup.
-</Callout>
-
-<Callout type="danger">
-The tab JavaScript plugin **does not** support tabbed interfaces that contain menus, as these cause 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 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>
-
-### Using data attributes
-
-You can activate a tab or pill navigation without writing any JavaScript by simply specifying `data-bs-toggle="tab"` or `data-bs-toggle="pill"` on an element. Use these data attributes on `.nav-tabs` or `.nav-pills`.
-
-```html
-<!-- Nav tabs -->
-<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>
-  </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>
-  </li>
-  <li class="nav-item" role="presentation">
-    <button class="nav-link" id="messages-tab" data-bs-toggle="tab" data-bs-target="#messages" type="button" role="tab" aria-controls="messages" aria-selected="false">Messages</button>
-  </li>
-  <li class="nav-item" role="presentation">
-    <button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="false">Settings</button>
-  </li>
-</ul>
-
-<!-- Tab panes -->
-<div class="tab-content">
-  <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
-  <div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
-  <div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
-  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
-</div>
-```
-
-### Via JavaScript
-
-Enable tabbable tabs via JavaScript (each tab needs to be activated individually):
-
-```js
-const triggerTabList = document.querySelectorAll('#myTab button')
-triggerTabList.forEach(triggerEl => {
-  const tabTrigger = new bootstrap.Tab(triggerEl)
-
-  triggerEl.addEventListener('click', event => {
-    event.preventDefault()
-    tabTrigger.show()
-  })
-})
-```
-
-You can activate individual tabs in several ways:
-
-```js
-const triggerEl = document.querySelector('#myTab button[data-bs-target="#profile"]')
-bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
-
-const triggerFirstTabEl = document.querySelector('#myTab li:first-child button')
-bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab
-```
-
-### Fade effect
-
-To make tabs fade in, add `.fade` to each `.tab-pane`. The first tab pane must also have `.show` to make the initial content visible.
-
-```html
-<div class="tab-content">
-  <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="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
-  <div class="tab-pane fade" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
-</div>
-```
-
-### Methods
-
-<Callout name="danger-async-methods" type="danger" />
-
-Activates your content as a tab element.
-
-You can create a tab instance with the constructor, for example:
-
-```js
-const bsTab = new bootstrap.Tab('#myTab')
-```
-
-<BsTable>
-| Method | Description |
-| --- | --- |
-| `dispose` | Destroys an element’s tab. |
-| `getInstance` | Static method which allows you to get the tab instance associated with a DOM element, you can use it like this: `bootstrap.Tab.getInstance(element)`. |
-| `getOrCreateInstance` | Static method which returns a tab instance associated to a DOM element or create a new one in case it wasn’t initialized. You can use it like this: `bootstrap.Tab.getOrCreateInstance(element)`. |
-| `show` | Selects the given tab and shows its associated pane. Any other tab that was previously selected becomes unselected and its associated pane is hidden. **Returns to the caller before the tab pane has actually been shown** (i.e. before the `shown.bs.tab` event occurs). |
-</BsTable>
-
-### Events
-
-When showing a new tab, the events fire in the following order:
-
-1. `hide.bs.tab` (on the current active tab)
-2. `show.bs.tab` (on the to-be-shown tab)
-3. `hidden.bs.tab` (on the previous active tab, the same one as for the `hide.bs.tab` event)
-4. `shown.bs.tab` (on the newly-active just-shown tab, the same one as for the `show.bs.tab` event)
-
-If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
-
-<BsTable>
-| Event type | Description |
-| --- | --- |
-| `hide.bs.tab` | This event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use `event.target` and `event.relatedTarget` to target the current active tab and the new soon-to-be-active tab, respectively. |
-| `hidden.bs.tab` | This event fires after a new tab is shown (and thus the previous active tab is hidden). Use `event.target` and `event.relatedTarget` to target the previous active tab and the new active tab, respectively. |
-| `show.bs.tab` | This event fires on tab show, but before the new tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
-| `shown.bs.tab` | This event fires on tab show after a tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
-</BsTable>
-
-```js
-const tabEl = document.querySelector('button[data-bs-toggle="tab"]')
-tabEl.addEventListener('shown.bs.tab', event => {
-  event.target // newly activated tab
-  event.relatedTarget // previous active tab
-})
-```
index 2625dc0704ce416023dde99ea9ad0977a87959cb..7a5d4f61826b85a2df6637028f98a81f73fd859d 100644 (file)
@@ -290,6 +290,14 @@ Add a dismiss button with the `data-bs-dismiss="offcanvas"` attribute, which tri
 
 ### Via data attributes
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="offcanvas"` | Initializes offcanvas behavior on the trigger element. |
+| `data-bs-target` | CSS selector for the `.offcanvas` element to open (or use `href` on a link). |
+| `data-bs-dismiss="offcanvas"` | On a dismiss control, closes the offcanvas when activated. |
+</BsTable>
+
 #### Toggle
 
 Add `data-bs-toggle="offcanvas"` and a `data-bs-target` or `href` to the element to automatically assign control of one offcanvas element. The `data-bs-target` attribute accepts a CSS selector to apply the offcanvas to. Be sure to add the class `offcanvas` to the offcanvas element. If you’d like it to default open, add the additional class `show`.
index 38dafd9720aba920f81abb2bf36b3700db0db42c..7e2333a75f322855631a8c276d05c24103c3b039 100644 (file)
@@ -198,6 +198,20 @@ Avoid adding an excessive amount of content in popovers with the `html` option.
 Popovers do not manage keyboard focus order, and their placement can be random in the DOM, so be careful when adding interactive elements (like forms or links), as it may lead to an illogical focus order or make the popover content itself completely unreachable for keyboard users. In cases where you must use these elements, consider using a dialog instead.
 </Callout>
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="popover"` | Initializes the popover on the trigger element. |
+| `data-bs-title` | Title content shown in the popover header. |
+| `data-bs-content` | Body content of the popover. |
+| `data-bs-placement` | Where to place the popover relative to the trigger. |
+| `data-bs-trigger` | How the popover opens (`click`, `hover`, `focus`, `manual`, or a combination). |
+| `data-bs-custom-class` | Extra class names added to the popover for theming. |
+| `data-bs-html` | When `true`, allows HTML in the title and content (use with care for untrusted input). |
+</BsTable>
+
 ### Dependencies
 
 The popover plugin extends the tooltip plugin, so it requires all tooltip dependencies plus its own:
index 7f14327c0f0c582239c81565c8c735a8e786a12f..88f340d529de2f74f5fc5991aa4a850f16c9a359 100644 (file)
@@ -6,7 +6,7 @@ toc: true
 
 ## How it works
 
-Scrollspy toggles the `.active` class on anchor (`<a>`) elements when the element with the `id` referenced by the anchor’s `href` is scrolled into view. Scrollspy is best used in conjunction with a Bootstrap [nav component]([[docsref:/components/navs-tabs]]) or [list group]([[docsref:/components/list-group]]), but it will also work with any anchor elements in the current page. Here’s how it works.
+Scrollspy toggles the `.active` class on anchor (`<a>`) elements when the element with the `id` referenced by the anchor’s `href` is scrolled into view. Scrollspy is best used in conjunction with a Bootstrap [nav component]([[docsref:/components/nav]]) or [list group]([[docsref:/components/list-group]]), but it will also work with any anchor elements in the current page. Here’s how it works.
 
 - To start, scrollspy requires two things: a navigation, list group, or a simple set of links, plus a scrollable container. The scrollable container can be the `<body>` or a custom element with a set `height` and `overflow-y: scroll`.
 
@@ -344,6 +344,13 @@ document.querySelectorAll('#nav-tab>[data-bs-toggle="tab"]').forEach(el => {
 
 To easily add scrollspy behavior to your topbar navigation, add `data-bs-spy="scroll"` to the element you want to spy on (most typically this would be the `<body>`). Then add the `data-bs-target` attribute with the `id` or class name of the parent element of any Bootstrap `.nav` component.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-spy="scroll"` | Enables ScrollSpy on the scrollable element (often `<body>`). |
+| `data-bs-target` | CSS selector for the nav whose links match sections in the spied element. |
+</BsTable>
+
 ```html
 <body data-bs-spy="scroll" data-bs-target="#navbar-example">
   ...
diff --git a/site/src/content/docs/components/tab.mdx b/site/src/content/docs/components/tab.mdx
new file mode 100644 (file)
index 0000000..5c9c83d
--- /dev/null
@@ -0,0 +1,301 @@
+---
+title: Tab
+description: Create toggleable content panes using any of our navigation or list group components with this JavaScript plugin.
+toc: true
+---
+
+The Tab plugin works with [nav components]([[docsref:/components/nav]]) such as `.nav-tabs` and `.nav-pills`, and with [list groups]([[docsref:/components/list-group#javascript-behavior]]).
+
+## Nav tab
+
+Add the required data attributes and `id` to your navigation to make it tabbable. Then, add the `tab-content` container with matching `id`s to each tab pane.
+
+<Example class="vstack gap-3" code={`<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-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-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-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-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
+      <p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
+    </div>
+    <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.</p>
+    </div>
+    <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.</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>`} />
+
+## With buttons
+
+To help fit your needs, this works with `<ul>`-based markup, as shown above, or with any arbitrary “roll your own” markup. Note that if you’re using `<nav>`, you shouldn’t add `role="tablist"` directly to it, as this would override the element’s native role as a navigation landmark. Instead, switch to an alternative element (in the example below, a simple `<div>`) and wrap the `<nav>` around it.
+
+<Example class="vstack gap-3" code={`<nav>
+    <div class="nav nav-tabs" id="nav-tab2" role="tablist">
+      <button class="nav-link active" id="nav-home-tab2" data-bs-toggle="tab" data-bs-target="#nav-home2" type="button" role="tab" aria-controls="nav-home2" aria-selected="true">Home</button>
+      <button class="nav-link" id="nav-profile-tab2" data-bs-toggle="tab" data-bs-target="#nav-profile2" type="button" role="tab" aria-controls="nav-profile2" aria-selected="false">Profile</button>
+      <button class="nav-link" id="nav-contact-tab2" data-bs-toggle="tab" data-bs-target="#nav-contact2" type="button" role="tab" aria-controls="nav-contact2" aria-selected="false">Contact</button>
+      <button class="nav-link" id="nav-disabled-tab2" data-bs-toggle="tab" data-bs-target="#nav-disabled2" type="button" role="tab" aria-controls="nav-disabled2" aria-selected="false" disabled>Disabled</button>
+    </div>
+  </nav>
+  <div class="tab-content" id="nav-tabContent2">
+    <div class="tab-pane fade show active" id="nav-home2" role="tabpanel" aria-labelledby="nav-home-tab2" tabindex="0">
+      <p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
+    </div>
+    <div class="tab-pane fade" id="nav-profile2" role="tabpanel" aria-labelledby="nav-profile-tab2" tabindex="0">
+      <p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
+    </div>
+    <div class="tab-pane fade" id="nav-contact2" role="tabpanel" aria-labelledby="nav-contact-tab2" tabindex="0">
+      <p>This is some placeholder content the <strong>Contact tab’s</strong> associated content.</p>
+    </div>
+    <div class="tab-pane fade" id="nav-disabled2" role="tabpanel" aria-labelledby="nav-disabled-tab2" tabindex="0">
+      <p>This is some placeholder content the <strong>Disabled tab’s</strong> associated content.</p>
+    </div>
+  </div>`} />
+
+## Pills
+
+The tabs plugin also works with pills.
+
+<Example class="vstack gap-3" code={`<ul class="nav nav-pills" id="pills-tab" role="tablist">
+    <li class="nav-item" role="presentation">
+      <button class="nav-link active" id="pills-home-tab" data-bs-toggle="tab" data-bs-target="#pills-home" type="button" role="tab" aria-controls="pills-home" aria-selected="true">Home</button>
+    </li>
+    <li class="nav-item" role="presentation">
+      <button class="nav-link" id="pills-profile-tab" data-bs-toggle="tab" data-bs-target="#pills-profile" type="button" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</button>
+    </li>
+    <li class="nav-item" role="presentation">
+      <button class="nav-link" id="pills-contact-tab" data-bs-toggle="tab" 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="tab" 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">
+      <p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
+    </div>
+    <div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">
+      <p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
+    </div>
+    <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.</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>`} />
+
+And with vertical pills. Ideally, for vertical tabs, you should also add `aria-orientation="vertical"` to the tab list container.
+
+<Example class="vstack gap-3" code={`<div class="d-flex align-items-start">
+  <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="tab" 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="tab" 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="tab" 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="tab" 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="tab" 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.</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.</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.</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.</p>
+    </div>
+  </div>
+</div>`} />
+
+## List groups
+
+The tab plugin also works with [list groups]([[docsref:/components/list-group]]). Add `data-bs-toggle="tab"` to each `.list-group-item` and pair them with `.tab-pane` elements.
+
+<Example class="vstack gap-3" code={`<div class="row">
+  <div class="col-4">
+    <div class="list-group" id="list-tab" role="tablist">
+      <a class="list-group-item list-group-item-action active" id="list-home-list" data-bs-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-bs-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-bs-toggle="tab" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
+      <a class="list-group-item list-group-item-action" id="list-settings-list" data-bs-toggle="tab" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
+    </div>
+  </div>
+  <div class="col-8">
+    <div class="tab-content" id="list-tabContent">
+      <div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">
+        <p>Some placeholder content in a paragraph relating to "Home".</p>
+      </div>
+      <div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
+        <p>Some placeholder content in a paragraph relating to "Profile".</p>
+      </div>
+      <div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
+        <p>Some placeholder content in a paragraph relating to "Messages".</p>
+      </div>
+      <div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
+        <p>Some placeholder content in a paragraph relating to "Settings".</p>
+      </div>
+    </div>
+  </div>
+</div>`} />
+
+## Accessibility
+
+Dynamic tabbed interfaces, as described in the [ARIA Authoring Practices Guide tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/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). As a best practice, we recommend using `<button>` elements for the tabs, as these are controls that trigger a dynamic change, rather than links that navigate to a new page or location.
+
+In line with the ARIA Authoring Practices pattern, only the currently active tab receives keyboard focus. When the JavaScript plugin is initialized, it will set `tabindex="-1"` on all inactive tab controls. Once the currently active tab has focus, the cursor keys activate the previous/next tab. The <kbd>Home</kbd> and <kbd>End</kbd> keys activate the first and last tabs, respectively. The plugin will change the [roving `tabindex`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/) accordingly. However, note that the JavaScript plugin does not distinguish between horizontal and vertical tab lists when it comes to cursor key interactions: regardless of the tab list’s orientation, both the up *and* left cursor go to the previous tab, and down *and* right cursor go to the next tab.
+
+<Callout type="warning">
+In general, to facilitate keyboard navigation, it’s recommended to make the tab panels themselves focusable as well, unless the first element containing meaningful content inside the tab panel is already focusable. The JavaScript plugin does not try to handle this aspect—where appropriate, you’ll need to explicitly make your tab panels focusable by adding `tabindex="0"` in your markup.
+</Callout>
+
+<Callout type="danger">
+The tab JavaScript plugin **does not** support tabbed interfaces that contain menus, as these cause 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 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>
+
+## Usage
+
+### Via data attributes
+
+You can activate a tab navigation without writing any JavaScript by simply specifying `data-bs-toggle="tab"` on an element.
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="tab"` | Activates tab navigation on the trigger. |
+| `data-bs-target` | CSS selector for the tab pane to show (must pair with a corresponding `.tab-pane`). |
+</BsTable>
+
+```html
+<!-- Nav tabs -->
+<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>
+  </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>
+  </li>
+  <li class="nav-item" role="presentation">
+    <button class="nav-link" id="messages-tab" data-bs-toggle="tab" data-bs-target="#messages" type="button" role="tab" aria-controls="messages" aria-selected="false">Messages</button>
+  </li>
+  <li class="nav-item" role="presentation">
+    <button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="false">Settings</button>
+  </li>
+</ul>
+
+<!-- Tab panes -->
+<div class="tab-content">
+  <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
+  <div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
+  <div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
+  <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
+</div>
+```
+
+### Via JavaScript
+
+Enable tabbable tabs via JavaScript (each tab needs to be activated individually):
+
+```js
+const triggerTabList = document.querySelectorAll('#myTab button')
+triggerTabList.forEach(triggerEl => {
+  const tabTrigger = new bootstrap.Tab(triggerEl)
+
+  triggerEl.addEventListener('click', event => {
+    event.preventDefault()
+    tabTrigger.show()
+  })
+})
+```
+
+You can activate individual tabs in several ways:
+
+```js
+const triggerEl = document.querySelector('#myTab button[data-bs-target="#profile"]')
+bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
+
+const triggerFirstTabEl = document.querySelector('#myTab li:first-child button')
+bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab
+```
+
+### Fade effect
+
+To make tabs fade in, add `.fade` to each `.tab-pane`. The first tab pane must also have `.show` to make the initial content visible.
+
+```html
+<div class="tab-content">
+  <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="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
+  <div class="tab-pane fade" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
+</div>
+```
+
+### Methods
+
+<Callout name="danger-async-methods" type="danger" />
+
+Activates your content as a tab element.
+
+You can create a tab instance with the constructor, for example:
+
+```js
+const bsTab = new bootstrap.Tab('#myTab')
+```
+
+<BsTable>
+| Method | Description |
+| --- | --- |
+| `dispose` | Destroys an element’s tab. |
+| `getInstance` | Static method which allows you to get the tab instance associated with a DOM element, you can use it like this: `bootstrap.Tab.getInstance(element)`. |
+| `getOrCreateInstance` | Static method which returns a tab instance associated to a DOM element or create a new one in case it wasn’t initialized. You can use it like this: `bootstrap.Tab.getOrCreateInstance(element)`. |
+| `show` | Selects the given tab and shows its associated pane. Any other tab that was previously selected becomes unselected and its associated pane is hidden. **Returns to the caller before the tab pane has actually been shown** (i.e. before the `shown.bs.tab` event occurs). |
+</BsTable>
+
+### Events
+
+When showing a new tab, the events fire in the following order:
+
+1. `hide.bs.tab` (on the current active tab)
+2. `show.bs.tab` (on the to-be-shown tab)
+3. `hidden.bs.tab` (on the previous active tab, the same one as for the `hide.bs.tab` event)
+4. `shown.bs.tab` (on the newly-active just-shown tab, the same one as for the `show.bs.tab` event)
+
+If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events will not be fired.
+
+<BsTable>
+| Event type | Description |
+| --- | --- |
+| `hide.bs.tab` | This event fires when a new tab is to be shown (and thus the previous active tab is to be hidden). Use `event.target` and `event.relatedTarget` to target the current active tab and the new soon-to-be-active tab, respectively. |
+| `hidden.bs.tab` | This event fires after a new tab is shown (and thus the previous active tab is hidden). Use `event.target` and `event.relatedTarget` to target the previous active tab and the new active tab, respectively. |
+| `show.bs.tab` | This event fires on tab show, but before the new tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
+| `shown.bs.tab` | This event fires on tab show after a tab has been shown. Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. |
+</BsTable>
+
+```js
+const tabEl = document.querySelector('button[data-bs-toggle="tab"]')
+tabEl.addEventListener('shown.bs.tab', event => {
+  event.target // newly activated tab
+  event.relatedTarget // previous active tab
+})
+```
index f029103d3084c870deaaf840c419013ce7618e3b..e20f1e3c629f0fd3f489f43044fddf5f5d752f1c 100644 (file)
@@ -321,6 +321,17 @@ const toastElList = document.querySelectorAll('.toast')
 const toastList = [...toastElList].map(toastEl => new bootstrap.Toast(toastEl, option))
 ```
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-dismiss="toast"` | On a close control, dismisses the toast when activated. |
+| `data-bs-autohide` | Whether the toast hides automatically after the delay. |
+| `data-bs-delay` | Time in milliseconds before hiding (when autohide is enabled). |
+| `data-bs-animation` | Whether to use the fade transition when showing and hiding. |
+</BsTable>
+
 ### Triggers
 
 <JsDismiss name="toast" />
index 5a4341a9a40a5e81dc281b0ae8ed3fa16d75b242..ace15989ca560c0f22de138d1a3a12e06f350fc8 100644 (file)
@@ -82,6 +82,15 @@ You could also use this to toggle the `disabled` attribute on a `fieldset` eleme
 
 Add `data-bs-toggle="toggler"` to the element to automatically. The `data-bs-target` is optional, and attribute accepts a CSS selector to apply the toggler functionality to. Be sure to add the `data-bs-attribute` and `data-bs-value` attributes to the toggled element's markup.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="toggler"` | Initializes the toggler on the trigger element. |
+| `data-bs-target` | Optional CSS selector for the element whose attribute is toggled. |
+| `data-bs-attribute` | Name of the HTML attribute to toggle (e.g. `hidden`, `disabled`). |
+| `data-bs-value` | Value to set when the attribute is “on” (often paired with removal when “off”). |
+</BsTable>
+
 ### Via JavaScript
 
 We don't recommend using this component programmatically, as the initial purpose of it is to avoid using JavaScript. However, you can enable manually with:
index 83b833177619228038bfef442f750c413c35955f..cddb5a7c43c791b22f83012567560c077cce41e5 100644 (file)
@@ -166,6 +166,18 @@ const tooltip = new bootstrap.Tooltip('#example', {
 
 </Callout>
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="tooltip"` | Initializes the tooltip on the trigger element. |
+| `data-bs-title` | Text (or HTML when allowed) shown in the tooltip body. |
+| `data-bs-placement` | Where to place the tooltip (`top`, `right`, `bottom`, `left`, or responsive variants). |
+| `data-bs-custom-class` | Extra class names added to the tooltip for theming. |
+| `data-bs-html` | When `true`, allows HTML in the title (use with care; prefer plain text for user content). |
+</BsTable>
+
 ### Markup
 
 The required markup for a tooltip is only a `data` attribute and `title` on the HTML element you wish to have a tooltip. The generated markup of a tooltip is rather simple, though it does require a position (by default, set to `top` by the plugin).
index 0dab11a65585d1e0361438d091bb130fa85a2561..bf381ccf40a761f1ce64bd99553a31caf01489e0 100644 (file)
@@ -183,6 +183,16 @@ Disable the ghost input to prevent adding new chips. Existing chips become non-i
 
 Add `data-bs-chip-input` to your container element to automatically initialize the chip input behavior. Options can be passed as data attributes.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-chip-input` | Initializes the chip input on the container element. |
+| `data-bs-separator` | Character that creates a new chip when typed (or `null` to disable). |
+| `data-bs-allow-duplicates` | Whether duplicate chip values are allowed. |
+| `data-bs-max-chips` | Maximum number of chips (`null` for no limit). |
+| `data-bs-create-on-blur` | Create a chip from the input value when focus leaves the field. |
+</BsTable>
+
 ```html
 <div class="chip-input theme-primary" data-bs-chip-input data-bs-separator="," data-bs-allow-duplicates="false">
   <input type="text" class="form-ghost" placeholder="Add tags...">
index 435f6e8f06afc71ff9f86facb1df277c26044f5f..db8c5fe6c4a5d6845915bfa1f6e7fc372f647f64 100644 (file)
@@ -371,6 +371,19 @@ For multiple selection, the hidden input value is a comma-separated list of sele
 
 ## JavaScript
 
+### Via data attributes
+
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="combobox"` | Initializes the combobox on the toggle button. |
+| `data-bs-value` | On a `.menu-item`, the value submitted and shown when that option is selected. |
+| `data-bs-search` | Enables the search/filter field inside the menu. |
+| `data-bs-multiple` | Enables multi-select behavior. |
+| `data-bs-name` | `name` of the auto-created hidden input for form submission. |
+| `data-bs-placeholder` | Placeholder text shown in the toggle when nothing is selected. |
+</BsTable>
+
 ### Options
 
 Options can be passed via data attributes on the toggle button (e.g., `data-bs-search="true"`) or as a config object when initializing via JavaScript.
index d9002775b5977e798a03fa246e660fcebe01a297..f3e11b423e33f31c7d857a32b10d53d079d22eeb 100644 (file)
@@ -199,6 +199,13 @@ Use `data-bs-datepicker-theme` to set the datepicker popup's theme independently
 
 Add `data-bs-toggle="datepicker"` to any input element to initialize it as a datepicker.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-toggle="datepicker"` | Initializes the datepicker on the input (or button) element. |
+| `data-bs-inline` | When `true`, renders the calendar inline instead of a popup. |
+</BsTable>
+
 ```html
 <input type="text" class="form-control" data-bs-toggle="datepicker">
 ```
index d62afd9d96b8e7d15447c9111660518b43fea465..9eab44a8788f0fc7ce02f2b608c696ef21906108 100644 (file)
@@ -171,6 +171,13 @@ Use a form label and help text for better accessibility.
 
 Add `data-bs-otp` to your container element to automatically initialize the OTP input behavior.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-otp` | Initializes the OTP input on the container wrapping the digit fields. |
+| `data-bs-mask` | When `true`, uses password fields to mask entered digits. |
+</BsTable>
+
 ```html
 <div class="otp" data-bs-otp>
   <input type="text" class="form-control">
index b38bf99538440ac6a920a098ee7d69d385245161..454502b6625176825ae5b7c08924d3652eb64faf 100644 (file)
@@ -149,6 +149,14 @@ The default scoring algorithm evaluates passwords based on:
 
 Add `data-bs-strength` to automatically initialize. The component will look for a password input in the same parent container.
 
+<BsTable>
+| Attribute | Description |
+| --- | --- |
+| `data-bs-strength` | Initializes the strength indicator on the element (usually `.strength`). |
+| `data-bs-input` | CSS selector for the password field when it is not a sibling in the same container. |
+| `data-bs-min-length` | Minimum length used when computing the strength score. |
+</BsTable>
+
 ```html
 <div>
   <input type="password" class="form-control">
index 8b0a38d274aac3d6be4c24f77740eb4259ce7a8e..8c8e0ffb43137194770fece0822b22db1cc9373c 100644 (file)
@@ -17,7 +17,7 @@ Curious which components explicitly require our JavaScript and Floating UI or Va
 - Menus for displaying and positioning (also requires [Floating UI](https://floating-ui.com/))
 - Modals for displaying, positioning, and scroll behavior
 - Navbar for extending our Collapse and Offcanvas plugins to implement responsive behaviors
-- Navs with the Tab plugin for toggling content panes
+- [Nav]([[docsref:/components/nav]]) for navigation markup and styles; [Tab]([[docsref:/components/tab]]) plugin for toggling tab panes
 - Offcanvases for displaying, positioning, and scroll behavior
 - Scrollspy for scroll behavior and navigation updates
 - Toasts for displaying and dismissing
index 5759d6a4a01d41c20a3bbda40fdb4eb51bad9dc9..4600f08749779e3dc8a520f290a070cf840c360e 100644 (file)
     //   margin-top: $spacer;
     // }
 
+    > .tab-content {
+      min-height: 120px;
+      padding: var(--bs-spacer);
+      background-color: var(--bs-bg-1);
+      @include border-radius(var(--bs-border-radius));
+    }
+
     > .menu.position-static {
       max-width: fit-content;
     }