Tabs
View .mdA tablist allows people to switch between categories of related information without going to different pages.
Default
Loading interactive example. Full source is available below.
View example source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import * as React from 'react';
export const Default = () => {
return (<TabList>
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2">Second Tab</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</TabList>);
};
export default Default;
Resources
Best practices
Do
- Use tabs for distinct but related content categories or a small set of closely related pages.
- Ensure one tab is active on initial render.
- Keep labels brief and grammatically and conceptually parallel.
Don't
- Use tabs for navigation beyond closely related categories; use links.
- Use tabs to initiate actions; use buttons.
- Expect horizontal tabs to scroll or wrap.
Behavior and states
- One tab, usually the first, should always be active on first render.
- Horizontal tabs don’t scroll or wrap to the next line.
- Use an overflow menu button when the container can’t show every tab.
- Icon-only tabs require an aria-label and a tooltip.
- Identify the current selection to screen readers using aria-current.
- Vertical tablists place tabs in a column.
- When space is limited, consider an accordion or dropdown instead.
- Use one consistent label format for every tab in the tablist.
- They’re are ideal for dividing content-heavy pages into distinct but related categories that are easier to process and require less scrolling.
- Tabs can also be used for navigation between a small set of closely related, frequently accessed pages.
- For navigation beyond closely related categories, use a link instead.
- To initiate an action, use a button instead.
API referenceGenerated CoreAI prop and type summaries
API
Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.
TabList API
interface TabListProps {
/**
* A tab list can supports 'transparent' and 'subtle' appearance.
* - 'subtle': Minimizes emphasis to blend into the background until hovered or focused.
* - 'transparent': No background and border styling
* - 'subtle-circular': Adds background and border styling
* - 'filled-circular': Adds background styling
* - 'elevated': Adds background around all tabs for visual grouping
*
* The appearance affects each of the contained tabs.
* @default 'transparent'
*/
appearance?: "subtle" | "transparent" | "elevated" | "subtle-circular" | "filled-circular";
as?: "div";
children?: any;
className?: string;
/**
* The value of the tab to be selected by default.
* Typically useful when the selectedValue is uncontrolled.
*/
defaultSelectedValue?: unknown;
/**
* A tab list can be set to disable interaction.
* @default false
*/
disabled?: boolean;
/**
* Raised when a tab is selected.
*/
onTabSelect?: SelectTabEventHandler;
ref?: Ref<HTMLDivElement>;
/**
* Tab size may change between unselected and selected states.
* The default scenario is a selected tab has bold text.
*
* When true, this property requests tabs be the same size whether unselected or selected.
* @default true
*/
reserveSelectedTabSpace?: boolean;
/**
* The value of the currently selected tab.
*/
selectedValue?: unknown;
/**
* When true, focusing a tab will select it.
* @default false
*/
selectTabOnFocus?: boolean;
/**
* A tab list can be either 'small', 'medium', or 'large' size.
* The size affects each of the contained tabs.
* @default 'medium'
*/
size?: "small" | "medium" | "large";
style?: CSSProperties;
/**
* A tab list can arrange its tabs vertically.
* @default false
*/
vertical?: boolean;
}
Tab API
A tab provides a selectable item in a tab list.
interface TabProps {
as?: "button";
children?: any;
className?: string;
/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible.
*/
content?: NonNullable<WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null> | undefined;
/**
* A tab can be set to disable interaction.
* @default false
*/
disabled?: boolean;
/**
* Icon that renders before the content.
*/
icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
ref?: Ref<HTMLButtonElement>;
style?: CSSProperties;
/**
* The value that identifies this tab when selected.
*/
value: unknown;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.
Appearance
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
export const Appearance = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab value="tab1">First Tab</Tab>
<Tab disabled value="tab2">
Second Tab
</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab3" appearance="transparent">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab3" appearance="subtle">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab3" appearance="subtle-circular">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab3" appearance="filled-circular">
{renderTabs()}
</TabList>
</div>);
};
export default Appearance;
Custom Appearance Elevated
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import * as React from 'react';
import type { TabValue } from "@coreai-ds/react-components";
import type { SelectTabEvent } from "@coreai-ds/react-components";
import type { SelectTabData } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarDayFilled } from "@fluentui/react-icons";
import { CalendarDayRegular } from "@fluentui/react-icons";
import { CalendarAgendaFilled } from "@fluentui/react-icons";
import { CalendarAgendaRegular } from "@fluentui/react-icons";
import { CalendarTodayFilled } from "@fluentui/react-icons";
import { CalendarTodayRegular } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { Overflow } from "@coreai-ds/react-components";
import { Calendar3DayFilled } from "@fluentui/react-icons";
import { Calendar3DayRegular } from "@fluentui/react-icons";
import { CalendarWorkWeekFilled } from "@fluentui/react-icons";
import { CalendarWorkWeekRegular } from "@fluentui/react-icons";
import { CalendarWeekStartFilled } from "@fluentui/react-icons";
import { CalendarWeekStartRegular } from "@fluentui/react-icons";
import { CalendarSearchFilled } from "@fluentui/react-icons";
import { CalendarSearchRegular } from "@fluentui/react-icons";
import { CalendarChatFilled } from "@fluentui/react-icons";
import { CalendarChatRegular } from "@fluentui/react-icons";
import { OverflowItem } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MoreHorizontalFilled } from "@fluentui/react-icons";
import { MoreHorizontalRegular } from "@fluentui/react-icons";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { MenuItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
const CalendarDay = bundleIcon(CalendarDayFilled, CalendarDayRegular);
const CalendarAgenda = bundleIcon(CalendarAgendaFilled, CalendarAgendaRegular);
const CalendarToday = bundleIcon(CalendarTodayFilled, CalendarTodayRegular);
// ---------- Default + Panels (combined) ----------
const DefaultWithPanels = () => {
const [selectedValue, setSelectedValue] = React.useState<TabValue>('conditions');
const onTabSelect = (_e: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};
return (<>
<TabList appearance="elevated" selectedValue={selectedValue} onTabSelect={onTabSelect}>
<Tab id="components-tablist--custom-appearance-elevated-Arrivals" icon={<CalendarDay />} value="arrivals">
Arrivals
</Tab>
<Tab id="components-tablist--custom-appearance-elevated-Departures" icon={<CalendarAgenda />} value="departures">
Departures
</Tab>
<Tab id="components-tablist--custom-appearance-elevated-Conditions" icon={<CalendarToday />} value="conditions">
Conditions
</Tab>
</TabList>
<div className="tab-list-elevated-example__panels">
{selectedValue === 'arrivals' && (<div role="tabpanel" aria-labelledby="components-tablist--custom-appearance-elevated-Arrivals">
<table>
<thead>
<th>Origin</th>
<th>Gate</th>
<th>ETA</th>
</thead>
<tbody>
<tr>
<td>DEN</td>
<td>C3</td>
<td>12:40 PM</td>
</tr>
<tr>
<td>SMF</td>
<td>D1</td>
<td>1:18 PM</td>
</tr>
<tr>
<td>SFO</td>
<td>E18</td>
<td>1:42 PM</td>
</tr>
</tbody>
</table>
</div>)}
{selectedValue === 'departures' && (<div role="tabpanel" aria-labelledby="components-tablist--custom-appearance-elevated-Departures">
<table>
<thead>
<th>Destination</th>
<th>Gate</th>
<th>ETD</th>
</thead>
<tbody>
<tr>
<td>MSP</td>
<td>A7</td>
<td>8:26 AM</td>
</tr>
<tr>
<td>DCA</td>
<td>N2</td>
<td>9:03 AM</td>
</tr>
<tr>
<td>LAS</td>
<td>E15</td>
<td>2:36 PM</td>
</tr>
</tbody>
</table>
</div>)}
{selectedValue === 'conditions' && (<div role="tabpanel" aria-labelledby="components-tablist--custom-appearance-elevated-Conditions">
<table className="tab-list-elevated-example__props-table">
<tbody>
<tr>
<td>Time</td>
<td>6:45 AM</td>
</tr>
<tr>
<td>Temperature</td>
<td>68F / 20C</td>
</tr>
<tr>
<td>Forecast</td>
<td>Overcast</td>
</tr>
<tr>
<td>Visibility</td>
<td>0.5 miles, 1800 ft runway visual range</td>
</tr>
</tbody>
</table>
</div>)}
</div>
</>);
};
// ---------- Simple tab set used across sections ----------
const renderSimpleTabs = (disabledValue?: string) => (<>
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2" disabled={disabledValue === 'tab2'}>
Second Tab
</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
// ---------- Icons ----------
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
const renderIconTabs = (iconOnly?: boolean) => (<>
<Tab icon={<CalendarMonth />} value="tab1" {...(iconOnly ? { 'aria-label': 'First Tab' } : {})}>
{iconOnly ? undefined : 'First Tab'}
</Tab>
<Tab icon={<CalendarMonth />} value="tab2" {...(iconOnly ? { 'aria-label': 'Second Tab' } : {})}>
{iconOnly ? undefined : 'Second Tab'}
</Tab>
<Tab icon={<CalendarMonth />} value="tab3" {...(iconOnly ? { 'aria-label': 'Third Tab' } : {})}>
{iconOnly ? undefined : 'Third Tab'}
</Tab>
<Tab icon={<CalendarMonth />} value="tab4" {...(iconOnly ? { 'aria-label': 'Fourth Tab' } : {})}>
{iconOnly ? undefined : 'Fourth Tab'}
</Tab>
</>);
// ---------- Overflow plumbing (adapted from TabListWithOverflow.stories) ----------
type ExampleTab = {
id: string;
name: string;
icon: React.ReactElement;
};
const Calendar3Day = bundleIcon(Calendar3DayFilled, Calendar3DayRegular);
const CalendarWorkWeek = bundleIcon(CalendarWorkWeekFilled, CalendarWorkWeekRegular);
const CalendarWeekStart = bundleIcon(CalendarWeekStartFilled, CalendarWeekStartRegular);
const CalendarSearch = bundleIcon(CalendarSearchFilled, CalendarSearchRegular);
const CalendarChat = bundleIcon(CalendarChatFilled, CalendarChatRegular);
const overflowTabs: ExampleTab[] = [
{ id: 'today', name: 'Today', icon: <CalendarToday /> },
{ id: 'agenda', name: 'Agenda', icon: <CalendarAgenda /> },
{ id: 'day', name: 'Day', icon: <CalendarDay /> },
{ id: 'threeDay', name: 'Three Day', icon: <Calendar3Day /> },
{ id: 'workWeek', name: 'Work Week', icon: <CalendarWorkWeek /> },
{ id: 'week', name: 'Week', icon: <CalendarWeekStart /> },
{ id: 'month', name: 'Month', icon: <CalendarMonth /> },
{ id: 'search', name: 'Search', icon: <CalendarSearch /> },
{ id: 'chat', name: 'Conversations', icon: <CalendarChat /> },
];
type OverflowMenuProps = {
onTabSelect?: (tabId: string) => void;
};
const MoreHorizontal = bundleIcon(MoreHorizontalFilled, MoreHorizontalRegular);
type OverflowMenuItemProps = {
tab: ExampleTab;
onClick: MenuItemProps['onClick'];
};
const OverflowMenuItem = ({ tab, onClick }: OverflowMenuItemProps) => {
const isVisible = useIsOverflowItemVisible(tab.id);
if (isVisible) {
return null;
}
return (<MenuItem key={tab.id} icon={tab.icon} onClick={onClick}>
<div>{tab.name}</div>
</MenuItem>);
};
const OverflowMenu = ({ onTabSelect }: OverflowMenuProps) => {
const { ref, isOverflowing, overflowCount } = useOverflowMenu<HTMLButtonElement>();
if (!isOverflowing) {
return null;
}
return (<Menu hasIcons>
<MenuTrigger disableButtonEnhancement>
<Button appearance="transparent" className="tab-list-elevated-example__menu-button" ref={ref} icon={<MoreHorizontal />} aria-label={`${overflowCount} more tabs`} role="tab"/>
</MenuTrigger>
<MenuPopover>
<MenuList>
{overflowTabs.map((tab) => (<OverflowMenuItem key={tab.id} tab={tab} onClick={() => onTabSelect?.(tab.id)}/>))}
</MenuList>
</MenuPopover>
</Menu>);
};
const OverflowHorizontal = () => {
const [selectedTabId, setSelectedTabId] = React.useState<string>('today');
return (<div className="tab-list-elevated-example__overflow tab-list-elevated-example__overflow--horizontal">
<Overflow minimumVisible={2}>
<TabList appearance="elevated" selectedValue={selectedTabId} onTabSelect={(_, d) => setSelectedTabId(d.value as string)}>
{overflowTabs.map((tab) => (<OverflowItem key={tab.id} id={tab.id} priority={tab.id === selectedTabId ? 2 : 1}>
<Tab value={tab.id} icon={<span>{tab.icon}</span>}>
{tab.name}
</Tab>
</OverflowItem>))}
<OverflowMenu onTabSelect={setSelectedTabId}/>
</TabList>
</Overflow>
</div>);
};
const OverflowVertical = () => {
const [selectedTabId, setSelectedTabId] = React.useState<string>('today');
return (<div className="tab-list-elevated-example__overflow tab-list-elevated-example__overflow--vertical">
<Overflow minimumVisible={2} overflowAxis="vertical">
<TabList appearance="elevated" vertical selectedValue={selectedTabId} onTabSelect={(_, d) => setSelectedTabId(d.value as string)}>
{overflowTabs.map((tab) => (<OverflowItem key={tab.id} id={tab.id} priority={tab.id === selectedTabId ? 2 : 1}>
<Tab value={tab.id} icon={<span>{tab.icon}</span>}>
{tab.name}
</Tab>
</OverflowItem>))}
<OverflowMenu onTabSelect={setSelectedTabId}/>
</TabList>
</Overflow>
</div>);
};
// ---------- The story ----------
export const CustomAppearanceElevated = () => {
const styles = /* css */ `
.tab-list-elevated-example {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
row-gap: var(--spacingVerticalXXXL);
padding: var(--spacingVerticalXXXL) var(--spacingHorizontalXL);
}
.tab-list-elevated-example__section {
display: flex;
flex-direction: column;
align-items: flex-start;
row-gap: var(--spacingVerticalS);
}
.tab-list-elevated-example__section-heading {
margin: 0;
color: var(--colorNeutralForeground1);
font-size: var(--fontSizeBase400);
font-weight: var(--fontWeightSemibold);
}
.tab-list-elevated-example__section-subheading {
margin: 0;
color: var(--colorNeutralForeground3);
font-size: var(--fontSizeBase200);
}
.tab-list-elevated-example__row {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
column-gap: var(--spacingHorizontalXXL);
}
.tab-list-elevated-example__panels {
padding: var(--spacingVerticalS) 0 0;
}
.tab-list-elevated-example__panels th {
padding: 0 30px 0 0;
text-align: left;
}
.tab-list-elevated-example__props-table td {
padding: 0 30px 0 0;
}
.tab-list-elevated-example__props-table td:first-child {
font-weight: var(--fontWeightSemibold);
}
.tab-list-elevated-example__overflow {
z-index: 0;
overflow: hidden;
padding: 5px;
background-color: var(--colorNeutralBackground2);
}
.tab-list-elevated-example__overflow--horizontal {
width: 600px;
min-width: 150px;
height: fit-content;
resize: horizontal;
}
.tab-list-elevated-example__overflow--vertical {
display: flex;
align-content: stretch;
align-items: stretch;
justify-content: stretch;
justify-items: stretch;
width: fit-content;
height: 250px;
min-height: 100px;
resize: vertical;
}
.tab-list-elevated-example__menu-button {
align-self: center;
}
`;
return (<>
<style>{styles}</style>
<div className="tab-list-elevated-example">
{/* 1. Default — appearance + panels combined */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">Default (with panels)</h3>
<p className="tab-list-elevated-example__section-subheading">
Selectable tabs that drive a panel below the strip.
</p>
<DefaultWithPanels />
</section>
{/* 2. Vertical */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">Vertical</h3>
<TabList appearance="elevated" defaultSelectedValue="tab3" vertical>
{renderSimpleTabs()}
</TabList>
</section>
{/* 3. Disabled */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">Disabled tab</h3>
<TabList appearance="elevated" defaultSelectedValue="tab3">
{renderSimpleTabs('tab2')}
</TabList>
</section>
{/* 4. Sizes — horizontal: small, medium, large stacked */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">Sizes (horizontal)</h3>
<TabList appearance="elevated" defaultSelectedValue="tab3" size="small">
{renderSimpleTabs()}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab3" size="medium">
{renderSimpleTabs()}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab3" size="large">
{renderSimpleTabs()}
</TabList>
</section>
{/* 5. Sizes vertical — laid out in a horizontal row: small, medium, large */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">
Sizes (vertical, side-by-side)
</h3>
<div className="tab-list-elevated-example__row">
<TabList appearance="elevated" defaultSelectedValue="tab3" vertical size="small">
{renderSimpleTabs()}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab3" vertical size="medium">
{renderSimpleTabs()}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab3" vertical size="large">
{renderSimpleTabs()}
</TabList>
</div>
</section>
{/* 6. With icon */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">With icon</h3>
<TabList appearance="elevated" defaultSelectedValue="tab2">
{renderIconTabs()}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab2" vertical>
{renderIconTabs()}
</TabList>
</section>
{/* 7. Icon only */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">Icon only</h3>
<TabList appearance="elevated" defaultSelectedValue="tab2">
{renderIconTabs(true)}
</TabList>
<TabList appearance="elevated" defaultSelectedValue="tab2" vertical>
{renderIconTabs(true)}
</TabList>
</section>
{/* 8. With overflow */}
<section className="tab-list-elevated-example__section">
<h3 className="tab-list-elevated-example__section-heading">With overflow</h3>
<p className="tab-list-elevated-example__section-subheading">
Drag the resize handles to shrink the container and trigger the overflow menu.
</p>
<OverflowHorizontal />
<OverflowVertical />
</section>
</div>
</>);
};
export default CustomAppearanceElevated;
Disabled
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const Disabled = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" disabled>
<Tab icon={<CalendarMonth />} value="tab1">
First Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab2">
Second Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab3">
Third Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab4">
Fourth Tab
</Tab>
</TabList>
<TabList defaultSelectedValue="tab2">
<Tab icon={<CalendarMonth />} value="tab1">
First Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab2" disabled>
Second Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab3" disabled>
Third Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab4">
Fourth Tab
</Tab>
</TabList>
</div>);
};
export default Disabled;
Elevated Appearance
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { Text } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import * as React from 'react';
export const ElevatedAppearance = () => {
const styles = /* css */ `
.tab-list-elevated-example {
align-items: flex-start;
display: flex;
flex-direction: column;
justify-content: flex-start;
padding: var(--spacingVerticalXXL) var(--spacingHorizontalL);
row-gap: var(--spacingVerticalXXL);
}
`;
return (<>
<style>{styles}</style>
<div className="tab-list-elevated-example">
<Text as="p" block>
The <code>elevated</code> appearance raises the tab strip onto its own background with
rounded corners and padding around every tab, instead of the flat underline/indicator
styling the other appearances use.
</Text>
<TabList appearance="elevated" defaultSelectedValue="tab2">
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2">Second Tab</Tab>
<Tab value="tab3">Third Tab</Tab>
</TabList>
</div>
</>);
};
export default ElevatedAppearance;
Horizontal
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
export const Horizontal = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2">
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2">Second Tab</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</TabList>
</div>);
};
export default Horizontal;
Icon Only
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const IconOnly = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab icon={<CalendarMonth />} value="tab1" aria-label="First Tab"/>
<Tab icon={<CalendarMonth />} value="tab2" aria-label="Second Tab"/>
<Tab icon={<CalendarMonth />} value="tab3" aria-label="Third Tab"/>
<Tab icon={<CalendarMonth />} value="tab4" aria-label="Fourth Tab"/>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2">{renderTabs()}</TabList>
<TabList defaultSelectedValue="tab2" vertical>
{renderTabs()}
</TabList>
</div>);
};
export default IconOnly;
Left Align Tab Text
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import * as React from 'react';
import type { TabValue } from "@coreai-ds/react-components";
import type { SelectTabEvent } from "@coreai-ds/react-components";
import type { SelectTabData } from "@coreai-ds/react-components";
import { Text } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
export const LeftAlignTabText = () => {
const tabContent: Record<string, {
heading: string;
body: string;
}> = {
overview: {
heading: 'Overview',
body: 'A high-level summary of the project, its goals, and current status.',
},
activity: {
heading: 'Activity',
body: 'A chronological feed of recent changes, comments, and status updates.',
},
settings: {
heading: 'Settings',
body: 'Configuration options such as notifications, access, and integrations.',
},
};
const [selectedValue, setSelectedValue] = React.useState<TabValue>('overview');
const onTabSelect = (_event: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};
const { heading, body } = tabContent[selectedValue as string];
const styles = /* css */ `
.tab-list-left-align-example {
display: flex;
flex-direction: column;
max-width: 480px;
row-gap: var(--spacingVerticalXXS);
}
.tab-list-left-align-example__title {
margin: 0;
}
.tab-list-left-align-example__tab-list {
margin-inline: calc(-1 * var(--spacingHorizontalM));
}
.tab-list-left-align-example__content {
color: var(--colorNeutralForeground1);
}
`;
return (<>
<style>{styles}</style>
<div className="tab-list-left-align-example">
<Text as="h2" size={500} weight="semibold" block className="tab-list-left-align-example__title">
Left-align tab content
</Text>
<TabList selectedValue={selectedValue} onTabSelect={onTabSelect} appearance="subtle" className="tab-list-left-align-example__tab-list">
<Tab value="overview">Overview</Tab>
<Tab value="activity">Activity</Tab>
<Tab value="settings">Settings</Tab>
</TabList>
<div className="tab-list-left-align-example__content" role="tabpanel" aria-labelledby={selectedValue as string}>
<Text as="h3" size={300} weight="semibold" block>
{heading}
</Text>
<Text as="p" size={200} weight="regular" block>
{body}
</Text>
</div>
</div>
</>);
};
export default LeftAlignTabText;
Select Tab On Focus
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
export const SelectTabOnFocus = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2">Second Tab</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" selectTabOnFocus={true}>
{renderTabs()}
</TabList>
</div>);
};
export default SelectTabOnFocus;
Size Large
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const SizeLarge = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab value="tab1">First Tab</Tab>
<Tab icon={<CalendarMonth />} value="tab2">
Second Tab
</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" size="large">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab2" size="large" vertical>
{renderTabs()}
</TabList>
</div>);
};
export default SizeLarge;
Size Medium
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const SizeMedium = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab value="tab1">First Tab</Tab>
<Tab icon={<CalendarMonth />} value="tab2">
Second Tab
</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" size="medium">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab2" size="medium" vertical>
{renderTabs()}
</TabList>
</div>);
};
export default SizeMedium;
Size Small
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const SizeSmall = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab value="tab1">First Tab</Tab>
<Tab icon={<CalendarMonth />} value="tab2">
Second Tab
</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" size="small">
{renderTabs()}
</TabList>
<TabList defaultSelectedValue="tab2" size="small" vertical>
{renderTabs()}
</TabList>
</div>);
};
export default SizeSmall;
Vertical
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
export const Vertical = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2" vertical>
<Tab value="tab1">First Tab</Tab>
<Tab value="tab2">Second Tab</Tab>
<Tab value="tab3">Third Tab</Tab>
<Tab value="tab4">Fourth Tab</Tab>
</TabList>
</div>);
};
export default Vertical;
With Icon
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { TabList } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
});
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
export const WithIcon = (): JSXElement => {
const styles = useStyles();
const renderTabs = () => {
return (<>
<Tab icon={<CalendarMonth />} value="tab1">
First Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab2">
Second Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab3">
Third Tab
</Tab>
<Tab icon={<CalendarMonth />} value="tab4">
Fourth Tab
</Tab>
</>);
};
return (<div className={styles.root}>
<TabList defaultSelectedValue="tab2">{renderTabs()}</TabList>
<TabList defaultSelectedValue="tab2" vertical>
{renderTabs()}
</TabList>
</div>);
};
export default WithIcon;
With Overflow
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import { mergeClasses } from "@coreai-ds/react-components";
import { Overflow } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarTodayFilled } from "@fluentui/react-icons";
import { CalendarTodayRegular } from "@fluentui/react-icons";
import { CalendarAgendaFilled } from "@fluentui/react-icons";
import { CalendarAgendaRegular } from "@fluentui/react-icons";
import { CalendarDayFilled } from "@fluentui/react-icons";
import { CalendarDayRegular } from "@fluentui/react-icons";
import { Calendar3DayFilled } from "@fluentui/react-icons";
import { Calendar3DayRegular } from "@fluentui/react-icons";
import { CalendarWorkWeekFilled } from "@fluentui/react-icons";
import { CalendarWorkWeekRegular } from "@fluentui/react-icons";
import { CalendarWeekStartFilled } from "@fluentui/react-icons";
import { CalendarWeekStartRegular } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { CalendarSearchFilled } from "@fluentui/react-icons";
import { CalendarSearchRegular } from "@fluentui/react-icons";
import { CalendarChatFilled } from "@fluentui/react-icons";
import { CalendarChatRegular } from "@fluentui/react-icons";
import { OverflowItem } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { useOverflowMenu } from "@coreai-ds/react-components";
import { Menu } from "@coreai-ds/react-components";
import { MenuTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { MoreHorizontalFilled } from "@fluentui/react-icons";
import { MoreHorizontalRegular } from "@fluentui/react-icons";
import { MenuPopover } from "@coreai-ds/react-components";
import { MenuList } from "@coreai-ds/react-components";
import type { MenuItemProps } from "@coreai-ds/react-components";
import { useIsOverflowItemVisible } from "@coreai-ds/react-components";
import { MenuItem } from "@coreai-ds/react-components";
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
overflow: 'auto',
padding: '50px 20px',
rowGap: '20px',
minHeight: '600px', //lets the page remain at a minimum height when vertical tabs are resized
},
});
//----- Stories -----//
const useExampleStyles = makeStyles({
example: {
backgroundColor: tokens.colorNeutralBackground2,
overflow: 'hidden',
padding: '5px',
zIndex: 0, //stop the browser resize handle from piercing the overflow menu
},
horizontal: {
height: 'fit-content',
minWidth: '150px',
resize: 'horizontal',
width: '600px',
},
vertical: {
height: '250px',
minHeight: '100px',
resize: 'vertical',
width: 'fit-content',
display: 'flex',
alignContent: 'stretch',
alignItems: 'stretch',
justifyContent: 'stretch',
justifyItems: 'stretch',
},
});
//----- Example Tab Data -----//
type ExampleTab = {
id: string;
name: string;
icon: React.ReactElement;
};
const CalendarToday = bundleIcon(CalendarTodayFilled, CalendarTodayRegular);
const CalendarAgenda = bundleIcon(CalendarAgendaFilled, CalendarAgendaRegular);
const CalendarDay = bundleIcon(CalendarDayFilled, CalendarDayRegular);
const Calendar3Day = bundleIcon(Calendar3DayFilled, Calendar3DayRegular);
const CalendarWorkWeek = bundleIcon(CalendarWorkWeekFilled, CalendarWorkWeekRegular);
const CalendarWeekStart = bundleIcon(CalendarWeekStartFilled, CalendarWeekStartRegular);
const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);
const CalendarSearch = bundleIcon(CalendarSearchFilled, CalendarSearchRegular);
const CalendarChat = bundleIcon(CalendarChatFilled, CalendarChatRegular);
const tabs: ExampleTab[] = [
{
id: 'today',
name: 'Today',
icon: <CalendarToday />,
},
{
id: 'agenda',
name: 'Agenda',
icon: <CalendarAgenda />,
},
{
id: 'day',
name: 'Day',
icon: <CalendarDay />,
},
{
id: 'threeDay',
name: 'Three Day',
icon: <Calendar3Day />,
},
{
id: 'workWeek',
name: 'Work Week',
icon: <CalendarWorkWeek />,
},
{
id: 'week',
name: 'Week',
icon: <CalendarWeekStart />,
},
{
id: 'month',
name: 'Month',
icon: <CalendarMonth />,
},
{
id: 'search',
name: 'Search',
icon: <CalendarSearch />,
},
{
id: 'chat',
name: 'Conversations',
icon: <CalendarChat />,
},
];
type OverflowMenuProps = {
onTabSelect?: (tabId: string) => void;
};
//----- OverflowMenu -----//
const useOverflowMenuStyles = makeStyles({
menu: {
backgroundColor: tokens.colorNeutralBackground1,
},
menuButton: {
alignSelf: 'center',
},
});
const MoreHorizontal = bundleIcon(MoreHorizontalFilled, MoreHorizontalRegular);
//----- OverflowMenuItem -----//
type OverflowMenuItemProps = {
tab: ExampleTab;
onClick: MenuItemProps['onClick'];
};
/**
* A menu item for an overflow menu that only displays when the tab is not visible
*/
const OverflowMenuItem = (props: OverflowMenuItemProps) => {
const { tab, onClick } = props;
const isVisible = useIsOverflowItemVisible(tab.id);
if (isVisible) {
return null;
}
return (<MenuItem key={tab.id} icon={tab.icon} onClick={onClick}>
<div>{tab.name}</div>
</MenuItem>);
};
/**
* A menu for selecting tabs that have overflowed and are not visible.
*/
const OverflowMenu = (props: OverflowMenuProps) => {
const { onTabSelect } = props;
const { ref, isOverflowing, overflowCount } = useOverflowMenu<HTMLButtonElement>();
const styles = useOverflowMenuStyles();
const onItemClick = (tabId: string) => {
onTabSelect?.(tabId);
};
if (!isOverflowing) {
return null;
}
return (<Menu hasIcons>
<MenuTrigger disableButtonEnhancement>
<Button appearance="transparent" className={styles.menuButton} ref={ref} icon={<MoreHorizontal />} aria-label={`${overflowCount} more tabs`} role="tab"/>
</MenuTrigger>
<MenuPopover>
<MenuList className={styles.menu}>
{tabs.map(tab => (<OverflowMenuItem key={tab.id} tab={tab} onClick={() => onItemClick(tab.id)}/>))}
</MenuList>
</MenuPopover>
</Menu>);
};
const HorizontalExample = () => {
const styles = useExampleStyles();
const [selectedTabId, setSelectedTabId] = React.useState<string>('today');
const onTabSelect = (tabId: string) => {
setSelectedTabId(tabId);
};
return (<div className={mergeClasses(styles.example, styles.horizontal)}>
<Overflow minimumVisible={2}>
<TabList selectedValue={selectedTabId} onTabSelect={(_, d) => onTabSelect(d.value as string)}>
{tabs.map(tab => {
return (<OverflowItem key={tab.id} id={tab.id} priority={tab.id === selectedTabId ? 2 : 1}>
<Tab value={tab.id} icon={<span>{tab.icon}</span>}>
{tab.name}
</Tab>
</OverflowItem>);
})}
<OverflowMenu onTabSelect={onTabSelect}/>
</TabList>
</Overflow>
</div>);
};
const VerticalExample = () => {
const styles = useExampleStyles();
const [selectedTabId, setSelectedTabId] = React.useState<string>('today');
const onTabSelect = (tabId: string) => {
setSelectedTabId(tabId);
};
return (<div className={mergeClasses(styles.example, styles.vertical)}>
<Overflow minimumVisible={2} overflowAxis="vertical">
<TabList vertical selectedValue={selectedTabId} onTabSelect={(_, d) => onTabSelect(d.value as string)}>
{tabs.map(tab => {
return (<OverflowItem key={tab.id} id={tab.id} priority={tab.id === selectedTabId ? 2 : 1}>
<Tab value={tab.id} icon={<span>{tab.icon}</span>}>
{tab.name}
</Tab>
</OverflowItem>);
})}
<OverflowMenu onTabSelect={onTabSelect}/>
</TabList>
</Overflow>
</div>);
};
export const WithOverflow = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.root}>
<HorizontalExample />
<VerticalExample />
</div>);
};
export default WithOverflow;
With Panels
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import * as React from 'react';
import type { TabValue } from "@coreai-ds/react-components";
import type { SelectTabEvent } from "@coreai-ds/react-components";
import type { SelectTabData } from "@coreai-ds/react-components";
import { TabList } from "@coreai-ds/react-components";
import { Tab } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { AirplaneFilled } from "@fluentui/react-icons";
import { AirplaneRegular } from "@fluentui/react-icons";
import { AirplaneTakeOffFilled } from "@fluentui/react-icons";
import { AirplaneTakeOffRegular } from "@fluentui/react-icons";
import { TimeAndWeatherFilled } from "@fluentui/react-icons";
import { TimeAndWeatherRegular } from "@fluentui/react-icons";
const useStyles = makeStyles({
root: {
alignItems: 'flex-start',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
padding: '50px 20px',
rowGap: '20px',
},
panels: {
padding: '0 10px',
'& th': {
textAlign: 'left',
padding: '0 30px 0 0',
},
},
propsTable: {
'& td:first-child': {
fontWeight: tokens.fontWeightSemibold,
},
'& td': {
padding: '0 30px 0 0',
},
},
});
const Airplane = bundleIcon(AirplaneFilled, AirplaneRegular);
const AirplaneTakeOff = bundleIcon(AirplaneTakeOffFilled, AirplaneTakeOffRegular);
const TimeAndWeather = bundleIcon(TimeAndWeatherFilled, TimeAndWeatherRegular);
export const WithPanels = (): JSXElement => {
const styles = useStyles();
const [selectedValue, setSelectedValue] = React.useState<TabValue>('conditions');
const onTabSelect = (event: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};
const Arrivals = React.memo(() => (<div role="tabpanel" aria-labelledby="components-tablist--with-panels-Arrivals">
<table>
<thead>
<th>Origin</th>
<th>Gate</th>
<th>ETA</th>
</thead>
<tbody>
<tr>
<td>DEN</td>
<td>C3</td>
<td>12:40 PM</td>
</tr>
<tr>
<td>SMF</td>
<td>D1</td>
<td>1:18 PM</td>
</tr>
<tr>
<td>SFO</td>
<td>E18</td>
<td>1:42 PM</td>
</tr>
</tbody>
</table>
</div>));
const Departures = React.memo(() => (<div role="tabpanel" aria-labelledby="components-tablist--with-panels-Departures">
<table>
<thead>
<th>Destination</th>
<th>Gate</th>
<th>ETD</th>
</thead>
<tbody>
<tr>
<td>MSP</td>
<td>A7</td>
<td>8:26 AM</td>
</tr>
<tr>
<td>DCA</td>
<td>N2</td>
<td>9:03 AM</td>
</tr>
<tr>
<td>LAS</td>
<td>E15</td>
<td>2:36 PM</td>
</tr>
</tbody>
</table>
</div>));
const Conditions = React.memo(() => (<div role="tabpanel" aria-labelledby="components-tablist--with-panels-Conditions">
<table className={styles.propsTable}>
<tbody>
<tr>
<td>Time</td>
<td>6:45 AM</td>
</tr>
<tr>
<td>Temperature</td>
<td>68F / 20C</td>
</tr>
<tr>
<td>Forecast</td>
<td>Overcast</td>
</tr>
<tr>
<td>Visibility</td>
<td>0.5 miles, 1800 ft runway visual range</td>
</tr>
</tbody>
</table>
</div>));
return (<div className={styles.root}>
<TabList selectedValue={selectedValue} onTabSelect={onTabSelect}>
<Tab id="components-tablist--with-panels-Arrivals" icon={<Airplane />} value="arrivals">
Arrivals
</Tab>
<Tab id="components-tablist--with-panels-Departures" icon={<AirplaneTakeOff />} value="departures">
Departures
</Tab>
<Tab id="components-tablist--with-panels-Conditions" icon={<TimeAndWeather />} value="conditions">
Conditions
</Tab>
</TabList>
<div className={styles.panels}>
{selectedValue === 'arrivals' && <Arrivals />}
{selectedValue === 'departures' && <Departures />}
{selectedValue === 'conditions' && <Conditions />}
</div>
</div>);
};
export default WithPanels;