Skip to content

Tabs Component

The Tabs component is a flexible navigation interface designed with Vue 3 and Tailwind CSS. It provides both desktop and mobile-friendly tab navigation, with support for both link-based and action-based tabs.

Features

  • Responsive design with mobile dropdown fallback
  • Two visual styles: tabs and buttons
  • Support for both link (<a>) and button-based tabs
  • V-model binding for controlled tab state
  • Custom event handling per tab
  • Full keyboard navigation support
  • Automatic mobile responsive behavior

Basic Usage

vue
<template>
  <Tabs :tabs="tabItems" />
</template>

<script setup>
import { Tabs } from '@robuust-digital/vue-components/core';

const tabItems = [
  {
    name: 'Account',
    url: '#'
  },
  {
    name: 'Company',
    url: '#'
  },
];
</script>

Props

PropTypeDefaultDescription
modelValueNumberundefinedThe index of the active tab (used with v-model)
tabsArray[]Array of tab configuration objects
tabStyleString'default'Visual style of the tabs ('default' or 'buttons')

Tab Configuration

Each tab in the tabs array can have the following properties:

javascript
// Example tab configuration object
{
  name: 'Account',          // Required: Display text for the tab
  as: 'a',                  // Optional: Component to render ('a', 'button', etc.)
  active: true,             // Optional: Whether the tab is initially active
  selectEvent: () => {},    // Optional: Custom event handler for the tab

  // Any other attributes will be passed to the rendered element
  href: '/account',         // Example: For link-based tabs
  target: '_blank',         // Example: For external links
  rel: 'noopener'           // Example: For external links
}

Events

EventArgumentsDescription
update:modelValue(index: number)Emitted when active tab changes
tabs:change(tab: TabConfig)Emitted when a tab is selected

Examples

Show Code
vue
<template>
  <Tabs :tabs="linkTabs" />
</template>

<script setup>
const linkTabs = [
  {
    name: 'Account',
    as: 'a',
    href: '/account',
  },
  {
    name: 'Company',
    as: 'a',
    href: '/account',
  }
];
</script>

Button-style Tabs with Custom Events

Open your console to see the custom event log when clicking on a tab.

Show Code
vue
<template>
  <Tabs
    v-model="activeTabIndex"
    :tabs="actionTabs"
    tab-style="buttons"
    @tabs:change="handleTabChange"
  />
</template>

<script setup>
import { ref } from 'vue';

const activeTabIndex = ref(0);

const handleCustomEvent = () => {
  console.log('Custom tab event triggered');
};

const actionTabs = [
  {
    name: 'Account',
    selectEvent: handleCustomEvent
  },
  {
    name: 'Settings',
    selectEvent: handleCustomEvent
  }
];

const handleTabChange = (tab) => {
  console.log('Tab changed:', tab);
};
</script>
Show Code
vue
<template>
  <Tabs :tabs="externalTabs" />
</template>

<script setup>
const externalTabs = [
  {
    name: 'Documentation',
    as: 'a',
    href: 'https://docs.example.com',
    target: '_blank',
    rel: 'noopener'
  },
  {
    name: 'Internal',
    as: 'a',
    href: '/internal'
  }
];
</script>

CSS Customization ⚡️

To customize the tabs styles global

css
:root {
  /* Available variables */
  --rvc-tabs-border-width: var(--rvc-base-border-width);
  --rvc-tabs-border-color: var(--rvc-base-border-color);
  --rvc-tabs-tab-transition-duration: var(--rvc-base-transition-duration);
  --rvc-tabs-tab-transition-timing-function: var(--rvc-base-transition-timing-function);
  --rvc-tabs-tab-button-border-radius: var(--rvc-base-border-radius);
  --rvc-tabs-gap: calc(var(--spacing) * 10);
  --rvc-tabs-buttons-gap: calc(var(--spacing) * 4);
  --rvc-tabs-tab-color: var(--color-slate-600);
  --rvc-tabs-tab-font-weight: var(--font-weight-medium);
  --rvc-tabs-tab-border-width: 2px;
  --rvc-tabs-tab-padding-bottom: calc(var(--spacing) * 4);
  --rvc-tabs-tab-color-hover: var(--color-slate-700);
  --rvc-tabs-tab-border-color-hover: var(--color-slate-600);
  --rvc-tabs-tab-active-color: var(--color-indigo-600);
  --rvc-tabs-tab-active-border-color: var(--color-indigo-600);
  --rvc-tabs-tab-button-height: calc(var(--spacing) * 9);
  --rvc-tabs-tab-button-padding-x: calc(var(--spacing) * 3);
  --rvc-tabs-tab-active-button-bg-color: var(--color-indigo-100);
}