Tabs
KTabs are horizontal controls that allow users to switch between multiple views within one page.
- Tab 1
- Tab 2
Tab 1 content
<KTabs :tabs="tabs">
<template #tab1>
<p>Tab 1 content</p>
</template>
<template #tab2>
<p>Tab 2 content</p>
</template>
</KTabs>
Props
tabs
Required prop, which is an array of tab objects with the following interface:
interface Tab {
hash: string
title: string
disabled?: boolean,
to?: string | object
}
hash
- has to be unique, corresponds to the panel slot nametitle
- title to be displayed in the tabdisabled
- whether or not tab is disabledto
- if present, tab will be rendered as either arouter-link
or ana
- Tab 1
- Tab 2
- Tab 3 (disabled)
Tab 1 content
<KTabs
:tabs="[
{
hash: '#tab1',
title: 'Tab 1'
},
{
hash: '#tab2',
title: 'Tab 2'
},
{
hash: '#tab3',
title: 'Tab 3',
disabled: true
}
]"
>
<template #tab1>
<p>Tab 1 content</p>
</template>
<template #tab2>
<p>Tab 2 content</p>
</template>
<template #tab3>
<p>Tab 3 content</p>
</template>
</KTabs>
Tabs as links
Passing the to
property for each tab object enables rendering tabs as links. If a string is provided, it will be used as the href
attribute in the rendered a
element. If an object is provided, the tab will be rendered as a router-link
.
TIP
When creating tab links, it is recommended to set the hidePanels
prop to true
, as page changes typically do not involve the use of panel
slots.
#tab-link-1
<template>
<KTabs :tabs="linkTabs" hide-panels />
<router-view v-slot="{ route }">
{{ route.hash }}
</router-view>
</template>
<script setup lang="ts">
import { Tab } from '@kong/kongponents'
const linkTabs = ref<Tab[]>([
{
hash: '#tab1',
title: 'Tab 1',
to: '#tab-link-1'
},
{
hash: '#tab2',
title: 'Tab 2',
to: '#tab-link-2'
},
])
</script>
v-model
KTabs will set the first tab in the tabs
array as active. You can override this by passing in the hash of any other tab to be used with v-model
.
- Tab 1
- Tab 2
Tab 2 content
<template>
<KTabs v-model="currentTab" :tabs="tabs">
<template #tab1>Tab 1 content</template>
<template #tab2>Tab 2 content</template>
</KTabs>
</template>
<script setup lang="ts">
import type { Tab } from '@kong/kongponents'
const currentTab = ref<string>('#tab2')
const tabs: Tab[] = [
{
hash: '#tab1',
title: 'Tab 1'
},
{
hash: '#tab2',
title: 'Tab 2'
}
]
</script>
If you want to keep your v-model
in sync so that you can programmatically change the active tab after initialization, you also must respond to the @change
emitted event.
- Tab 1
- Tab 2
<KTabs v-model="currentTab" :tabs="tabs" @change="hash => currentTab = hash">
<template #tab1>Tab 1 content</template>
<template #tab2>Tab 2 content</template>
</KTabs>
<KButton @click="currentTab = '#tab1'">Activate Tab 1</KButton>
<KButton @click="currentTab = '#tab2'">Activate Tab 2</KButton>
hidePanels
A boolean
that determines whether all tabs should have corresponding "panel" (the tab content) containers. Defaults to false
.
In some scenarios, you may want to implement the KTabs UI controls without utilizing the corresponding panel containers.
For example, you could set the hidePanels
prop to true
and then your host app could provide custom functionality such as navigating to a different page or router-view
on click.
Here's an example where we display the active tab hash:
- Gateway
- Notifications
- Documentation
- Disabled
Active hash: #gateway
<template>
<KTabs :tabs="tabs" hide-panels @change="tabChange" />
<p>Active hash: {{ currentTab }} </p>
</template>
<script setup lang="ts">
import type { Tab } from '@kong/kongponents'
const tabs: Tab[] = [
{ hash: '#pictures', title: 'Pictures' },
{ hash: '#movies', title: 'Movies' },
{ hash: '#books', title: 'Books' },
]
const currentTab = ref<string>(tabs.value[0].hash)
const tabChange = (hash: string): void => {
currentTab.value = hash
}
</script>
Slots
anchor & panel
The tab control defaults to the tab.title
string. You may use the #{tab.hash}-anchor
slot to customize the content of the tab control.
In order provide the tab panel content (when the hidePanels
prop is set to false
) you must slot the content in the named slot, defined by the tab.hash
string, without the #
. For example, if tab.hash
is #notifications
- the panel slot name will be notifications
, like in the example below.
- Gateway
- Notifications3
- Documentation
- Disabled
<KTabs :tabs="tabs">
<template #gateway-anchor>
<KongIcon />
Gateway
</template>
<template #gateway><b>Gateway</b> tab content</template>
<template #notifications-anchor>
<InboxNotificationIcon />
Notifications
<KBadge appearance="decorative">3</KBadge>
</template>
<template #notifications><b>Notifications</b> tab content</template>
<template #docs-anchor>
<BookIcon />
Documentation
</template>
<template #docs><b>Documentation</b> tab content</template>
<template #disabled-anchor>
<KTooltip text="This tab item is disabled.">
<div>Disabled</div>
</KTooltip>
</template>
</KTabs>
Events
change
KTabs emits a @change
event with the new tab hash
when clicked. You can use this to set the router or window hash and in turn use that with v-model
.
<template>
<KTabs
:tabs="tabs"
v-model="$route.hash"
@change="hash => $router.replace({ hash })">
<template #tab1>Tab 1 content</template>
<template #tab2>Tab 2 content</template>
</KTabs>
</template>
<script setup lang="ts">
import type { Tab } from '@kong/kongponents'
// importing $route and $router in your app may vary and is excluded in this example.
const tabs = ref<Tab[]>([
{ hash: '#tab1', title: 'Tab 1' },
{ hash: '#tab2', title: 'Tab 2' },
])
</script>