Tab Group Ready
Tab Group is used as a graphical interface element that allows multiple panels to be contained within a single window, using tabs as a navigational element.
When there are 4 or more navigation items in the Tab Group it’s automatically converted to a select menu on small viewports.
Examples #
<duet-tab-group>
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
<duet-tab label="Säästöt">Tab 3 content</duet-tab>
<duet-tab label="Eläkesuunnitelma">Tab 4 content</duet-tab>
<duet-tab label="Asiointi">Tab 5 content</duet-tab>
</duet-tab-group>
<script>
// Select the above tab group component
var tabs = document.querySelector("duet-tab-group")
// Listen for change events in the tabs
tabs.addEventListener("duetTabChange", function (e) {
console.log("Change detected in tabs:", e.detail)
})
</script>
<duet-tab-group>
<duet-tab label="Yhteenveto" selected>
<duet-card padding="large">
<duet-heading level="h3">Yhteenveto</duet-heading>
<duet-paragraph>Tab 1 content</duet-paragraph>
</duet-card>
</duet-tab>
<duet-tab label="Säästösuunnitelma">
<duet-card padding="large">
<duet-heading level="h3">Säästösuunnitelma</duet-heading>
<duet-paragraph>Tab 2 content</duet-paragraph>
</duet-card>
</duet-tab>
<duet-tab label="Säästöt">
<duet-card padding="large">
<duet-heading level="h3">Säästöt</duet-heading>
<duet-paragraph>Tab 3 content</duet-paragraph>
</duet-card>
</duet-tab>
<duet-tab label="Eläkesuunnitelma">
<duet-card padding="large">
<duet-heading level="h3">Eläkesuunnitelma</duet-heading>
<duet-paragraph>Tab 4 content</duet-paragraph>
</duet-card>
</duet-tab>
<duet-tab label="Asiointi">
<duet-card padding="large">
<duet-heading level="h3">Asiointi</duet-heading>
<duet-paragraph>Tab 5 content</duet-paragraph>
</duet-card>
</duet-tab>
</duet-tab-group>
<duet-tab-group>
<duet-tab label="Outer 1" selected>Outer tab 1 content</duet-tab>
<duet-tab label="Outer 2">
Outer tab 2 content
<duet-tab-group>
<duet-tab label="Inner 1" selected>Inner tab 1 content</duet-tab>
<duet-tab label="Inner 2">Inner tab 2 content</duet-tab>
<duet-tab label="Inner 3">Inner tab 3 content</duet-tab>
</duet-tab-group>
</duet-tab>
<duet-tab label="Outer 3">Outer tab 3 content</duet-tab>
</duet-tab-group>
<duet-tab-group label="Label shown on mobile" label-hidden="false">
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
<duet-tab label="Säästöt">Tab 3 content</duet-tab>
<duet-tab label="Eläkesuunnitelma">Tab 4 content</duet-tab>
<duet-tab label="Asiointi">Tab 5 content</duet-tab>
</duet-tab-group>
<duet-layout margin="none" center>
<div slot="main">
<duet-card heading="plain>default">
<duet-tab-group variation="plain" scrolls>
<duet-tab label=" -- item 1 -- " accessible-description="SomeLAbel" selected>
<duet-card margin="none" image="https://cdn.duetds.com/api/assets/illustrations/placeholder-dark.svg">
<duet-heading level="h3">Card heading 1</duet-heading>
<duet-paragraph margin="none">
Card content lorem ipsum dolor sit amet consectetuer adipiscing elit no nummy laoreet lorem ipsum.
</duet-paragraph>
<duet-spacer></duet-spacer>
<duet-button
fixed
url="#"
padding="none"
variation="plain"
icon="action-arrow-right-small"
icon-size="small"
icon-right
>
Read more
</duet-button>
</duet-card>
</duet-tab>
<duet-tab label=" -- item 2 -- " accessible-description="SomeLAbel">
<duet-card margin="none" image="https://cdn.duetds.com/api/assets/illustrations/placeholder-dark.svg">
<duet-heading level="h3">Card heading 2</duet-heading>
<duet-paragraph margin="none">
Card content lorem ipsum dolor sit amet consectetuer adipiscing elit no nummy laoreet lorem ipsum.
</duet-paragraph>
<duet-spacer></duet-spacer>
<duet-button
fixed
url="#"
padding="none"
variation="plain"
icon="action-arrow-right-small"
icon-size="small"
icon-right
>
Read more
</duet-button>
</duet-card>
</duet-tab>
<duet-tab label=" -- item 3 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 1</duet-heading>
</duet-tab>
<duet-tab label=" -- item 4 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 2</duet-heading>
</duet-tab>
<duet-tab label=" -- item 5 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 3</duet-heading>
</duet-tab>
<duet-tab label=" -- item 6 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 4</duet-heading>
</duet-tab>
<duet-tab label=" -- item 7 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 5</duet-heading>
</duet-tab>
<duet-tab label=" -- item 8 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 6</duet-heading>
</duet-tab>
<duet-tab label=" -- item 9 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 7</duet-heading>
</duet-tab>
<duet-tab label=" -- item 10 -- " accessible-description="SomeLAbel">
<duet-heading level="h3">Card heading 8</duet-heading>
</duet-tab>
</duet-tab-group>
</duet-card>
</div>
</duet-layout>
<duet-tab-group variation="plain">
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
</duet-tab-group>
<style>
duet-tab-group::part(styled-test-button) {
background-color: #fff;
color: #000;
padding: 10px;
border-color: #5b5b5b;
}
duet-tab-group::part(styled-test-button--selected) {
background-color: cyan;
}
</style>
<duet-tab-group variation="plain" identifier="styled-test">
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
</duet-tab-group>
<duet-tab-group variation="plain" class="duet-text-center">
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
</duet-tab-group>
<duet-tab-group variation="plain" class="duet-text-center" margin="none">
<duet-tab label="Kasko">
<div class="duet-p-x-large duet-background-gray-lighter">Tab 1 content</div>
</duet-tab>
<duet-tab label="Liikennevakuutus" selected>
<div class="duet-p-x-large duet-background-gray-lighter">Tab 2 content</div>
</duet-tab>
</duet-tab-group>
<duet-layout center>
<div slot="main">
<duet-tab-group variation="checked">
<duet-tab label="Laaja" caption="574,50 €" selected>Tab 1 content</duet-tab>
<duet-tab label="Suppea More Words" caption="263,90 €">Tab 1 content</duet-tab>
<duet-tab label="Liikenne" caption="163,90 €">Tab 3 content</duet-tab>
</duet-tab-group>
</div>
</duet-layout>
<duet-tab-group variation="plain">
<duet-tab label="Yhteenveto" notification-mark="warning">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected notification-mark="danger">Tab 2 content</duet-tab>
</duet-tab-group>
<duet-spacer size="xx-large"></duet-spacer>
<duet-tab-group>
<duet-tab label="Yhteenveto" selected notification-mark="warning">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" notification-mark="danger">Tab 2 content</duet-tab>
</duet-tab-group>
<duet-tab-group tab-change-confirm>
<duet-tab label="Yhteenveto">Tab 1 content</duet-tab>
<duet-tab label="Säästösuunnitelma" selected>Tab 2 content</duet-tab>
<duet-tab label="Säästöt">Tab 3 content</duet-tab>
<duet-tab label="Eläkesuunnitelma">Tab 4 content</duet-tab>
<duet-tab label="Asiointi">Tab 5 content</duet-tab>
</duet-tab-group>
<script>
// Select the above tab group component
var tabs = document.querySelector("duet-tab-group")
// Listen for tab change request events in the tabs and show confirmation window
tabs.addEventListener("duetTabChangeRequested", function (e) {
const eventDetail = e.detail;
console.log("Tab change request detected in tabs:", eventDetail)
if(window.confirm("Are you sure?")){
tabs.openTab(eventDetail.value)
}
})
// Listen for tab change events in the tabs
tabs.addEventListener("duetTabChange", function (e) {
console.log("Change detected in tabs:", e.detail)
})
</script>
<duet-tab-group>
<duet-tab label="Yhteenveto" content-id="tabpanel1"></duet-tab>
<duet-tab label="Säästösuunnitelma" selected content-id="tabpanel2"></duet-tab>
</duet-tab-group>
<div id="tabpanel1">Tab 1 content</div>
<div id="tabpanel2">Tab 2 content</div>
Properties #
Property | Attribute | Description | Type | Default |
---|---|---|---|---|
accessibleLabel | accessible-label | Aria label for the entire tab-group | string | undefined |
collapses | collapses | Whether the tab-group collapses to a select dropwdown in minor breakpoints | boolean | true |
identifier | identifier | Optional identifier to add to buttons in the tab group | string | this.id |
label | label | Label for the select element which gets shown on mobile. | string | getLocaleString(this.labelDefaults, this.language) |
labelDefaults | label-default | Defaults for Label | DuetLangObject | string | { fi: "Valitse", en: "Choose", sv: "Välj", } |
labelHidden | label-hidden | Determines whether the label for the select element shown on mobile is visually hidden. | boolean | true |
language | language | [DEPRECATED] this is now handled via the html lang tag, and is no longer used - kept to avoid breaking changes and ease unit testing The currently active language. This setting changes the accessible labels to match the chosen language. | "en" | "fi" | "sv" | getLanguage() |
margin | margin | Controls the margin of the component. | "auto" | "none" | "auto" |
padding | padding | Controls the padding of the component. | "auto" | "none" | "auto" |
scrolls | scrolls | Controls whether the tab-group should scroll (by inflection this will disable collapsing to select box on small screens), if this is a number instead of true it will be used as "amount of items to scroll" | boolean | false |
setTabIndex | set-tab-index | [DEPRECATED] in favour of Duet Tab component owning the tab indexing Controls if tab container should have tab index and be accessible by pressing tab | boolean | true |
tabChangeConfirm | tab-change-confirm | If this property is set to true, tab won't change immediately after clicking it. Component will emit "duetTabChangeRequested" event, and it needs to be handled manually in order to change tab. | boolean | false |
theme | theme | Theme of the component. | "" | "default" | "turva" | "" |
variation | variation | Style variation of the tab group. | "checked" | "default" | "plain" | "plain-scrolling" | "default" |
Events #
Event | Description | Type |
---|---|---|
duetChange | [DEPRECATED] in favour of more specific duetTabChange event. Callback for when the value changed. | CustomEvent<{ component: "duet-tab-group"; value: number; }> |
duetTabChange | Event raised when the selected tab is changed | CustomEvent<{ component: "duet-tab-group"; value: number; }> |
duetTabChangeRequested | Event raised when new tab is clicked and "tabChangeConfirm" property is set to true | CustomEvent<{ component: "duet-tab-group"; value: number; }> |
Methods #
openTab(tabIndex: number) => Promise<void>
#
This method allows you to open any of the tabs by calling the method and
passing the index of the tab. Please note that index starts from zero.
Parameters #
Name | Type | Description |
---|---|---|
tabIndex | number |
Returns #
Type: Promise<void>
refresh() => Promise<void>
#
[DEPRECATED]
This method used to refresh the contents of the tab group
but is now deprecated as this is done automatically.
Returns #
Type: Promise<void>
Shadow Parts #
Part | Description |
---|---|
"${identifier}-button" | piercing selector for styling tab buttons |
"${identifier}-button--selected" | piercing selector for styling selected tab button |
Usage #
This section includes guidelines for designers and developers about the usage of this component in different contexts.
Note that the Tab Group must always have exactly one tab selected. If there are none selected, the first tab is automatically selected. If multiple tabs have selected
attribute set, only the first one will have effect.
When to use #
- To allow multiple panels to be contained within a single window.
Accessibility #
This component has been validated to meet the WCAG 2.1 AA accessibility guidelines. You can find additional information regarding accessibility of this component below.
- Tab group component uses
role="tablist"
to convey its functionality correctly to assistive technologies.
Integration
For integration, event and theming guidelines, please see Using Components. This documentation explains how to implement and use Duet’s components across different technologies like Angular, React or Vanilla JavaScript.
Tutorials
Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:
Building Layouts
TutorialsUsing CLI Tools
TutorialsCreating Custom Patterns
TutorialsServer Side Rendering
TutorialsSharing Prototypes
TutorialsUsage With Markdown
Troubleshooting
If you experience any issues while using a component, please head over to the Support page for more guidelines and help.