md-tabs spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
Switch between sibling views within one screen. md-tabs is the strip
only: it owns the active index, the roving focus and the indicator. The content
lives in a separate md-tab-panels region, and each
tab is a md-tab child.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs aria-label="Travel sections">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '500px' }}>
<MdTabs aria-label="Travel sections">
<MdTab label="Flights" icon="flight"></MdTab>
<MdTab label="Hotels" icon="hotel"></MdTab>
<MdTab label="Trips" icon="explore"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs aria-label="Travel sections">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs aria-label="Travel sections">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs aria-label="Travel sections">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
Already installed? See the
Installation guide for one-time package setup
(core + tokens, fonts). Each tab below shows two patterns for using
md-tabs in your project: Option A registers every AWC UI
component at once (simplest), Option B imports only this component for
tree-shake-friendly bundles.
<!-- ─── Option A: global registration (all components) ─── -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- ─── Option B: single import (tree-shake only md-tabs) ─── -->
<script type="module">
import '@awc-ui/core/components/md-tabs';
</script>
<md-tabs></md-tabs>// ─── Option A: typed React wrapper (registers all components) ───
// Importing from '@awc-ui/react' calls defineCustomElements() as a
// side effect, so every md-* element becomes available in the browser.
import { MdTabs } from '@awc-ui/react';
export function Example() {
return <MdTabs></MdTabs>;
}
// ─── Option B: single import (tree-shake to only md-tabs) ───
// Skip the wrapper and use the raw custom element. Smallest bundle,
// but you lose typed props/events on JSX.
import '@awc-ui/core/components/md-tabs';
export function ExampleTreeShaken() {
return <md-tabs></md-tabs>;
}// ─── Option A: schema module (any md-* element accepted) ───
// Pair with `defineCustomElements(window)` in main.ts.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<md-tabs></md-tabs>`,
})
export class ExampleComponent {}
// ─── Option B: typed directive (tree-shake friendly) ───
// Pair with `import '@awc-ui/core/components/md-tabs'` in main.ts.
import { Component } from '@angular/core';
import { MdTabs } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [MdTabs],
template: `<md-tabs></md-tabs>`,
})
export class ExampleTreeShakenComponent {}<!-- ─── Option A: typed Vue wrapper (registers all components) ─── -->
<script setup lang="ts">
import { MdTabs } from '@awc-ui/vue';
</script>
<template>
<MdTabs></MdTabs>
</template>
<!-- ─── Option B: single import (tree-shake to only md-tabs) ─── -->
<script setup lang="ts">
import '@awc-ui/core/components/md-tabs';
</script>
<template>
<md-tabs></md-tabs>
</template><!-- ─── Option A: global registration (done once in main entry) ─── -->
<!-- main.ts: -->
<!-- import { defineCustomElements } from '@awc-ui/svelte'; -->
<!-- defineCustomElements(window); -->
<md-tabs></md-tabs>
<!-- ─── Option B: single import (tree-shake to only md-tabs) ─── -->
<script lang="ts">
import '@awc-ui/core/components/md-tabs';
</script>
<md-tabs></md-tabs>| Situation | Use instead |
|---|---|
| Sequential content meant to be read in order | Hierarchy in the content — typography and spacing |
| A linear process with validation | md-stepper |
| Top-level app destinations | md-navigation-bar / md-navigation-rail |
| Independent collapsible sections | md-accordion |
| Choosing a value or mode | md-segmented-button |
| Actions rather than views | md-button-group / md-toolbar |
| Many categories that won’t fit | md-select, or a menu |
| Need | Setting |
|---|---|
| Top-level sections of a screen | variant="primary" (default) |
| Sub-sections inside a primary tab’s panel | variant="secondary" |
| Equal-width tabs filling the strip | tab-width="equal" (default) |
| Tabs sized to their labels | tab-width="auto" |
| More tabs than fit | They scroll — no prop needed |
| Wire tabs to panels for you | Wrap panels in md-tab-panels |
| Tighter rows | density on each md-tab |
primary is for the top-level tab set on a surface; secondary is for a nested
set inside a primary one. The children carry their own variant — the strip
propagates its value to them, so keep them consistent if you also set it by
hand.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary tabs">
<md-tab label="Flights"></md-tab>
<md-tab label="Hotels"></md-tab>
<md-tab label="Trips"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary tabs">
<md-tab label="Music"></md-tab>
<md-tab label="Podcasts"></md-tab>
<md-tab label="Audiobooks"></md-tab>
</md-tabs>
</div>import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Primary tabs">
<MdTab label="Flights"></MdTab>
<MdTab label="Hotels"></MdTab>
<MdTab label="Trips"></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="secondary" aria-label="Secondary tabs">
<MdTab label="Music"></MdTab>
<MdTab label="Podcasts"></MdTab>
<MdTab label="Audiobooks"></MdTab>
</MdTabs>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary tabs">
<md-tab label="Flights"></md-tab>
<md-tab label="Hotels"></md-tab>
<md-tab label="Trips"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary tabs">
<md-tab label="Music"></md-tab>
<md-tab label="Podcasts"></md-tab>
<md-tab label="Audiobooks"></md-tab>
</md-tabs>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary tabs">
<md-tab label="Flights"></md-tab>
<md-tab label="Hotels"></md-tab>
<md-tab label="Trips"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary tabs">
<md-tab label="Music"></md-tab>
<md-tab label="Podcasts"></md-tab>
<md-tab label="Audiobooks"></md-tab>
</md-tabs>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary tabs">
<md-tab label="Flights"></md-tab>
<md-tab label="Hotels"></md-tab>
<md-tab label="Trips"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary tabs">
<md-tab label="Music"></md-tab>
<md-tab label="Podcasts"></md-tab>
<md-tab label="Audiobooks"></md-tab>
</md-tabs>
</div>Icons stack above the label by default; inline-icon puts them side by side.
badge with a value renders a pill, badge="" renders a dot. M3 forbids mixing
icon+text tabs with icon-only or text-only tabs in the same set.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Stacked icons">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Inline icons">
<md-tab label="Flights" icon="flight" inline-icon></md-tab>
<md-tab label="Hotels" icon="hotel" inline-icon></md-tab>
<md-tab label="Trips" icon="explore" inline-icon></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs variant="primary" aria-label="Badges">
<md-tab label="Inbox" icon="inbox" badge="12"></md-tab>
<md-tab label="Sent" icon="send"></md-tab>
<md-tab label="Drafts" icon="drafts" badge=""></md-tab>
<md-tab label="Spam" icon="report" badge="3"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Stacked icons">
<MdTab label="Flights" icon="flight"></MdTab>
<MdTab label="Hotels" icon="hotel"></MdTab>
<MdTab label="Trips" icon="explore"></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Inline icons">
<MdTab label="Flights" icon="flight" inline-icon></MdTab>
<MdTab label="Hotels" icon="hotel" inline-icon></MdTab>
<MdTab label="Trips" icon="explore" inline-icon></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '500px' }}>
<MdTabs variant="primary" aria-label="Badges">
<MdTab label="Inbox" icon="inbox" badge="12"></MdTab>
<MdTab label="Sent" icon="send"></MdTab>
<MdTab label="Drafts" icon="drafts" badge=""></MdTab>
<MdTab label="Spam" icon="report" badge="3"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Stacked icons">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Inline icons">
<md-tab label="Flights" icon="flight" inline-icon></md-tab>
<md-tab label="Hotels" icon="hotel" inline-icon></md-tab>
<md-tab label="Trips" icon="explore" inline-icon></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs variant="primary" aria-label="Badges">
<md-tab label="Inbox" icon="inbox" badge="12"></md-tab>
<md-tab label="Sent" icon="send"></md-tab>
<md-tab label="Drafts" icon="drafts" badge=""></md-tab>
<md-tab label="Spam" icon="report" badge="3"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Stacked icons">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Inline icons">
<md-tab label="Flights" icon="flight" inline-icon></md-tab>
<md-tab label="Hotels" icon="hotel" inline-icon></md-tab>
<md-tab label="Trips" icon="explore" inline-icon></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs variant="primary" aria-label="Badges">
<md-tab label="Inbox" icon="inbox" badge="12"></md-tab>
<md-tab label="Sent" icon="send"></md-tab>
<md-tab label="Drafts" icon="drafts" badge=""></md-tab>
<md-tab label="Spam" icon="report" badge="3"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Stacked icons">
<md-tab label="Flights" icon="flight"></md-tab>
<md-tab label="Hotels" icon="hotel"></md-tab>
<md-tab label="Trips" icon="explore"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Inline icons">
<md-tab label="Flights" icon="flight" inline-icon></md-tab>
<md-tab label="Hotels" icon="hotel" inline-icon></md-tab>
<md-tab label="Trips" icon="explore" inline-icon></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs variant="primary" aria-label="Badges">
<md-tab label="Inbox" icon="inbox" badge="12"></md-tab>
<md-tab label="Sent" icon="send"></md-tab>
<md-tab label="Drafts" icon="drafts" badge=""></md-tab>
<md-tab label="Spam" icon="report" badge="3"></md-tab>
</md-tabs>
</div>Custom glyphs go in the tab’s icon slot and replace the icon prop:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Slotted icons">
<md-tab label="Starred">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
</md-tab>
<md-tab label="Loved">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
</md-tab>
<md-tab label="Music">
<span slot="icon" style="font-size: 24px;">🎵</span>
</md-tab>
</md-tabs>
</div>import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Slotted icons">
<MdTab label="Starred">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
</MdTab>
<MdTab label="Loved">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
</MdTab>
<MdTab label="Music">
<span slot="icon" style={{ fontSize: '24px' }}>🎵</span>
</MdTab>
</MdTabs>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Slotted icons">
<md-tab label="Starred">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
</md-tab>
<md-tab label="Loved">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
</md-tab>
<md-tab label="Music">
<span slot="icon" style="font-size: 24px;">🎵</span>
</md-tab>
</md-tabs>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Slotted icons">
<md-tab label="Starred">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
</md-tab>
<md-tab label="Loved">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
</md-tab>
<md-tab label="Music">
<span slot="icon" style="font-size: 24px;">🎵</span>
</md-tab>
</md-tabs>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Slotted icons">
<md-tab label="Starred">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
</md-tab>
<md-tab label="Loved">
<svg slot="icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
</md-tab>
<md-tab label="Music">
<span slot="icon" style="font-size: 24px;">🎵</span>
</md-tab>
</md-tabs>
</div>A disabled tab is skipped by arrow-key navigation and ignored by clicks.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary states">
<md-tab label="Active" icon="home"></md-tab>
<md-tab label="Inactive" icon="search"></md-tab>
<md-tab label="Disabled" icon="block" disabled></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary states">
<md-tab label="Active"></md-tab>
<md-tab label="Inactive"></md-tab>
<md-tab label="Disabled" disabled></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Primary states">
<MdTab label="Active" icon="home"></MdTab>
<MdTab label="Inactive" icon="search"></MdTab>
<MdTab label="Disabled" icon="block" disabled></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="secondary" aria-label="Secondary states">
<MdTab label="Active"></MdTab>
<MdTab label="Inactive"></MdTab>
<MdTab label="Disabled" disabled></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary states">
<md-tab label="Active" icon="home"></md-tab>
<md-tab label="Inactive" icon="search"></md-tab>
<md-tab label="Disabled" icon="block" disabled></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary states">
<md-tab label="Active"></md-tab>
<md-tab label="Inactive"></md-tab>
<md-tab label="Disabled" disabled></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary states">
<md-tab label="Active" icon="home"></md-tab>
<md-tab label="Inactive" icon="search"></md-tab>
<md-tab label="Disabled" icon="block" disabled></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary states">
<md-tab label="Active"></md-tab>
<md-tab label="Inactive"></md-tab>
<md-tab label="Disabled" disabled></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Primary states">
<md-tab label="Active" icon="home"></md-tab>
<md-tab label="Inactive" icon="search"></md-tab>
<md-tab label="Disabled" icon="block" disabled></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="secondary" aria-label="Secondary states">
<md-tab label="Active"></md-tab>
<md-tab label="Inactive"></md-tab>
<md-tab label="Disabled" disabled></md-tab>
</md-tabs>
</div>Two separate knobs, and confusing them is the usual bug.
| Prop | Controls | Values |
|---|---|---|
tab-width | How each tab sizes along the strip | equal (default, share the parent’s full width) · auto (content width, strip scrolls) · any CSS length, e.g. 140px |
width | The width of the whole strip | Any CSS size. Default: 100% of the parent |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="equal" aria-label="Equal tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="auto" aria-label="Auto tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="140px" aria-label="Fixed tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '620px' }}>
<MdTabs tabWidth="equal" aria-label="Equal tab width">
<MdTab label="Inbox" badge="3"></MdTab>
<MdTab label="Payments"></MdTab>
<MdTab label="Documents and archived"></MdTab>
<MdTab label="Settings"></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '620px' }}>
<MdTabs tabWidth="auto" aria-label="Auto tab width">
<MdTab label="Inbox" badge="3"></MdTab>
<MdTab label="Payments"></MdTab>
<MdTab label="Documents and archived"></MdTab>
<MdTab label="Settings"></MdTab>
</MdTabs>
</div>
<div style={{ inlineSize: '100%', maxInlineSize: '620px' }}>
<MdTabs tabWidth="140px" aria-label="Fixed tab width">
<MdTab label="Inbox" badge="3"></MdTab>
<MdTab label="Payments"></MdTab>
<MdTab label="Documents and archived"></MdTab>
<MdTab label="Settings"></MdTab>
</MdTabs>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="equal" aria-label="Equal tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="auto" aria-label="Auto tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="140px" aria-label="Fixed tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="equal" aria-label="Equal tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="auto" aria-label="Auto tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="140px" aria-label="Fixed tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="equal" aria-label="Equal tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="auto" aria-label="Auto tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>
<div style="inline-size: 100%; max-inline-size: 620px;">
<md-tabs tab-width="140px" aria-label="Fixed tab width">
<md-tab label="Inbox" badge="3"></md-tab>
<md-tab label="Payments"></md-tab>
<md-tab label="Documents and archived"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
</div>More tabs than fit? The strip scrolls horizontally, activating an off-screen tab scrolls it into view, and a fade marks the clipped edge. M3 asks you to offset the first tab from the leading edge so it’s clear more exist.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 400px;">
<md-tabs variant="primary" tab-width="auto" aria-label="Scrollable tabs">
<md-tab label="Tab 1"></md-tab>
<md-tab label="Tab 2"></md-tab>
<md-tab label="Tab 3"></md-tab>
<md-tab label="Tab 4"></md-tab>
<md-tab label="Tab 5"></md-tab>
<md-tab label="Tab 6"></md-tab>
<md-tab label="Tab 7"></md-tab>
<md-tab label="Tab 8"></md-tab>
</md-tabs>
</div>import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '400px' }}>
<MdTabs variant="primary" tabWidth="auto" aria-label="Scrollable tabs">
<MdTab label="Tab 1"></MdTab>
<MdTab label="Tab 2"></MdTab>
<MdTab label="Tab 3"></MdTab>
<MdTab label="Tab 4"></MdTab>
<MdTab label="Tab 5"></MdTab>
<MdTab label="Tab 6"></MdTab>
<MdTab label="Tab 7"></MdTab>
<MdTab label="Tab 8"></MdTab>
</MdTabs>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 400px;">
<md-tabs variant="primary" tab-width="auto" aria-label="Scrollable tabs">
<md-tab label="Tab 1"></md-tab>
<md-tab label="Tab 2"></md-tab>
<md-tab label="Tab 3"></md-tab>
<md-tab label="Tab 4"></md-tab>
<md-tab label="Tab 5"></md-tab>
<md-tab label="Tab 6"></md-tab>
<md-tab label="Tab 7"></md-tab>
<md-tab label="Tab 8"></md-tab>
</md-tabs>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 400px;">
<md-tabs variant="primary" tab-width="auto" aria-label="Scrollable tabs">
<md-tab label="Tab 1"></md-tab>
<md-tab label="Tab 2"></md-tab>
<md-tab label="Tab 3"></md-tab>
<md-tab label="Tab 4"></md-tab>
<md-tab label="Tab 5"></md-tab>
<md-tab label="Tab 6"></md-tab>
<md-tab label="Tab 7"></md-tab>
<md-tab label="Tab 8"></md-tab>
</md-tabs>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 400px;">
<md-tabs variant="primary" tab-width="auto" aria-label="Scrollable tabs">
<md-tab label="Tab 1"></md-tab>
<md-tab label="Tab 2"></md-tab>
<md-tab label="Tab 3"></md-tab>
<md-tab label="Tab 4"></md-tab>
<md-tab label="Tab 5"></md-tab>
<md-tab label="Tab 6"></md-tab>
<md-tab label="Tab 7"></md-tab>
<md-tab label="Tab 8"></md-tab>
</md-tabs>
</div>md-tabs renders no content. Put a
md-tab-panels region directly after the strip with
one md-tab-panel per tab, in tab order. The region
finds the nearest preceding md-tabs sibling (or point for at its id),
follows mdTabChange itself, and wires the ARIA both ways — aria-controls on
each tab, aria-labelledby on each panel, ids auto-assigned where missing.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs id="analytics-strip" aria-label="Analytics sections">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Reports" badge="2"></md-tab>
</md-tabs>
<md-tab-panels for="analytics-strip">
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Sessions up 18% week over week. Peak traffic Tuesday 14:00.</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">S</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Weekly user growth · Revenue breakdown Q1</div>
</md-tab-panel>
</md-tab-panels>
</div>import { MdTab, MdTabPanel, MdTabPanels, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '500px' }}>
<MdTabs id="analytics-strip" aria-label="Analytics sections">
<MdTab label="Overview"></MdTab>
<MdTab label="Activity"></MdTab>
<MdTab label="Reports" badge="2"></MdTab>
</MdTabs>
<MdTabPanels htmlFor="analytics-strip">
<MdTabPanel>
<div style={{ padding: '16px 4px', font: '14px/1.6 system-ui' }}>Sessions up 18% week over week. Peak traffic Tuesday 14:00.</div>
</MdTabPanel>
<MdTabPanel>
<div style={{ padding: '16px 4px', font: '14px/1.6 system-ui' }}>S</div>
</MdTabPanel>
<MdTabPanel>
<div style={{ padding: '16px 4px', font: '14px/1.6 system-ui' }}>Weekly user growth · Revenue breakdown Q1</div>
</MdTabPanel>
</MdTabPanels>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs id="analytics-strip" aria-label="Analytics sections">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Reports" badge="2"></md-tab>
</md-tabs>
<md-tab-panels for="analytics-strip">
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Sessions up 18% week over week. Peak traffic Tuesday 14:00.</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">S</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Weekly user growth · Revenue breakdown Q1</div>
</md-tab-panel>
</md-tab-panels>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs id="analytics-strip" aria-label="Analytics sections">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Reports" badge="2"></md-tab>
</md-tabs>
<md-tab-panels for="analytics-strip">
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Sessions up 18% week over week. Peak traffic Tuesday 14:00.</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">S</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Weekly user growth · Revenue breakdown Q1</div>
</md-tab-panel>
</md-tab-panels>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 500px;">
<md-tabs id="analytics-strip" aria-label="Analytics sections">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Reports" badge="2"></md-tab>
</md-tabs>
<md-tab-panels for="analytics-strip">
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Sessions up 18% week over week. Peak traffic Tuesday 14:00.</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">S</div>
</md-tab-panel>
<md-tab-panel>
<div style="padding: 16px 4px; font: 14px/1.6 system-ui;">Weekly user growth · Revenue breakdown Q1</div>
</md-tab-panel>
</md-tab-panels>
</div>If you are wiring your own panels instead, they must be in the same DOM
scope as the tabs — controls is an IDREF, and IDREFs don’t cross shadow
boundaries.
| Event | Cancelable | Detail | Fires |
|---|---|---|---|
mdTabChange | no | { index, previousIndex } | The active tab changed — click, keyboard, or selectTab() |
Re-activating the already-active tab does not emit. Out-of-range
selectTab() calls are ignored, and setting activeTabIndex as a property
normalizes (rounds and clamps) without emitting — the property path is
consumer-initiated, so you already know.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-tabs id="strip" aria-label="Project sections">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
<md-tab-panels for="strip">
<md-tab-panel>Overview…</md-tab-panel>
<md-tab-panel>Activity…</md-tab-panel>
<md-tab-panel>Settings…</md-tab-panel>
</md-tab-panels>
<script type="module">
const strip = document.getElementById('strip');
// Fires on click, keyboard, and an in-range selectTab().
strip.addEventListener('mdTabChange', (e) => {
console.log(e.detail.index, e.detail.previousIndex);
});
// None of these emit:
strip.selectTab(strip.activeTabIndex); // already active
strip.selectTab(9); // out of range, ignored
strip.activeTabIndex = 2.7; // property path normalizes silently
</script>import { MdTabs, MdTab, MdTabPanels, MdTabPanel } from '@awc-ui/react';
import { useState } from 'react';
export function ProjectTabs() {
const [index, setIndex] = useState(0);
return (
<>
<MdTabs
id="strip"
aria-label="Project sections"
activeTabIndex={index}
onMdTabChange={(e) => setIndex(e.detail.index)}
>
<MdTab label="Overview" />
<MdTab label="Activity" />
<MdTab label="Settings" />
</MdTabs>
<MdTabPanels for="strip">
<MdTabPanel>Overview…</MdTabPanel>
<MdTabPanel>Activity…</MdTabPanel>
<MdTabPanel>Settings…</MdTabPanel>
</MdTabPanels>
</>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-project-tabs',
template: `
<md-tabs id="strip" aria-label="Project sections" (mdTabChange)="onChange($event)">
<md-tab label="Overview"></md-tab>
<md-tab label="Activity"></md-tab>
<md-tab label="Settings"></md-tab>
</md-tabs>
<md-tab-panels for="strip">
<md-tab-panel>Overview…</md-tab-panel>
<md-tab-panel>Activity…</md-tab-panel>
<md-tab-panel>Settings…</md-tab-panel>
</md-tab-panels>
`,
})
export class ProjectTabsComponent {
onChange(e: CustomEvent<{ index: number; previousIndex: number }>) {
console.log(e.detail.index, e.detail.previousIndex);
}
}<script setup lang="ts">
import { ref } from 'vue';
const index = ref(0);
function onChange(e: CustomEvent) {
index.value = e.detail.index;
}
</script>
<template>
<md-tabs id="strip" aria-label="Project sections" :active-tab-index="index" @mdTabChange="onChange">
<md-tab label="Overview" />
<md-tab label="Activity" />
<md-tab label="Settings" />
</md-tabs>
<md-tab-panels for="strip">
<md-tab-panel>Overview…</md-tab-panel>
<md-tab-panel>Activity…</md-tab-panel>
<md-tab-panel>Settings…</md-tab-panel>
</md-tab-panels>
</template><script lang="ts">
let index = 0;
function onChange(e: CustomEvent) {
index = e.detail.index;
}
</script>
<md-tabs id="strip" aria-label="Project sections" active-tab-index={index} on:mdTabChange={onChange}>
<md-tab label="Overview" />
<md-tab label="Activity" />
<md-tab label="Settings" />
</md-tabs>
<md-tab-panels for="strip">
<md-tab-panel>Overview…</md-tab-panel>
<md-tab-panel>Activity…</md-tab-panel>
<md-tab-panel>Settings…</md-tab-panel>
</md-tab-panels>| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
activeTabIndex | active-tab-index | number | 0 | — |
variant | variant | 'primary' | 'secondary' | 'primary' | Yes |
divider | divider | 'auto' | 'full' | 'auto' | Yes |
ariaLabelProp | aria-label | string | '' | — |
tabWidth | tab-width | string | 'equal' | — |
width | width | string | '' | — |
| Method | Parameters |
|---|---|
selectTab() | index: number |
| Slot | Description |
|---|---|
(default) | — |
Override on the host element for per-instance theming:
| Property | Description |
|---|---|
--md-tabs-container-color | Container background |
--md-tabs-divider-color | Divider color for every child tab's |
Style internal elements through shadow DOM with ::part():
| Part | Description |
|---|---|
container | Scrollable tab container |
A tabbed view is composed from three sub-components. They are documented here rather than on their own pages: none of them mean anything outside a tabbed view, and the strip owns the active index for all of them.
md-tabOne tab in the strip — a label and/or icon, an optional badge, and the active indicator.
inline-icon switches icon+label from stacked to side-by-side.badge="" (empty string) renders a dot badge rather than no badge.md-tabs, md-tab does have a density prop — set density here,
not on the strip.| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
label | label | string | '' | — |
icon | icon | string | '' | — |
active | active | boolean | false | Yes |
disabled | disabled | boolean | false | Yes |
inlineIcon | inline-icon | boolean | false | Yes |
variant | variant | 'primary' | 'secondary' | 'primary' | Yes |
badge | badge | string | undefined | — | — |
controls | controls | string | '' | — |
density | density | 0 | -1 | -2 | -3 | -4 | 0 | Yes |
| Slot | Description |
|---|---|
icon | Custom leading icon |
badge | Badge overlay on the icon |
Override on the host element for per-instance theming:
| Property | Description |
|---|---|
--md-tab-container-color | Container background |
--md-tab-active-label-color | Active label color (primary) |
--md-tab-inactive-label-color | Inactive label color |
--md-tab-active-icon-color | Active icon color (primary) |
--md-tab-inactive-icon-color | Inactive icon color |
--md-tab-active-indicator-color | Indicator bar color |
--md-tab-active-indicator-height | Indicator bar thickness |
--md-tab-divider-color | Bottom divider color |
--md-tab-glide-duration | — |
--md-tab-glide-x | — |
--md-tab-glide-scale | — |
Style internal elements through shadow DOM with ::part():
| Part | Description |
|---|---|
state-layer | Hover / focus / press overlay |
content | Inner content wrapper (icon + label) |
icon | Icon element |
label | Label text element |
indicator | Active indicator bar |
divider | Bottom divider line |
md-tab-panelsThe content half of a tabbed view — holds one
md-tab-panel per tab, follows the strip’s active index, and
controls how the region is sized as panels change.
mdTabChange and sets
active / inert on the panels. You do not toggle active by hand — and
you do not need a mdTabChange listener just to switch panels.aria-controls, each panel gets
aria-labelledby, and ids are auto-assigned where missing. Set your own
id / controls only when you need stable, meaningful ids.for resolves against the panel region’s own root, so the strip must be in the
same DOM scope — IDREFs don’t cross shadow boundaries.md-tab-panel has a density prop.| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
for | for | string | '' | — |
sizing | sizing | 'stable' | 'active' | 'stable' | Yes |
| Slot | Description |
|---|---|
(default) | — |
md-tab-panelThe content of one tab. A single active flag decides whether it is shown;
everything else is your content. The host renders role="tabpanel" and takes a
tabindex of 0 while active, -1 otherwise.
active is the entire API — and the parent owns it.
md-tab-panels sets active and inert from the strip’s
mdTabChange. Setting active yourself fights it, and two active panels is an
ambiguous state.aria-controls / aria-labelledby both ways. Give the
panel a stable id only when you want a meaningful one (deep links, tests) —
and then match it with the tab’s controls in the same DOM scope, because
IDREFs don’t cross shadow boundaries.visibility: hidden and the host is
inert, so it is out of paint, hit-testing and the accessibility tree.density prop.| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
active | active | boolean | false | Yes |
| Slot | Description |
|---|---|
(default) | — |
aria-label naming what the tabs switch between.Home / End to jump to the ends. Arrow direction follows
the visual order, so it inverts under RTL.md-tab-panels does it
for you, otherwise set the tab’s controls to the panel’s id. Both must be
in the same DOM scope — IDREFs don’t cross shadow boundaries.| Key | Action |
|---|---|
Tab | One stop for the whole strip (roving tabindex), then into the active panel |
← / → | Move between enabled tabs, wrapping at the ends (inverted under dir="rtl") |
Home / End | First / last enabled tab |
Enter / Space | Activate the focused tab |
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Account sections">
<md-tab label="Profile" icon="person" active></md-tab>
<md-tab label="Security" icon="lock"></md-tab>
<md-tab label="Billing" icon="credit_card" disabled></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Account sections">
<MdTab label="Profile" icon="person" active></MdTab>
<MdTab label="Security" icon="lock"></MdTab>
<MdTab label="Billing" icon="credit_card" disabled></MdTab>
<MdTab label="Alerts" icon="notifications" badgeValue="3"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Account sections">
<md-tab label="Profile" icon="person" active></md-tab>
<md-tab label="Security" icon="lock"></md-tab>
<md-tab label="Billing" icon="credit_card" disabled></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Account sections">
<md-tab label="Profile" icon="person" active></md-tab>
<md-tab label="Security" icon="lock"></md-tab>
<md-tab label="Billing" icon="credit_card" disabled></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Account sections">
<md-tab label="Profile" icon="person" active></md-tab>
<md-tab label="Security" icon="lock"></md-tab>
<md-tab label="Billing" icon="credit_card" disabled></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>RTL — strip order, indicator travel and arrow-key direction all follow
reading order under dir="rtl". See RTL.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<div dir="ltr">
<md-tabs variant="primary" aria-label="Sections">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
<div dir="rtl">
<md-tabs variant="primary" aria-label="الأقسام">
<md-tab label="الرئيسية" icon="home" active></md-tab>
<md-tab label="بحث" icon="search"></md-tab>
<md-tab label="التنبيهات" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gap: '20px', inlineSize: '100%', maxInlineSize: '460px' }}>
<div dir="ltr">
<MdTabs variant="primary" aria-label="Sections">
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Alerts" icon="notifications" badgeValue="3"></MdTab>
</MdTabs>
</div>
<div dir="rtl">
<MdTabs variant="primary" aria-label="الأقسام">
<MdTab label="الرئيسية" icon="home" active></MdTab>
<MdTab label="بحث" icon="search"></MdTab>
<MdTab label="التنبيهات" icon="notifications" badgeValue="3"></MdTab>
</MdTabs>
</div>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<div dir="ltr">
<md-tabs variant="primary" aria-label="Sections">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
<div dir="rtl">
<md-tabs variant="primary" aria-label="الأقسام">
<md-tab label="الرئيسية" icon="home" active></md-tab>
<md-tab label="بحث" icon="search"></md-tab>
<md-tab label="التنبيهات" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<div dir="ltr">
<md-tabs variant="primary" aria-label="Sections">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
<div dir="rtl">
<md-tabs variant="primary" aria-label="الأقسام">
<md-tab label="الرئيسية" icon="home" active></md-tab>
<md-tab label="بحث" icon="search"></md-tab>
<md-tab label="التنبيهات" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<div dir="ltr">
<md-tabs variant="primary" aria-label="Sections">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
<div dir="rtl">
<md-tabs variant="primary" aria-label="الأقسام">
<md-tab label="الرئيسية" icon="home" active></md-tab>
<md-tab label="بحث" icon="search"></md-tab>
<md-tab label="التنبيهات" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</div>Density — there is no density prop on the strip. Set it on each
md-tab child; the strip height follows the tallest
tab. See Density.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;inline-size:100%;max-inline-size:520px;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-tabs aria-label="d0"><md-tab density="0" label="Home" icon="home" active></md-tab><md-tab density="0" label="Search" icon="search"></md-tab><md-tab density="0" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-tabs aria-label="d-1"><md-tab density="-1" label="Home" icon="home" active></md-tab><md-tab density="-1" label="Search" icon="search"></md-tab><md-tab density="-1" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-tabs aria-label="d-2"><md-tab density="-2" label="Home" icon="home" active></md-tab><md-tab density="-2" label="Search" icon="search"></md-tab><md-tab density="-2" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-tabs aria-label="d-3"><md-tab density="-3" label="Home" icon="home" active></md-tab><md-tab density="-3" label="Search" icon="search"></md-tab><md-tab density="-3" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-tabs aria-label="d-4"><md-tab density="-4" label="Home" icon="home" active></md-tab><md-tab density="-4" label="Search" icon="search"></md-tab><md-tab density="-4" label="Profile" icon="person"></md-tab></md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center', inlineSize: '100%', maxInlineSize: '520px' }}>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>0</span>
<MdTabs aria-label="d0"><MdTab density="0" label="Home" icon="home" active></MdTab><MdTab density="0" label="Search" icon="search"></MdTab><MdTab density="0" label="Profile" icon="person"></MdTab></MdTabs>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-1</span>
<MdTabs aria-label="d-1"><MdTab density="-1" label="Home" icon="home" active></MdTab><MdTab density="-1" label="Search" icon="search"></MdTab><MdTab density="-1" label="Profile" icon="person"></MdTab></MdTabs>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-2</span>
<MdTabs aria-label="d-2"><MdTab density="-2" label="Home" icon="home" active></MdTab><MdTab density="-2" label="Search" icon="search"></MdTab><MdTab density="-2" label="Profile" icon="person"></MdTab></MdTabs>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-3</span>
<MdTabs aria-label="d-3"><MdTab density="-3" label="Home" icon="home" active></MdTab><MdTab density="-3" label="Search" icon="search"></MdTab><MdTab density="-3" label="Profile" icon="person"></MdTab></MdTabs>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-4</span>
<MdTabs aria-label="d-4"><MdTab density="-4" label="Home" icon="home" active></MdTab><MdTab density="-4" label="Search" icon="search"></MdTab><MdTab density="-4" label="Profile" icon="person"></MdTab></MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;inline-size:100%;max-inline-size:520px;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-tabs aria-label="d0"><md-tab density="0" label="Home" icon="home" active></md-tab><md-tab density="0" label="Search" icon="search"></md-tab><md-tab density="0" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-tabs aria-label="d-1"><md-tab density="-1" label="Home" icon="home" active></md-tab><md-tab density="-1" label="Search" icon="search"></md-tab><md-tab density="-1" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-tabs aria-label="d-2"><md-tab density="-2" label="Home" icon="home" active></md-tab><md-tab density="-2" label="Search" icon="search"></md-tab><md-tab density="-2" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-tabs aria-label="d-3"><md-tab density="-3" label="Home" icon="home" active></md-tab><md-tab density="-3" label="Search" icon="search"></md-tab><md-tab density="-3" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-tabs aria-label="d-4"><md-tab density="-4" label="Home" icon="home" active></md-tab><md-tab density="-4" label="Search" icon="search"></md-tab><md-tab density="-4" label="Profile" icon="person"></md-tab></md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;inline-size:100%;max-inline-size:520px;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-tabs aria-label="d0"><md-tab density="0" label="Home" icon="home" active></md-tab><md-tab density="0" label="Search" icon="search"></md-tab><md-tab density="0" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-tabs aria-label="d-1"><md-tab density="-1" label="Home" icon="home" active></md-tab><md-tab density="-1" label="Search" icon="search"></md-tab><md-tab density="-1" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-tabs aria-label="d-2"><md-tab density="-2" label="Home" icon="home" active></md-tab><md-tab density="-2" label="Search" icon="search"></md-tab><md-tab density="-2" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-tabs aria-label="d-3"><md-tab density="-3" label="Home" icon="home" active></md-tab><md-tab density="-3" label="Search" icon="search"></md-tab><md-tab density="-3" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-tabs aria-label="d-4"><md-tab density="-4" label="Home" icon="home" active></md-tab><md-tab density="-4" label="Search" icon="search"></md-tab><md-tab density="-4" label="Profile" icon="person"></md-tab></md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;inline-size:100%;max-inline-size:520px;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-tabs aria-label="d0"><md-tab density="0" label="Home" icon="home" active></md-tab><md-tab density="0" label="Search" icon="search"></md-tab><md-tab density="0" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-tabs aria-label="d-1"><md-tab density="-1" label="Home" icon="home" active></md-tab><md-tab density="-1" label="Search" icon="search"></md-tab><md-tab density="-1" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-tabs aria-label="d-2"><md-tab density="-2" label="Home" icon="home" active></md-tab><md-tab density="-2" label="Search" icon="search"></md-tab><md-tab density="-2" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-tabs aria-label="d-3"><md-tab density="-3" label="Home" icon="home" active></md-tab><md-tab density="-3" label="Search" icon="search"></md-tab><md-tab density="-3" label="Profile" icon="person"></md-tab></md-tabs>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-tabs aria-label="d-4"><md-tab density="-4" label="Home" icon="home" active></md-tab><md-tab density="-4" label="Search" icon="search"></md-tab><md-tab density="-4" label="Profile" icon="person"></md-tab></md-tabs>
</div>i18n — translate tab labels. Translations change tab widths, which matters
under tab-width="equal"; re-check for truncation per locale.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs variant="primary" aria-label="Kontobereiche">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
<md-tabs variant="primary" tab-width="auto" aria-label="Kontobereiche, auto">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gap: '20px', inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Kontobereiche">
<MdTab label="Profil" icon="person" active></MdTab>
<MdTab label="Sicherheit" icon="lock"></MdTab>
<MdTab label="Abrechnung" icon="credit_card"></MdTab>
</MdTabs>
<MdTabs variant="primary" tabWidth="auto" aria-label="Kontobereiche, auto">
<MdTab label="Profil" icon="person" active></MdTab>
<MdTab label="Sicherheit" icon="lock"></MdTab>
<MdTab label="Abrechnung" icon="credit_card"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs variant="primary" aria-label="Kontobereiche">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
<md-tabs variant="primary" tab-width="auto" aria-label="Kontobereiche, auto">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs variant="primary" aria-label="Kontobereiche">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
<md-tabs variant="primary" tab-width="auto" aria-label="Kontobereiche, auto">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs variant="primary" aria-label="Kontobereiche">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
<md-tabs variant="primary" tab-width="auto" aria-label="Kontobereiche, auto">
<md-tab label="Profil" icon="person" active></md-tab>
<md-tab label="Sicherheit" icon="lock"></md-tab>
<md-tab label="Abrechnung" icon="credit_card"></md-tab>
</md-tabs>
</div>| Custom property | Purpose | Default |
|---|---|---|
--md-tabs-container-color | Strip background | surface |
--md-tabs-divider-color | Rule under the strip — read by each child tab’s own divider default | outline-variant |
Per-tab appearance (label colour, icon colour, indicator) uses the --md-tab-*
properties documented on md-tab.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Themed tabs" style="--md-tabs-container-color: var(--md-sys-color-surface-container-highest); --md-tabs-divider-color: var(--md-sys-color-primary);">
<md-tab label="Home" icon="home"></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Themed tabs" style={{ '--md-tabs-container-color': 'var(--md-sys-color-surface-container-highest)', '--md-tabs-divider-color': 'var(--md-sys-color-primary)' }}>
<MdTab label="Home" icon="home"></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Profile" icon="person"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Themed tabs" style="--md-tabs-container-color: var(--md-sys-color-surface-container-highest); --md-tabs-divider-color: var(--md-sys-color-primary);">
<md-tab label="Home" icon="home"></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Themed tabs" style="--md-tabs-container-color: var(--md-sys-color-surface-container-highest); --md-tabs-divider-color: var(--md-sys-color-primary);">
<md-tab label="Home" icon="home"></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Themed tabs" style="--md-tabs-container-color: var(--md-sys-color-surface-container-highest); --md-tabs-divider-color: var(--md-sys-color-primary);">
<md-tab label="Home" icon="home"></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>Every default resolves through an md-sys-color role, so a strip that sets no
custom properties follows the theme on its own:
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Untouched defaults">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs variant="primary" aria-label="Untouched defaults">
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Alerts" icon="notifications" badgeValue="3"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Untouched defaults">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Untouched defaults">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs variant="primary" aria-label="Untouched defaults">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Alerts" icon="notifications" badge-value="3"></md-tab>
</md-tabs>
</div>| Custom property | On | Purpose |
|---|---|---|
--md-tab-active-label-color / -inactive-label-color | md-tab | Label colour |
--md-tab-active-icon-color / -inactive-icon-color | md-tab | Glyph colour |
--md-tab-active-indicator-color / -height | md-tab | The indicator bar |
--md-tab-container-color | md-tab | The tab’s own background |
--md-tab-divider-color | md-tab | The rule under this tab |
--md-tab-glide-duration / -glide-scale / -glide-x | md-tab | Indicator travel motion |
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs aria-label="Tonal" style="--md-tab-active-indicator-color: var(--md-sys-color-tertiary); --md-tab-active-label-color: var(--md-sys-color-tertiary); --md-tab-active-icon-color: var(--md-sys-color-tertiary);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Thick indicator" style="--md-tab-active-indicator-height: 6px; --md-tab-active-indicator-color: #7c4dff; --md-tab-active-label-color: #311b92;">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Filled strip" style="--md-tabs-container-color: var(--md-sys-color-secondary-container); --md-tabs-divider-color: transparent; --md-tab-active-label-color: var(--md-sys-color-on-secondary-container); --md-tab-active-indicator-color: var(--md-sys-color-on-secondary-container);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gap: '20px', inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs aria-label="Tonal" style={{ '--md-tab-active-indicator-color': 'var(--md-sys-color-tertiary)', '--md-tab-active-label-color': 'var(--md-sys-color-tertiary)', '--md-tab-active-icon-color': 'var(--md-sys-color-tertiary)' }}>
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Profile" icon="person"></MdTab>
</MdTabs>
<MdTabs aria-label="Thick indicator" style={{ '--md-tab-active-indicator-height': '6px', '--md-tab-active-indicator-color': '#7c4dff', '--md-tab-active-label-color': '#311b92' }}>
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Profile" icon="person"></MdTab>
</MdTabs>
<MdTabs aria-label="Filled strip" style={{ '--md-tabs-container-color': 'var(--md-sys-color-secondary-container)', '--md-tabs-divider-color': 'transparent', '--md-tab-active-label-color': 'var(--md-sys-color-on-secondary-container)', '--md-tab-active-indicator-color': 'var(--md-sys-color-on-secondary-container)' }}>
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Profile" icon="person"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs aria-label="Tonal" style="--md-tab-active-indicator-color: var(--md-sys-color-tertiary); --md-tab-active-label-color: var(--md-sys-color-tertiary); --md-tab-active-icon-color: var(--md-sys-color-tertiary);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Thick indicator" style="--md-tab-active-indicator-height: 6px; --md-tab-active-indicator-color: #7c4dff; --md-tab-active-label-color: #311b92;">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Filled strip" style="--md-tabs-container-color: var(--md-sys-color-secondary-container); --md-tabs-divider-color: transparent; --md-tab-active-label-color: var(--md-sys-color-on-secondary-container); --md-tab-active-indicator-color: var(--md-sys-color-on-secondary-container);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs aria-label="Tonal" style="--md-tab-active-indicator-color: var(--md-sys-color-tertiary); --md-tab-active-label-color: var(--md-sys-color-tertiary); --md-tab-active-icon-color: var(--md-sys-color-tertiary);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Thick indicator" style="--md-tab-active-indicator-height: 6px; --md-tab-active-indicator-color: #7c4dff; --md-tab-active-label-color: #311b92;">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Filled strip" style="--md-tabs-container-color: var(--md-sys-color-secondary-container); --md-tabs-divider-color: transparent; --md-tab-active-label-color: var(--md-sys-color-on-secondary-container); --md-tab-active-indicator-color: var(--md-sys-color-on-secondary-container);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display:grid;gap:20px;inline-size:100%;max-inline-size:460px;">
<md-tabs aria-label="Tonal" style="--md-tab-active-indicator-color: var(--md-sys-color-tertiary); --md-tab-active-label-color: var(--md-sys-color-tertiary); --md-tab-active-icon-color: var(--md-sys-color-tertiary);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Thick indicator" style="--md-tab-active-indicator-height: 6px; --md-tab-active-indicator-color: #7c4dff; --md-tab-active-label-color: #311b92;">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
<md-tabs aria-label="Filled strip" style="--md-tabs-container-color: var(--md-sys-color-secondary-container); --md-tabs-divider-color: transparent; --md-tab-active-label-color: var(--md-sys-color-on-secondary-container); --md-tab-active-indicator-color: var(--md-sys-color-on-secondary-container);">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>| Part | On | Element |
|---|---|---|
container | md-tabs | The scrollable tab container |
content | md-tab | Icon + label wrapper |
icon | md-tab | The glyph |
label | md-tab | Label text |
indicator | md-tab | The active bar |
divider | md-tab | This tab’s slice of the rule under the strip |
state-layer | md-tab | Hover / focus / press overlay |
md-tab-panels and md-tab-panel expose no parts — they are layout and
plumbing, with nothing of their own to paint.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.parts-tabs::part(container) { padding-inline-start: 16px; }
.parts-tabs md-tab::part(label) { text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.parts-tabs md-tab::part(indicator) { border-radius: 999px; }
.parts-tabs md-tab::part(divider) { background: var(--md-sys-color-primary); opacity: .25; }
</style>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs class="parts-tabs" aria-label="Styled parts">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdTab, MdTabs } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.parts-tabs::part(container) { padding-inline-start: 16px; }
.parts-tabs md-tab::part(label) { text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.parts-tabs md-tab::part(indicator) { border-radius: 999px; }
.parts-tabs md-tab::part(divider) { background: var(--md-sys-color-primary); opacity: .25; }
</style>
<div style={{ inlineSize: '100%', maxInlineSize: '460px' }}>
<MdTabs className="parts-tabs" aria-label="Styled parts">
<MdTab label="Home" icon="home" active></MdTab>
<MdTab label="Search" icon="search"></MdTab>
<MdTab label="Profile" icon="person"></MdTab>
</MdTabs>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.parts-tabs::part(container) { padding-inline-start: 16px; }
.parts-tabs md-tab::part(label) { text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.parts-tabs md-tab::part(indicator) { border-radius: 999px; }
.parts-tabs md-tab::part(divider) { background: var(--md-sys-color-primary); opacity: .25; }
</style>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs class="parts-tabs" aria-label="Styled parts">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<style>
.parts-tabs::part(container) { padding-inline-start: 16px; }
.parts-tabs md-tab::part(label) { text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.parts-tabs md-tab::part(indicator) { border-radius: 999px; }
.parts-tabs md-tab::part(divider) { background: var(--md-sys-color-primary); opacity: .25; }
</style>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs class="parts-tabs" aria-label="Styled parts">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<style>
.parts-tabs::part(container) { padding-inline-start: 16px; }
.parts-tabs md-tab::part(label) { text-transform: uppercase; letter-spacing: .08em; font-size: 11px; }
.parts-tabs md-tab::part(indicator) { border-radius: 999px; }
.parts-tabs md-tab::part(divider) { background: var(--md-sys-color-primary); opacity: .25; }
</style>
<div style="inline-size: 100%; max-inline-size: 460px;">
<md-tabs class="parts-tabs" aria-label="Styled parts">
<md-tab label="Home" icon="home" active></md-tab>
<md-tab label="Search" icon="search"></md-tab>
<md-tab label="Profile" icon="person"></md-tab>
</md-tabs>
</div>md-tabs::part(container) { padding-inline-start: 16px; /* M3: offset the first scrollable tab */}md-tab ·
md-tab-panels ·
md-tab-panel ·
md-navigation-bar ·
md-navigation-rail ·
md-stepper ·
md-segmented-button ·
md-accordion
md-tabsTwo artefacts to give your AI agent so it generates correct UI with this component. The per-component spec answers "how do I use this exact tag?". The main-llm spec answers "which tag should I pick in the first place?".
md-tabs spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
System-prompt preamble · decision matrix · token reference · page recipes · anti-patterns. Paste into the system prompt at the start of a piece of work.