Tabs
The Tabs component is a responsive horizontal navigation bar that allows the user to easily switch between content. Tab panelsare a set of individual content sections, where only one content panel can be displayed at a time. Each tab panel has an associated tab element that, when activated, displays the panel. The list of tab elements is arranged along one edge of the currently displayed panel, the top edge. The component implements the W3C ARIA APG Tabs Pattern.
Examples
Base
Each item component can have a value prop. The active tab is represented by the value of the item as the modelValue prop of the tabs component.
Show code
<section>
<o-field grouped>
<o-switch v-model="showBooks" label="Show Books item" />
<o-button label="Set Music" @click="activeTab = 'music'" />
</o-field>
<o-tabs v-model="activeTab">
<o-tab-item value="pictures" label="Pictures" icon="image">
what light is light, if Silvia be not seen? <br />
What joy is joy.
</o-tab-item>
<o-tab-item value="articles" label="Articles" icon="pen">
Lorem ipsum dolor sit amet.
</o-tab-item>
<o-tab-item value="music" label="Music" icon="music">
Lorem <br />
ipsum <br />
dolor <br />
sit <br />
amet.
</o-tab-item>
<o-tab-item
value="books"
:visible="showBooks"
label="Books"
icon="book">
What light is light, if Silvia be not seen? <br />
What joy is joy, if Silvia be not by— <br />
Unless it be to think that she is by <br />
And feed upon the shadow of perfection? <br />
Except I be by Silvia in the night, <br />
There is no music in the nightingale.
</o-tab-item>
<o-tab-item value="words" label="Words">
This text is much longer than the other examples. The most
merciful thing in the world, I think, is the inability of the
human mind to correlate all its contents. We live on a placid
island of ignorance in the midst of black seas of infinity, and
it was not meant that we should voyage far. The sciences, each
straining in its own direction, have hitherto harmed us little;
but some day the piecing together of dissociated knowledge will
open up such terrifying vistas of reality, and of our frightful
position therein, that we shall either go mad from the
revelation or flee from the deadly light into the peace and
safety of a new dark age.
</o-tab-item>
<o-tab-item value="videos" label="Videos" icon="video" disabled>
Nunc nec velit nec libero vestibulum eleifend. Curabitur
pulvinar congue luctus. Nullam hendrerit iaculis augue vitae
ornare. Maecenas vehicula pulvinar tellus, id sodales felis
lobortis eget.
</o-tab-item>
</o-tabs>
</section>
import { ref } from "vue";
const activeTab = ref<string>();
const showBooks = ref(false);
Types
The tabs header can be displayed in different styles using the type prop.
Show code
<section>
<o-field label="Boxed/Tabs">
<o-tabs type="boxed">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
</o-field>
<o-field label="Toggle">
<o-tabs type="toggle">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
</o-field>
<o-field label="Pills">
<o-tabs type="pills">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
</o-field>
</section>
Positions
The tabs header can be positioned by the position prop.
Show code
<section>
<o-tabs type="boxed" position="left">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
<o-tabs type="boxed" position="centered">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
<o-tabs type="boxed" position="right">
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
</section>
Expanded
When the expanded prop is set, the tabs header will be occupy the full with it can have.
Show code
<section>
<o-tabs expanded>
<o-tab-item label="Pictures" icon="images" />
<o-tab-item label="Music" icon="music" />
<o-tab-item label="Words" />
<o-tab-item label="Videos" icon="video" />
</o-tabs>
</section>
Variants
Different styles can be achieved with the variant prop. The variant prop can be set for the whole Tabs component as well as for each TabItem.
Show code
<section>
<o-tabs>
<o-tab-item label="Pictures" icon="images" variant="success" />
<o-tab-item label="Music" icon="music" variant="info" />
<o-tab-item label="Words" variant="warning" />
<o-tab-item label="Videos" icon="video" variant="danger" />
</o-tabs>
</section>
Sizes
The component can be displayed in different sizes using the size prop.
Show code
<section>
<o-tabs size="small" type="boxed" :options="options" />
<o-tabs size="medium" type="boxed" :options="options" />
<o-tabs size="large" type="boxed" :options="options" />
</section>
import type { OptionsProp } from "@oruga-ui/oruga-next";
const options: OptionsProp = [
{
label: "Pictures",
value: 0,
attrs: {
icon: "image",
},
},
{
label: "Music",
value: 1,
attrs: {
icon: "music",
},
},
{
label: "Articles",
value: 2,
attrs: {
icon: "pen",
},
},
{
label: "Words",
value: 3,
},
{
label: "Videos",
value: 4,
attrs: {
icon: "video",
disabled: true,
},
},
];
Vertical
Adding the vertical prop displays the component vertically instead of horizontally.
Show code
<section>
<o-field grouped multiline>
<o-field label="Position">
<o-select v-model="position" placeholder="Position">
<option :value="undefined">Default</option>
<option value="left">Left</option>
<option value="right">Right</option>
</o-select>
</o-field>
<o-field label="Size">
<o-select v-model="size" placeholder="Size">
<option :value="undefined">Default</option>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</o-select>
</o-field>
<o-field label="Type">
<o-select v-model="type" placeholder="Type">
<option value="default">Default</option>
<option value="boxed">Boxed</option>
<option value="toggle">Toggle</option>
</o-select>
</o-field>
<o-field>
<o-switch v-model="expanded" label="Expanded" />
</o-field>
</o-field>
<o-tabs
:position="position"
:size="size"
:type="type"
vertical
:expanded="expanded">
<o-tab-item label="Pictures" icon="images">
Lorem ipsum dolor sit amet. <br />
Lorem ipsum dolor sit amet. <br />
Lorem ipsum dolor sit amet. <br />
Lorem ipsum dolor sit amet. <br />
Lorem ipsum dolor sit amet. <br />
Lorem ipsum dolor sit amet.
</o-tab-item>
<o-tab-item label="Music" icon="music">
What light is light, if Silvia be not seen? <br />
What joy is joy, if Silvia be not by— <br />
Unless it be to think that she is by <br />
And feed upon the shadow of perfection? <br />
Except I be by Silvia in the night, <br />
There is no music in the nightingale.
</o-tab-item>
<o-tab-item label="Words">
<p>
This text is much longer than the other examples. The most
merciful thing in the world, I think, is the inability of
the human mind to correlate all its contents. We live on a
placid island of ignorance in the midst of black seas of
infinity, and it was not meant that we should voyage far.
The sciences, each straining in its own direction, have
hitherto harmed us little; but some day the piecing together
of dissociated knowledge will open up such terrifying vistas
of reality, and of our frightful position therein, that we
shall either go mad from the revelation or flee from the
deadly light into the peace and safety of a new dark age.
</p>
</o-tab-item>
<o-tab-item label="Videos" icon="video" disabled>
Nunc nec velit nec libero vestibulum eleifend. Curabitur
pulvinar congue luctus. Nullam hendrerit iaculis augue vitae
ornare. Maecenas vehicula pulvinar tellus, id sodales felis
lobortis eget.
</o-tab-item>
</o-tabs>
</section>
import { ref } from "vue";
const position = ref<"left" | "right">("left");
const expanded = ref(false);
const size = ref(undefined);
const type = ref("default");
Custom header
The individual tab label can be customised using the header slot.
Show code
<section>
<o-tabs type="boxed">
<o-tab-item>
<template #header>
<o-icon icon="info-circle" root-class="custom-icon" />
<span> Issues 3 </span>
</template>
</o-tab-item>
<o-tab-item>
<template #header>
<o-icon icon="retweet" root-class="custom-icon" />
<span> Pull Requests {{ count }} </span>
</template>
</o-tab-item>
</o-tabs>
</section>
import { ref, onMounted } from "vue";
const count = ref(1);
onMounted(() => {
setTimeout(() => {
count.value++;
}, 3000);
});
.custom-icon {
margin-right: 5px;
}
Long header
The multiple prop allows to break the tab header to be broken into multiple lines if there are too many tabs for one line.
Show code
<section>
<o-tabs type="boxed" multiline>
<o-tab-item
v-for="(item, index) in new Array(45)"
:key="`longitem-${index}`"
:label="`Head ${index}`"
:icon="index % 2 === 0 ? 'book' : ''" />
</o-tabs>
</section>
Tabs Component
Responsive horizontal navigation tabs, switch between contents with ease.
<o-tabs></o-tabs>Props
| Prop name | Description | Type | Values | Default |
|---|---|---|---|---|
| activateOnFocus | Set the tab active on navigation focus | boolean | - | false |
| animateInitially | Apply animation on the initial render | boolean | - | From config: tabs: { |
| animated | Tab will have an animation | boolean | - | From config: tabs: { |
| animation | Transition animation name | [string, string, string, string] | [string, string] | [next, prev], [right, left, down, up] | From config: tabs: { |
| ariaLabel | Accessibility aria-label to be passed to the tablist wrapper element | string | - | From config: tabs: { |
| expanded | Tabs will be expanded (full-width) | boolean | - | false |
| v-model | The selected item value, use v-model to make it two-way binding | string|number|object | - | |
| multiline | Show tab items multiline when there is no space | boolean | - | false |
| options | Tabs options, unnecessary when default slot is used | TabsOptions<unknown> | - | |
| override | Override existing theme classes completely | boolean | - | |
| position | Position of the tabs | "centered" | "left" | "right" | left, centered, right | |
| size | Tab size | string | small, medium, large | From config: tabs: { |
| tag | Tablist tag name | DynamicComponent | - | From config: tabs: { |
| type | Tab type | string | default, boxed, toggle, pills | From config: tabs: { |
| variant | Color variant of the control | string | primary, info, success, warning, danger, and any other custom color | From config: tabs: { |
| vertical | Show tab in vertical layout | boolean | - | From config: tabs: { |
Events
| Event name | Properties | Description |
|---|---|---|
| update:model-value | value unknown - updated modelValue prop | modelValue prop two-way binding |
| change | value unknown - new tab valuevalue unknown - old tab value | on tab change event |
Slots
| Name | Description | Bindings |
|---|---|---|
| before | Additional slot before the tabs | |
| after | Additional slot after the tabs | |
| default | Define the tag items here |
TabItem Component
An tab item used by the tabs component.
<o-tab-item></o-tab-item>Props
| Prop name | Description | Type | Values | Default |
|---|---|---|---|---|
| component | Component to be injected | C | - | |
| content | Text content, unnecessary when default slot is used | string | - | |
| disabled | Item will be disabled | boolean | - | false |
| events | Events to be binded to the injected component | EmitsToProps<ComponentEmit<C>> | - | |
| icon | Icon shown to the left of the label | string | - | From config: tabs: { |
| iconPack | Icon pack | string | - | From config: tabs: { |
| label | Item label | string | - | |
| override | Override existing theme classes completely | boolean | - | |
| props | Props to be binded to the injected component | ComponentProps<C> | - | |
| tag | Tabs item tag name | DynamicComponent | - | From config: tabs: { |
| value | Item value (it will be used as the v-model of the wrapper component) - default is an uuid | string|number|object | - | useId() |
| variant | Color variant of the control This will override parent variant. | string | primary, info, success, warning, danger, and any other custom color | |
| visible | Show/hide item | boolean | - | true |
Events
| Event name | Properties | Description |
|---|---|---|
| activate | on tab item activate event | |
| deactivate | on tab item deactivate event |
Slots
| Name | Description | Bindings |
|---|---|---|
| default | Define the tab item content here | active boolean - if item is shown |
| header | Override tab header label | active boolean - if item is shown |
Class Inspector
| Class prop | Description | Props | Suffixes | |
|---|---|---|---|---|
| rootClass | Class of the root element. | |||
| positionClass | Class of the root element with position. | position | bottom | |
| sizeClass | Class of the root element with size. | size | small | |
| typeClass | Class of the root element with type. | type | default | |
| expandedClass | Class of the root element when expanded. | expanded | ||
| verticalClass | Class of the root element when vertical. | vertical | ||
| multilineClass | Class of the root element when multilined. | multiline | ||
| listClass | Class of the list container element. | |||
| animatedClass | Class of the item element when animated. | |||
| contentClass | Class of the panel container element. | |||
| transitioningClass | Class of the panel container element when transitioning. | |||
| ▷ tabClass | Class of the tab item element. | |||
| ▷ tabVariantClass | Class of the step item element with variant (default value by parent steps component). | variant | primary | |
| ▷ tabActiveClass | Class of the tab item element when active. | |||
| ▷ tabDisabledClass | Class of the tab item element when disabled. | disabled | ||
| ▷ tabPreviousClass | Class of the tab item element before the active one. | |||
| ▷ tabNextClass | Class of the tab item element after the active one. | |||
| ▷ tabIconClass | Class of the tab item icon element. | icon | ||
| ▷ tabLabelClass | Class of the tab item label element. | label | ||
| ▷ tabPanelClass | Class of the tab panel element. |
Sass Variables
Current theme ➜ Oruga
| SASS Variable | Default |
|---|---|
| $tabs-sapcer | h.useVar("control-spacer") |
| $tabs-disabled-opacity | h.useVar("control-disabled-opacity") |
| $tabs-tab-padding | h.useVar("control-spacer") calc(2 * h.useVar("control-spacer")) |
| $tabs-tab-icon-margin | 0 h.useVar("control-spacer") 0 0 |
| $tabs-tab-color | h.useVar("font-color") |
| $tabs-tab-font-size | h.useVar("font-size") |
| $tabs-tab-font-weight | h.useVar("font-weight") |
| $tabs-tab-line-height | h.useVar("line-height") |
| $tabs-tab-border-width | h.useVar("control-border-width") |
| $tabs-tab-border-style | solid |
| $tabs-tab-border-color | h.useVar("control-border-color") |
| $tabs-tab-border-radius | h.useVar("border-radius") |
| $tabs-tab-background-color | transparent |
| $tabs-tab-hover-color | $tabs-tab-color |
| $tabs-tab-hover-background-color | hsl(0, 0%, 96%) |
| $tabs-tab-hover-border-color | hsl(0, 0%, 86%) |
| $tabs-tab-hover-border-radius | $tabs-tab-border-radius |
| $tabs-tab-active-color | h.useVar("primary") |
| $tabs-tab-active-background-color | h.useVar("primary-invert") |
| $tabs-tab-active-border-color | h.useVar("primary") |
| $tabs-tab-active-border-radius | $tabs-tab-border-radius |
| $tabs-content-padding | calc(2 * h.useVar("control-spacer")) |
See ➜ 📄 SCSS file
Current theme ➜ Bulma
| SASS Variable | Default |
|---|---|
| $tabs-focused-outline | none |
| $tabs-link-focus-border-bottom-color | css.getVar( "tabs-link-hover-border-bottom-color") |
| $tabs-link-focus-active-border-bottom-color | css.getVar( "tabs-link-active-border-bottom-color") |
| $tabs-boxed-link-focus-active-background-color | css.getVar( "tabs-boxed-link-active-background-color") |
| $tabs-boxed-link-focus-background-color | css.getVar( "tabs-boxed-link-hover-background-color") |
| $tabs-boxed-link-focus-active-border-bottom-color | css.getVar( "tabs-boxed-link-active-border-bottom-color") |
| $tabs-boxed-link-focus-border-bottom-color | css.getVar( "tabs-boxed-link-hover-border-bottom-color") |
| $tabs-toggle-link-focus-active-background-color | css.getVar( "tabs-toggle-link-active-background-color") |
| $tabs-toggle-link-focus-background-color | css.getVar( "tabs-toggle-link-hover-background-color") |
| $tabs-toggle-link-focus-active-border-color | css.getVar( "tabs-toggle-link-active-border-color") |
| $tabs-toggle-link-focus-border-color | css.getVar( "tabs-toggle-link-hover-border-color") |
See ➜ 📄 SCSS file
