Tabs
Let users navigate between related sections of content, displaying one section at a time.
Props
initialTab
number
The initially active tab (1-based index). If not set, the first tab is active.
navigation
GoabTabsNavigation
Controls URL navigation mode on tab change.
Defaults to
hash.
orientation
GoabTabsOrientation
Tab layout orientation. "auto" stacks vertically on mobile, "horizontal" keeps horizontal on all screen sizes.
Defaults to
auto.
testId
string
Sets a data-testid attribute for automated testing.
variant
GoabTabsVariant
Visual style variant. "segmented" shows pill-style tabs with animation.
Defaults to
default.
Events
onChange
(detail: GoabTabsOnChangeDetail) => void
Callback fired when the active tab changes.
Tab Props
disabled
boolean
When true, disables the tab so it cannot be selected.
heading
string | React.ReactNode
The text label for this tab. Can also pass React nodes for custom heading content.
slug
string
URL-friendly identifier for the tab, used for hash-based navigation.
Tab ReactNode
heading
ReactNode
The text label for this tab. Can also pass React nodes for custom heading content.
Set a specific tab to be active
const review = [0, 1, 2, 3];
const complete = [0, 1];<GoabTabs initialTab={2}>
<GoabTab heading="All">
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{review.map((i) => (
<tr key={`review-${i}`}>
<td>
<GoabBadge type="important" content="Review pending" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
{complete.map((i) => (
<tr key={`complete-${i}`}>
<td>
<GoabBadge type="information" content="Complete" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
<GoabTab
heading={
Review pending
<GoabBadge type="important" content="4" icon={false} />
}
>
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{review.map((i) => (
<tr key={i}>
<td>
<GoabBadge type="important" content="Review pending" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
<GoabTab
heading={
<>
Complete
<GoabBadge type="information" content="338" icon={false} />
</>
}
>
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{complete.map((i) => (
<tr key={i}>
<td>
<GoabBadge type="information" content="Complete" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
</GoabTabs>review = [0, 1, 2, 3];
complete = [0, 1];<goab-tabs [initialTab]="2">
<goab-tab heading="All">
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of review; track $index) {
<tr>
<td>
<goab-badge type="important" content="Review pending"></goab-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goab-button type="tertiary" size="compact">Action</goab-button>
</td>
</tr>
} @for (i of complete; track $index) {
<tr>
<td>
<goab-badge type="information" content="Complete"></goab-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goab-button type="tertiary" size="compact">Action</goab-button>
</td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
<goab-tab [heading]="reviewPending">
<ng-template #reviewPending
>Review pending<goab-badge type="important" content="4" [icon]="false"></goab-badge
></ng-template>
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of review; track $index) {
<tr>
<td>
<goab-badge type="important" content="Review pending"></goab-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goab-button type="tertiary" size="compact">Action</goab-button>
</td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
<goab-tab [heading]="completeTemplate">
<ng-template #completeTemplate
>Complete<goab-badge type="information" content="338" [icon]="false"></goab-badge
></ng-template>
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of complete; track $index) {
<tr>
<td>
<goab-badge type="information" content="Complete"></goab-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goab-button type="tertiary" size="compact">Action</goab-button>
</td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
</goab-tabs><goa-tabs version="2" initialtab="2">
<goa-tab>
<div slot="heading">All</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="information" content="Complete"></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
<goa-tab>
<div slot="heading">
Review pending<goa-badge
version="2"
type="important"
content="4"
icon="false"
></goa-badge>
</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
<goa-tab>
<div slot="heading">
Complete<goa-badge
version="2"
type="information"
content="338"
icon="false"
></goa-badge>
</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge version="2" type="information" content="Complete"></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="information" content="Complete"></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
</goa-tabs>Show different views of data in a table
const review = [0, 1, 2, 3];
const complete = [0, 1];<GoabTabs initialTab={1}>
<GoabTab heading="All">
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{review.map((i) => (
<tr key={`review-${i}`}>
<td>
<GoabBadge type="important" content="Review pending" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
{complete.map((i) => (
<tr key={`complete-${i}`}>
<td>
<GoabBadge type="information" content="Complete" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
<GoabTab
heading={
Review pending
<GoabBadge type="important" content="4" icon={false} />
}
>
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{review.map((i) => (
<tr key={i}>
<td>
<GoabBadge type="important" content="Review pending" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
<GoabTab
heading={
<>
Complete
<GoabBadge type="information" content="338" icon={false} />
</>
}
>
<GoabTable width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th className="goa-table-number-header">Number</th>
<th style={{ width: "1%", whiteSpace: "nowrap" }}>Action</th>
</tr>
</thead>
<tbody>
{complete.map((i) => (
<tr key={i}>
<td>
<GoabBadge type="information" content="Complete" />
</td>
<td>Lorem Ipsum</td>
<td className="goa-table-number-column">1234567890</td>
<td>
<GoabButton type="tertiary" size="compact">
Action
</GoabButton>
</td>
</tr>
))}
</tbody>
</GoabTable>
</GoabTab>
</GoabTabs>reviewItems = [0, 1, 2, 3];
completeItems = [0, 1];<goab-tabs>
<goab-tab heading="All">
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of reviewItems; track $index) {
<tr>
<td><goab-badge type="important" content="Review pending"></goab-badge></td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td><goab-button type="tertiary" size="compact">Action</goab-button></td>
</tr>
} @for (i of completeItems; track $index) {
<tr>
<td><goab-badge type="information" content="Complete"></goab-badge></td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td><goab-button type="tertiary" size="compact">Action</goab-button></td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
<goab-tab [heading]="reviewPending">
<ng-template #reviewPending
>Review pending<goab-badge type="important" content="4" [icon]="false"></goab-badge
></ng-template>
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of reviewItems; track $index) {
<tr>
<td><goab-badge type="important" content="Review pending"></goab-badge></td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td><goab-button type="tertiary" size="compact">Action</goab-button></td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
<goab-tab [heading]="completeTab">
<ng-template #completeTab
>Complete<goab-badge type="information" content="338" [icon]="false"></goab-badge
></ng-template>
<goab-table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
@for (i of completeItems; track $index) {
<tr>
<td><goab-badge type="information" content="Complete"></goab-badge></td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td><goab-button type="tertiary" size="compact">Action</goab-button></td>
</tr>
}
</tbody>
</goab-table>
</goab-tab>
</goab-tabs><goa-tabs version="2">
<goa-tab>
<div slot="heading">All</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge version="2" type="information" content="Complete"></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
<goa-tab>
<div slot="heading">
Review pending<goa-badge
version="2"
type="important"
content="4"
icon="false"
></goa-badge>
</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
<tr>
<td>
<goa-badge
version="2"
type="important"
content="Review pending"
></goa-badge>
</td>
<td>Lorem ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
<goa-tab>
<div slot="heading">
Complete<goa-badge
version="2"
type="information"
content="338"
icon="false"
></goa-badge>
</div>
<goa-table version="2" width="100%">
<table width="100%">
<thead>
<tr>
<th>Status</th>
<th>Text</th>
<th class="goa-table-number-header">Number</th>
<th style="width: 1%; white-space: nowrap">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<goa-badge version="2" type="information" content="Complete"></goa-badge>
</td>
<td>Lorem Ipsum</td>
<td class="goa-table-number-column">1234567890</td>
<td>
<goa-button version="2" type="tertiary" size="compact">Action</goa-button>
</td>
</tr>
</tbody>
</table>
</goa-table>
</goa-tab>
</goa-tabs>The workspace is for productivity-focused services used by service delivery staff as a daily tool to review information, manage records, and complete tasks. The design prioritizes productivity, efficiency, and accuracy so staff can move through their work quickly while ensuring the best outcome for citizens and government.
Workspaces should be adapted to fit each service's context and user needs. The reference example is a starting point to expand on, not a rigid template.
Usage
Don't
Don't use tabs to indicate progress.
Don't
Don't use tabs if users need to see content from multiple tabs simultaneously.
Don't
Avoid nesting tabs inside other tabs.
Interaction
Do
Always have one of the tabs pre-selected on page load.
Content
Don't
Don't truncate tab labels - use short labels instead.