MazTabs
MazTabs is a standalone component to display content in tabs with animations
Basic usage
<script lang="ts" setup>
import { MazTabs, MazTabsBar, type MazTabsBarItem, MazTabsContent, MazTabsContentItem } from 'maz-ui/components'
const tabs: MazTabsBarItem[] = [
{ label: 'First Tab', disabled: false },
{ label: 'Second Tab', disabled: false, badge: { color: 'destructive', content: 1, roundedSize: 'full' } },
{ label: 'Third Tab', disabled: true },
]
</script>
<template>
<MazTabs>
<MazTabsBar :items="tabs" />
<MazTabsContent>
<MazTabsContentItem :tab="1" class="py-4">
Tab 1
</MazTabsContentItem>
<MazTabsContentItem :tab="2" class="py-4">
Tab 2
</MazTabsContentItem>
<MazTabsContentItem :tab="3" class="py-4">
Tab 3
</MazTabsContentItem>
</MazTabsContent>
</MazTabs>
</template>With model-value
View code
<script lang="ts" setup>
import { ref } from 'vue'
const currentTab = ref(2)
const tabs: MazTabsBarItem[] = ['First Tab', 'Second Tab', 'Third Tab']
</script>
<template>
<MazTabs v-model="currentTab">
<MazTabsBar :items="tabs" />
<MazTabsContent>
<MazTabsContentItem :tab="1" class="py-4">
Tab 1
</MazTabsContentItem>
<MazTabsContentItem :tab="2" class="py-4">
Tab 2
</MazTabsContentItem>
<MazTabsContentItem :tab="3" class="py-4">
Tab 3
</MazTabsContentItem>
</MazTabsContent>
</MazTabs>
<br>
<MazBtn @click="currentTab = currentTab === 1 ? 2 : 1">
Set model-value to {{ currentTab === 1 ? 2 : 1 }}
</MazBtn>
</template>Persistent tab
To keep the tab current when the page reloads, you can use the persistent props on the component <MazTabsBar />.
The component will save the current table index in the URL of the page via a query parameter.
You can choose the name of this query parameter with the props query-param @default 'tab'
Custom tabs with slot
<MazTabs>
<MazTabsBar :items="tabs">
<template #item="{ item, index, active }">
{{ item.label }}
<MazBadge size="mini" rounded-size="full" :color="active ? 'primary' : 'transparent'"> {{ index }} </MazBadge>
</template>
</MazTabsBar>
</MazTabs>Size and rounded size
Each tab is rendered with a MazBtn, so you can control its size (MazSize) and rounded-size (MazRoundedSize, applied to the bar, the indicator and each tab).
These props can be set on MazTabsBar directly, or on MazTabs which forwards them to its MazTabsBar. They are also globalizable through the global defaults (MazTabsBar or global entry).
<template>
<!-- size & rounded-size forwarded from MazTabs to MazTabsBar -->
<MazTabs size="sm" rounded-size="lg">
<MazTabsBar :items="tabs" />
<!-- ... -->
</MazTabs>
<!-- or directly on MazTabsBar -->
<MazTabsBar :items="tabs" size="lg" rounded-size="full" />
</template>Each item can also override the size and rounded-size (and accepts every other MazBtn prop, except active, block, type, loading and fab).
Active color
The active tab is highlighted by the indicator. Use the color prop (MazColor) on MazTabsBar (or on MazTabs, which forwards it) to color it. When omitted, the default neutral indicator is used.
<template>
<MazTabsBar :items="tabs" color="primary" />
</template>Standalone usage
MazTabsBar can be used on its own, without MazTabs, as an independent switcher with its own v-model.
Nested inside a MazTabs
If your page is already wrapped by a MazTabs, a nested MazTabsBar would otherwise be linked to that parent (clicking a tab would change the page). Add the standalone prop to make it fully independent (it then ignores the parent's selection, size, rounded-size and color):
<MazTabsBar v-model="selected" :items="items" standalone />The model returns the 1-based index of the selected tab, unless the items provide a value (string | number), in which case that value is returned. The model type is inferred from the items passed: declare the items as const (or with literal values) to get a strict union type for the model and the @update:model-value event.
Selected value: weekly
<script lang="ts" setup>
import { MazTabsBar, type MazTabsBarItem } from 'maz-ui/components'
import { ref } from 'vue'
const selected = ref('weekly')
const items = [
{ label: 'Daily', value: 'daily' },
{ label: 'Weekly', value: 'weekly' },
{ label: 'Monthly', value: 'monthly' },
] as const satisfies readonly MazTabsBarItem[]
</script>
<template>
<MazTabsBar v-model="selected" :items="items" color="secondary" rounded-size="full" />
<!-- selected & @update:model-value === 'daily' | 'weekly' | 'monthly' -->
</template>When no value is set on the items, the model is a number (the 1-based index):
<script lang="ts" setup>
const selected = ref(1)
const items = ['First', 'Second', 'Third']
</script>
<template>
<MazTabsBar v-model="selected" :items="items" />
<!-- selected === 1 | 2 | 3 -->
</template>Types
type MazTabsBarItem<Value extends string | number = string | number>
// Inherits all MazBtn props except 'active' | 'block' | 'type' | 'loading' | 'fab'
= | (Omit<MazBtnProps, 'active' | 'block' | 'type' | 'loading' | 'fab'> & {
/**
* Label of the tab
*/
label: string
/**
* Value returned by the model when the tab is selected (standalone usage).
* When omitted, the model returns the 1-based index of the tab.
*/
value?: Value
/**
* Will disable the tab
* @default false
*/
disabled?: boolean
/**
* Badge to display in the tab
* Inherit all props of MazBadge component
*/
badge?: MazBadgeProps & {
/**
* Content of the badge
*/
content: string | number | boolean
}
})
| stringAccessibility
The tabs follow the WAI-ARIA tabs pattern:
MazTabsBaris atablist(pass anaria-labelto name it), each item is atabwitharia-selected, linked to itsMazTabsContentItem(tabpanel) througharia-controls/aria-labelledby.- Keyboard: only the selected tab is in the tab sequence, ← / → select the previous / next tab (reversed in RTL), Home / End the first / last one. Disabled tabs are skipped.
Props & Events emitted
MazTabs
Props
| Name | Description | Type | Required | Default | Possible values |
|---|---|---|---|---|---|
| model-value | v-model The the selected tab number | number | No | - | - |
| size | Size of the tabs, forwarded to MazTabsBar (and each tab button) | "xs" | "sm" | "md" | "lg" | "xl" | "mini" | No | - | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini' |
| rounded-size | Size of the rounded, forwarded to MazTabsBar | MazRoundedSize | No | - | 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' |
| color | Color of the active tab indicator, forwarded to MazTabsBar | "primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent" | No | - | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'destructive' | 'contrast' | 'transparent' |
Events
| Event name | Payload | Description |
|---|---|---|
| update:model-value | value: number | Emitted when the selected tab change |
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |
MazTabsBar
Props
| Name | Description | Type | Required | Default | Possible values |
|---|---|---|---|---|---|
| items | The items to display in the tabs bar | readonly Item[] | Yes | - | - |
| model-value | v-model Selected tab (standalone usage, without MazTabs). Holds the item value when provided, otherwise the 1-based index. Pass items as const (or with literal value) to infer a union type. | MazTabsBarItemValue<Item> | No | - | - |
| size | Size of the tabs (forwarded to each MazBtn) | "xs" | "sm" | "md" | "lg" | "xl" | "mini" | No | 'md' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini' |
| rounded-size | Size of the rounded applied to the bar, the indicator and each tab | MazRoundedSize | No | 'md' | 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' |
| color | Color of the active tab indicator. When omitted, the default neutral indicator is used. | "primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent" | No | - | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'destructive' | 'contrast' | 'transparent' |
| standalone | Force the standalone mode: the tabs bar ignores any surrounding MazTabs (selection, size, rounded-size and color are no longer inherited) and is driven only by its own v-model. Useful for a nested switcher inside a page already wrapped by MazTabs. | boolean | No | false | - |
| persistent | Will add a query param to the url to keep the selected tab on page refresh | boolean | No | false | - |
| query-param | The name of the query param to add to the url | string | No | "tab" | - |
| block | Will make the tabs bar full width | boolean | No | false | - |
| elevation | Will remove the elevation | boolean | No | false | - |
| auto-scroll | Will add a scroll on the tabs bar to show selected element | boolean | No | true | - |
| bordered | Will add a border to the tabs bar | boolean | No | true | - |
Events
| Event name | Payload | Description |
|---|---|---|
| update:model-value | value: MazTabsBarItemValue<Item> | Emitted when the selected tab changes (standalone usage). |
Slots
| Name | Description | Bindings |
|---|---|---|
| item | Content of item to display in the tabs bar | item { label: Item & string; value: string | number | undefined; disabled: boolean; size: "xs" | "sm" | "md" | "lg" | "xl" | "mini" | undefined; roundedSize: MazRoundedSize | undefined; color: NonNullable<"primary" | "secondary" | "accent" | ... - all data of the itemactive boolean - true if the tab is activeindex number - index of the item |
| badge-content | Content in the badge | content string | number | boolean - content of the badge provided in item |
MazTabsContent
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |
MazTabsContentItem
Props
| Name | Description | Type | Required | Default | Possible values |
|---|---|---|---|---|---|
| tab | number | Yes | - | - |
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |