Overview
The Tabs component (mt-tabs) provides a flexible tab navigation system that automatically handles overflow with a “More” menu when tabs don’t fit in the available space. It supports error indicators, badges, and both horizontal and vertical orientations.
Import
import MtTabs from '@/components/navigation/mt-tabs/mt-tabs.vue';
Props
Array of tab items to display. Each item must have name and label properties
When true, displays tabs in a vertical orientation
Deprecated in v4.0.0 - Reduces the maximum width of the tab bar
The name of the tab that should be active by default
TabItem Interface
interface TabItem {
label: string; // Display text for the tab
name: string; // Unique identifier for the tab
hasError?: boolean; // Show error indicator
disabled?: boolean; // Disable the tab
badge?: 'positive' | 'critical' | 'warning' | 'info'; // Badge variant
onClick?: (name: string) => void; // Custom click handler
}
Events
new-item-active
(itemName: string) => void
Emitted when a new tab becomes active. Returns the name of the activated tab
Usage Examples
Basic Tabs
<template>
<mt-tabs
:items="tabItems"
:default-item="activeTab"
@new-item-active="handleTabChange"
/>
<div>Active content: {{ activeTab }}</div>
</template>
<script setup>
import { ref } from 'vue';
import MtTabs from '@/components/navigation/mt-tabs/mt-tabs.vue';
const activeTab = ref('dashboard');
const tabItems = [
{ name: 'dashboard', label: 'Dashboard' },
{ name: 'products', label: 'Products' },
{ name: 'orders', label: 'Orders' },
{ name: 'customers', label: 'Customers' }
];
const handleTabChange = (tabName) => {
activeTab.value = tabName;
console.log('Tab changed to:', tabName);
};
</script>
Tabs with Error Indicators
<template>
<mt-tabs :items="tabItems" default-item="general" />
</template>
<script setup>
const tabItems = [
{ name: 'general', label: 'General' },
{ name: 'validation', label: 'Validation', hasError: true },
{ name: 'permissions', label: 'Permissions', hasError: true },
{ name: 'advanced', label: 'Advanced' }
];
</script>
Tabs with Badges
<template>
<mt-tabs :items="tabItems" default-item="all" />
</template>
<script setup>
const tabItems = [
{ name: 'all', label: 'All Items' },
{ name: 'active', label: 'Active', badge: 'positive' },
{ name: 'errors', label: 'Errors', badge: 'critical' },
{ name: 'warnings', label: 'Warnings', badge: 'warning' },
{ name: 'info', label: 'Info', badge: 'info' }
];
</script>
Disabled Tabs
<template>
<mt-tabs :items="tabItems" default-item="overview" />
</template>
<script setup>
const tabItems = [
{ name: 'overview', label: 'Overview' },
{ name: 'details', label: 'Details' },
{ name: 'premium', label: 'Premium Features', disabled: true },
{ name: 'analytics', label: 'Analytics', disabled: true }
];
</script>
Vertical Tabs
<template>
<div style="display: flex; gap: 1rem;">
<mt-tabs
:items="tabItems"
vertical
default-item="profile"
@new-item-active="activeTab = $event"
/>
<div style="flex: 1;">
<h2>{{ getTabContent(activeTab) }}</h2>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const activeTab = ref('profile');
const tabItems = [
{ name: 'profile', label: 'Profile' },
{ name: 'account', label: 'Account' },
{ name: 'security', label: 'Security' },
{ name: 'notifications', label: 'Notifications' },
{ name: 'billing', label: 'Billing' }
];
const getTabContent = (tab) => {
return `Content for ${tab}`;
};
</script>
Tabs with Custom Click Handlers
<template>
<mt-tabs :items="tabItems" default-item="home" />
</template>
<script setup>
const tabItems = [
{
name: 'home',
label: 'Home',
onClick: (name) => console.log('Home clicked')
},
{
name: 'analytics',
label: 'Analytics',
onClick: (name) => {
// Custom logic before tab change
trackEvent('tab_click', { tab: name });
}
},
{
name: 'settings',
label: 'Settings',
onClick: (name) => console.log('Settings clicked')
}
];
</script>
Using Tabs in a Card
<template>
<mt-card title="Product Management">
<template #tabs>
<mt-tabs
:items="tabItems"
:default-item="activeTab"
@new-item-active="activeTab = $event"
/>
</template>
<div v-if="activeTab === 'list'">
<!-- Product list content -->
</div>
<div v-else-if="activeTab === 'categories'">
<!-- Categories content -->
</div>
<div v-else-if="activeTab === 'settings'">
<!-- Settings content -->
</div>
</mt-card>
</template>
<script setup>
import { ref } from 'vue';
import MtCard from '@/components/layout/mt-card/mt-card.vue';
import MtTabs from '@/components/navigation/mt-tabs/mt-tabs.vue';
const activeTab = ref('list');
const tabItems = [
{ name: 'list', label: 'Product List' },
{ name: 'categories', label: 'Categories' },
{ name: 'settings', label: 'Settings' }
];
</script>
Features
Priority-Plus Navigation
The tabs component automatically handles overflow situations. When tabs don’t fit in the available width, excess tabs are moved into a “More” dropdown menu. This ensures the interface remains usable on all screen sizes.
Visual States
- Active: The currently selected tab is highlighted with a sliding indicator
- Error: Tabs can show an error badge using
hasError: true
- Disabled: Tabs can be disabled using
disabled: true
- Badges: Color-coded badges can be added to highlight tab states
Source
View the component source at /home/daytona/workspace/source/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue:1