docs: aria tabs examples

(cherry picked from commit 04859b41a2)
This commit is contained in:
Wagner Maciel 2025-11-17 23:42:48 -05:00 committed by Jessica Janiuk
parent 363bcb311c
commit 903cb23df9
41 changed files with 1594 additions and 59 deletions

View file

@ -1,9 +0,0 @@
h1 {
background: #1e1e1e;
color: #e0e0e0;
padding: 2rem;
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
font-size: 2rem;
text-align: center;
}

View file

@ -1 +0,0 @@
<h1>PLACEHOLDER</h1>

View file

@ -0,0 +1,84 @@
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
border: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 0.75rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab][aria-disabled='true'] {
cursor: default;
color: color-mix(in srgb, var(--primary-contrast) 30%, transparent);
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab][aria-selected='false']:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab][aria-disabled='false'][aria-selected='false']:hover {
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
border-bottom-right-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,21 @@
<div ngTabs>
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes" disabled>Reviews</div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -1,8 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,103 @@
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 20%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab][aria-disabled='true'] {
cursor: default;
color: color-mix(in srgb, var(--primary-contrast) 30%, transparent);
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab]:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--bright-blue);
}
.bottom-border {
position: absolute;
pointer-events: none;
left: 0;
bottom: 0;
height: 3px;
width: calc(100% / 3);
background-color: var(--bright-blue);
transition: all 0.2s ease-in-out;
transform: translateX(0%);
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
[ngTab]:nth-child(1)[aria-selected='true'] ~ .bottom-border {
transform: translateX(0%);
}
[ngTab]:nth-child(2)[aria-selected='true'] ~ .bottom-border {
transform: translateX(100%);
}
[ngTab]:nth-child(3)[aria-selected='true'] ~ .bottom-border {
transform: translateX(200%);
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,22 @@
<div ngTabs class="material-tabs">
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes" disabled>Reviews</div>
<div class="bottom-border"></div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -1,8 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,106 @@
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: var(--bright-blue);
--retro-shadow-light: color-mix(in srgb, #fff 20%, transparent);
--retro-shadow-dark: color-mix(in srgb, #000 20%, transparent);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700);
--retro-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 8px 8px 0px 0px var(--gray-700);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 0px 0px 0px 0px var(--gray-700);
}
[ngTabs] {
width: 600px;
}
[ngTabList] {
gap: 1rem;
display: flex;
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem;
cursor: pointer;
text-align: center;
color: #000;
background-color: #fff;
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngTab][aria-disabled='true'] {
cursor: default;
color: color-mix(in srgb, #000 30%, transparent);
}
[ngTab][aria-disabled='false'][aria-selected='false']:focus,
[ngTab][aria-disabled='false'][aria-selected='false']:hover {
transform: translate(1px, 1px);
}
[ngTab]:focus {
outline-offset: 2px;
outline: 4px dashed var(--bright-blue);
}
[ngTab][aria-disabled='false'][aria-selected='false']:hover {
background-color: color-mix(in srgb, var(--bright-blue) 50%, #fff);
}
[ngTab][aria-disabled='false']:active,
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
box-shadow: var(--retro-pressed-shadow);
transform: translate(4px, 4px);
}
[ngTabPanel] {
flex: 1;
font-size: 1.5rem;
color: #000;
background-color: #fff;
padding: 1rem;
margin-top: 1rem;
min-height: 100px;
display: grid;
place-items: center;
box-shadow: var(--retro-flat-shadow);
background: linear-gradient(rgba(0, 0, 0, 0.3) 50%, rgba(0, 0, 0, 0.1) 50%);
background-color: color-mix(in srgb, var(--bright-blue) 10%, #fff);
background-size: 100% 4px;
}
[ngTabPanel]:focus {
outline-offset: 4px;
outline: 4px dashed var(--bright-blue);
}
[ngTabPanel][inert] {
display: none;
}

View file

@ -0,0 +1,19 @@
<div ngTabs class="retro-tabs">
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes" disabled>Reviews</div>
</div>
<div ngTabPanel value="movie">
<ng-template ngTabContent>Line 1</ng-template>
</div>
<div ngTabPanel value="theatres">
<ng-template ngTabContent>Line 2</ng-template>
</div>
<div ngTabPanel value="showtimes">
<ng-template ngTabContent>Line 3</ng-template>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -1,9 +1,78 @@
h1 {
background: #1e1e1e;
color: #e0e0e0;
padding: 2rem;
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
font-size: 2rem;
text-align: center;
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
border: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 0.75rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab][aria-selected='false']:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
border-bottom-right-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -1 +1,21 @@
<h1>PLACEHOLDER</h1>
<div ngTabs>
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -1,8 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,97 @@
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 20%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab]:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--bright-blue);
}
.bottom-border {
position: absolute;
pointer-events: none;
left: 0;
bottom: 0;
height: 3px;
width: calc(100% / 3);
background-color: var(--bright-blue);
transition: all 0.2s ease-in-out;
transform: translateX(0%);
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
[ngTab]:nth-child(1)[aria-selected='true'] ~ .bottom-border {
transform: translateX(0%);
}
[ngTab]:nth-child(2)[aria-selected='true'] ~ .bottom-border {
transform: translateX(100%);
}
[ngTab]:nth-child(3)[aria-selected='true'] ~ .bottom-border {
transform: translateX(200%);
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,22 @@
<div ngTabs class="material-tabs">
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
<div class="bottom-border"></div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,101 @@
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: var(--bright-blue);
--retro-shadow-light: color-mix(in srgb, #fff 20%, transparent);
--retro-shadow-dark: color-mix(in srgb, #000 20%, transparent);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700);
--retro-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 8px 8px 0px 0px var(--gray-700);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 0px 0px 0px 0px var(--gray-700);
}
[ngTabs] {
width: 600px;
}
[ngTabList] {
gap: 1rem;
display: flex;
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem;
cursor: pointer;
text-align: center;
color: #000;
background-color: #fff;
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngTab]:focus,
[ngTab]:hover {
transform: translate(1px, 1px);
}
[ngTab]:focus {
outline-offset: 2px;
outline: 4px dashed var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 50%, #fff);
}
[ngTab]:active,
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
box-shadow: var(--retro-pressed-shadow);
transform: translate(4px, 4px);
}
[ngTabPanel] {
flex: 1;
font-size: 1.5rem;
color: #000;
background-color: #fff;
padding: 1rem;
margin-top: 1rem;
min-height: 100px;
display: grid;
place-items: center;
box-shadow: var(--retro-flat-shadow);
background: linear-gradient(rgba(0, 0, 0, 0.3) 50%, rgba(0, 0, 0, 0.1) 50%);
background-color: color-mix(in srgb, var(--bright-blue) 10%, #fff);
background-size: 100% 4px;
}
[ngTabPanel]:focus {
outline-offset: 4px;
outline: 4px dashed var(--bright-blue);
}
[ngTabPanel][inert] {
display: none;
}

View file

@ -0,0 +1,19 @@
<div ngTabs class="retro-tabs">
<div ngTabList selectionMode="explicit" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
</div>
<div ngTabPanel value="movie">
<ng-template ngTabContent>Line 1</ng-template>
</div>
<div ngTabPanel value="theatres">
<ng-template ngTabContent>Line 2</ng-template>
</div>
<div ngTabPanel value="showtimes">
<ng-template ngTabContent>Line 3</ng-template>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -1,9 +1,78 @@
h1 {
background: #1e1e1e;
color: #e0e0e0;
padding: 2rem;
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
font-size: 2rem;
text-align: center;
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
border: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 0.75rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab][aria-selected='false']:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
border-bottom-right-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -1 +1,21 @@
<h1>PLACEHOLDER</h1>
<div ngTabs>
<div ngTabList selectionMode="follow" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -1,8 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,97 @@
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
border-radius: 0.5rem;
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTabList] {
padding: 0;
display: flex;
list-style: none;
position: relative;
border-bottom: 1px solid color-mix(in srgb, var(--primary-contrast) 20%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem 0;
cursor: pointer;
text-align: center;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
}
[ngTab]:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--bright-blue);
}
.bottom-border {
position: absolute;
pointer-events: none;
left: 0;
bottom: 0;
height: 3px;
width: calc(100% / 3);
background-color: var(--bright-blue);
transition: all 0.2s ease-in-out;
transform: translateX(0%);
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
[ngTab]:nth-child(1)[aria-selected='true'] ~ .bottom-border {
transform: translateX(0%);
}
[ngTab]:nth-child(2)[aria-selected='true'] ~ .bottom-border {
transform: translateX(100%);
}
[ngTab]:nth-child(3)[aria-selected='true'] ~ .bottom-border {
transform: translateX(200%);
}
.sliding-window {
width: 300%;
display: flex;
transition: all 0.2s ease-in-out;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateX(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateX(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
min-height: 100px;
flex: 1;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,22 @@
<div ngTabs class="material-tabs">
<div ngTabList selectionMode="follow" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
<div class="bottom-border"></div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,101 @@
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: var(--bright-blue);
--retro-shadow-light: color-mix(in srgb, #fff 20%, transparent);
--retro-shadow-dark: color-mix(in srgb, #000 20%, transparent);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700);
--retro-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 8px 8px 0px 0px var(--gray-700);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 0px 0px 0px 0px var(--gray-700);
}
[ngTabs] {
width: 600px;
}
[ngTabList] {
gap: 1rem;
display: flex;
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem;
cursor: pointer;
text-align: center;
color: #000;
background-color: #fff;
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngTab]:focus,
[ngTab]:hover {
transform: translate(1px, 1px);
}
[ngTab]:focus {
outline-offset: 2px;
outline: 4px dashed var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 50%, #fff);
}
[ngTab]:active,
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
box-shadow: var(--retro-pressed-shadow);
transform: translate(4px, 4px);
}
[ngTabPanel] {
flex: 1;
font-size: 1.5rem;
color: #000;
background-color: #fff;
padding: 1rem;
margin-top: 1rem;
min-height: 100px;
display: grid;
place-items: center;
box-shadow: var(--retro-flat-shadow);
background: linear-gradient(rgba(0, 0, 0, 0.3) 50%, rgba(0, 0, 0, 0.1) 50%);
background-color: color-mix(in srgb, var(--bright-blue) 10%, #fff);
background-size: 100% 4px;
}
[ngTabPanel]:focus {
outline-offset: 4px;
outline: 4px dashed var(--bright-blue);
}
[ngTabPanel][inert] {
display: none;
}

View file

@ -0,0 +1,19 @@
<div ngTabs class="retro-tabs">
<div ngTabList selectionMode="follow" selectedTab="movie">
<div ngTab value="movie">Movie</div>
<div ngTab value="theatres">Cast</div>
<div ngTab value="showtimes">Reviews</div>
</div>
<div ngTabPanel value="movie">
<ng-template ngTabContent>Line 1</ng-template>
</div>
<div ngTabPanel value="theatres">
<ng-template ngTabContent>Line 2</ng-template>
</div>
<div ngTabPanel value="showtimes">
<ng-template ngTabContent>Line 3</ng-template>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -1,9 +0,0 @@
h1 {
background: #1e1e1e;
color: #e0e0e0;
padding: 2rem;
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
font-size: 2rem;
text-align: center;
}

View file

@ -1 +0,0 @@
<h1>PLACEHOLDER</h1>

View file

@ -0,0 +1,83 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
font-family: var(--inter-font);
display: flex;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
height: 200px;
border-radius: 0.5rem;
border: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
display: flex;
}
[ngTabList] {
padding: 0;
display: flex;
flex-direction: column;
list-style: none;
position: relative;
border-right: 1px solid color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
width: 80px;
cursor: pointer;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
display: grid;
place-items: center;
}
[ngTab][aria-selected='false']:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
border-top-left-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
}
.sliding-window {
height: 300%;
display: flex;
flex-direction: column;
transition: all 0.2s ease-in-out;
flex: 1;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateY(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateY(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateY(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
flex: 1;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,21 @@
<div ngTabs>
<div ngTabList orientation="vertical" selectedTab="movie">
<div ngTab value="movie"><span class="material-symbols-outlined">videocam</span></div>
<div ngTab value="theatres"><span class="material-symbols-outlined">theater_comedy</span></div>
<div ngTab value="showtimes"><span class="material-symbols-outlined">reviews</span></div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,104 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
font-family: var(--inter-font);
display: flex;;
justify-content: center;
}
[ngTabs] {
overflow: hidden;
width: 600px;
height: 200px;
border-radius: 0.5rem;
background-color: color-mix(in srgb, var(--bright-blue) 5%, transparent);
display: flex;
}
[ngTabList] {
padding: 0;
display: flex;
flex-direction: column;
list-style: none;
position: relative;
border-right: 1px solid color-mix(in srgb, var(--primary-contrast) 20%, transparent);
}
[ngTab] {
flex: 1;
outline: none;
width: 80px;
cursor: pointer;
color: color-mix(in srgb, var(--primary-contrast) 60%, transparent);
display: grid;
place-items: center;
}
[ngTab]:focus {
outline-offset: -8px;
border-radius: 0.7rem;
outline: 2px solid var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngTab][aria-selected='true'] {
color: var(--bright-blue);
}
.bottom-border {
position: absolute;
pointer-events: none;
top: 0;
right: 0;
width: 3px;
height: calc(100% / 3);
background-color: var(--bright-blue);
transition: all 0.2s ease-in-out;
transform: translateY(0%);
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
[ngTab]:nth-child(1)[aria-selected='true'] ~ .bottom-border {
transform: translateY(0%);
}
[ngTab]:nth-child(2)[aria-selected='true'] ~ .bottom-border {
transform: translateY(100%);
}
[ngTab]:nth-child(3)[aria-selected='true'] ~ .bottom-border {
transform: translateY(200%);
}
.sliding-window {
height: 300%;
display: flex;
flex-direction: column;
transition: all 0.2s ease-in-out;
flex: 1;
}
[ngTabList]:has([ngTab]:nth-child(1)[aria-selected='true']) ~ .sliding-window {
transform: translateY(0%);
}
[ngTabList]:has([ngTab]:nth-child(2)[aria-selected='true']) ~ .sliding-window {
transform: translateY(-33.333%);
}
[ngTabList]:has([ngTab]:nth-child(3)[aria-selected='true']) ~ .sliding-window {
transform: translateY(-66.666%);
}
[ngTabPanel] {
display: grid;
place-items: center;
padding: 1rem;
flex: 1;
}
[ngTabPanel]:focus {
outline-offset: -4px;
border-radius: 0.5rem;
outline: 2px solid var(--bright-blue);
}

View file

@ -0,0 +1,22 @@
<div ngTabs>
<div ngTabList class="material-tabs" orientation="vertical" selectedTab="movie">
<div ngTab value="movie"><span class="material-symbols-outlined">videocam</span></div>
<div ngTab value="theatres"><span class="material-symbols-outlined">theater_comedy</span></div>
<div ngTab value="showtimes"><span class="material-symbols-outlined">reviews</span></div>
<div class="bottom-border"></div>
</div>
<div class="sliding-window">
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Panel 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Panel 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Panel 3</ng-template>
</div>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -0,0 +1,103 @@
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: var(--bright-blue);
--retro-shadow-light: color-mix(in srgb, #fff 20%, transparent);
--retro-shadow-dark: color-mix(in srgb, #000 20%, transparent);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700);
--retro-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 8px 8px 0px 0px var(--gray-700);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--gray-700),
0px 4px 0px 0px var(--gray-700), -4px 0px 0px 0px var(--gray-700),
0px -4px 0px 0px var(--gray-700), 0px 0px 0px 0px var(--gray-700);
}
[ngTabs] {
width: 500px;
display: flex;
}
[ngTabList] {
gap: 1rem;
display: flex;
flex-direction: column;
}
[ngTab] {
flex: 1;
outline: none;
padding: 1rem 1.5rem;
cursor: pointer;
text-align: center;
color: #000;
background-color: #fff;
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngTab]:focus,
[ngTab]:hover {
transform: translate(1px, 1px);
}
[ngTab]:focus {
outline-offset: 2px;
outline: 4px dashed var(--bright-blue);
}
[ngTab]:hover {
background-color: color-mix(in srgb, var(--bright-blue) 50%, #fff);
}
[ngTab]:active,
[ngTab][aria-selected='true'] {
color: var(--page-background);
background-color: var(--bright-blue);
box-shadow: var(--retro-pressed-shadow);
transform: translate(4px, 4px);
}
[ngTabPanel] {
flex: 1;
font-size: 1.5rem;
color: #000;
background-color: #fff;
padding: 1rem;
margin-left: 1rem;
min-width: 100px;
display: grid;
place-items: center;
box-shadow: var(--retro-flat-shadow);
background: linear-gradient(rgba(0, 0, 0, 0.3) 50%, rgba(0, 0, 0, 0.1) 50%);
background-color: color-mix(in srgb, var(--bright-blue) 10%, #fff);
background-size: 100% 4px;
}
[ngTabPanel]:focus {
outline-offset: 4px;
outline: 4px dashed var(--bright-blue);
}
[ngTabPanel][inert] {
display: none;
}

View file

@ -0,0 +1,19 @@
<div ngTabs class="retro-tabs">
<div ngTabList orientation="vertical" selectedTab="movie">
<div ngTab value="movie"><span class="material-symbols-outlined">videocam</span></div>
<div ngTab value="theatres"><span class="material-symbols-outlined">theater_comedy</span></div>
<div ngTab value="showtimes"><span class="material-symbols-outlined">reviews</span></div>
</div>
<div ngTabPanel [preserveContent]="true" value="movie">
<ng-template ngTabContent>Line 1</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="theatres">
<ng-template ngTabContent>Line 2</ng-template>
</div>
<div ngTabPanel [preserveContent]="true" value="showtimes">
<ng-template ngTabContent>Line 3</ng-template>
</div>
</div>

View file

@ -0,0 +1,10 @@
import {Component} from '@angular/core';
import {Tab, Tabs, TabList, TabPanel, TabContent} from '@angular/aria/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [TabList, Tab, Tabs, TabPanel, TabContent],
})
export class App {}

View file

@ -5,11 +5,31 @@
Tabs display layered content sections where only one panel is visible at a time. Users switch between panels by clicking tab buttons or using arrow keys to navigate the tab list.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.css"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
<docs-pill-row>
<docs-pill href="https://www.w3.org/WAI/ARIA/apg/patterns/tabs/" title="ARIA pattern"/>
@ -51,10 +71,31 @@ Tabs work well for organizing related content into distinct sections where users
When selection follows focus, tabs activate immediately as you navigate with arrow keys. This provides instant feedback and works well for lightweight content.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.html"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/selection-follows-focus/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
Set `[selectionMode]="'follow'"` on the tab list to enable this behavior.
@ -62,10 +103,31 @@ Set `[selectionMode]="'follow'"` on the tab list to enable this behavior.
With manual activation, arrow keys move focus between tabs without changing the selected tab. Users press Space or Enter to activate the focused tab.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.html"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/explicit-selection/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/explicit-selection/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/explicit-selection/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/explicit-selection/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/explicit-selection/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/explicit-selection/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/explicit-selection/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/explicit-selection/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/explicit-selection/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
Use `[selectionMode]="'explicit'"` for heavy content panels to avoid unnecessary rendering.
@ -73,10 +135,31 @@ Use `[selectionMode]="'explicit'"` for heavy content panels to avoid unnecessary
Arrange tabs vertically for interfaces like settings panels or navigation sidebars.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/vertical-orientation/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/vertical-orientation/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/vertical-orientation/app/app.html"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/vertical/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/vertical/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/vertical/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/vertical/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/vertical/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/vertical/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/vertical/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/vertical/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/vertical/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/vertical/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/vertical/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/vertical/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
Set `[orientation]="'vertical'"` on the tab list. Navigation changes to Up/Down arrow keys.
@ -113,10 +196,31 @@ By default, content remains in the DOM after the panel is hidden. Set `[preserve
Disable specific tabs to prevent user interaction. Control whether disabled tabs can receive keyboard focus.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/disabled-focusable/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/disabled-focusable/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/disabled-focusable/app/app.html"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/disabled/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/disabled/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/disabled/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/disabled/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/disabled/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/disabled/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/disabled/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/disabled/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/tabs/src/disabled/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/tabs/src/disabled/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/tabs/src/disabled/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/tabs/src/disabled/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
When `[softDisabled]="true"` on the tab list, disabled tabs can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled tabs are skipped during keyboard navigation.