diff --git a/src/components/experimental/Tabs/Tabs.spec.tsx b/src/components/experimental/Tabs/Tabs.spec.tsx
new file mode 100644
index 00000000..c5cc3ccd
--- /dev/null
+++ b/src/components/experimental/Tabs/Tabs.spec.tsx
@@ -0,0 +1,51 @@
+import * as React from 'react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { Tabs, TabList, Tab, TabPanel } from './Tabs';
+
+describe('Experimental: Tabs', () => {
+ it('renders tabs and switch between them', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ Tab 1
+ Tab 2
+ Tab 3
+
+ Content of Tab 1
+ Content of Tab 2
+ Content of Tab 3
+
+ );
+
+ expect(screen.getByRole('tab', { name: 'Tab 1' })).toHaveAttribute('aria-selected', 'true');
+ expect(screen.getByText('Content of Tab 1')).toBeInTheDocument();
+
+ await user.click(screen.getByRole('tab', { name: 'Tab 3' }));
+
+ expect(screen.getByRole('tab', { name: 'Tab 3' })).toHaveAttribute('aria-selected', 'true');
+ expect(screen.getByText('Content of Tab 3')).toBeInTheDocument();
+ expect(screen.queryByText('Content of Tab 1')).not.toBeInTheDocument();
+ });
+
+ it('handles disabled tabs', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+ Tab 1
+
+ Tab 2
+
+
+ Founding.
+ Monarchy.
+
+ );
+
+ await user.click(screen.getByRole('tab', { name: 'Tab 2' }));
+ expect(screen.getByRole('tab', { name: 'Tab 1' })).toHaveAttribute('aria-selected', 'true');
+ expect(screen.getByRole('tab', { name: 'Tab 2' })).toHaveAttribute('aria-selected', 'false');
+ });
+});
diff --git a/src/components/experimental/Tabs/Tabs.tsx b/src/components/experimental/Tabs/Tabs.tsx
new file mode 100644
index 00000000..1a0b7215
--- /dev/null
+++ b/src/components/experimental/Tabs/Tabs.tsx
@@ -0,0 +1,125 @@
+import React, { ReactElement, ComponentType } from 'react';
+import {
+ Tabs as BaseTabs,
+ TabList as BaseTabList,
+ Tab as BaseTab,
+ TabPanel as BaseTabPanel,
+ TabsProps,
+ TabListProps,
+ TabProps,
+ TabPanelProps
+} from 'react-aria-components';
+import styled from 'styled-components';
+import { get } from '../../../utils/experimental/themeGet';
+import { getSemanticValue } from '../../../essentials/experimental';
+import { textStyles } from '../Text/Text';
+
+const StyledTabs = styled(BaseTabs as ComponentType)`
+ display: flex;
+ gap: ${get('space.4')};
+
+ &[data-orientation='vertical'] {
+ flex-direction: row;
+ }
+
+ &[data-orientation='horizontal'] {
+ flex-direction: column;
+ }
+`;
+
+const StyledTabList = styled(BaseTabList as ComponentType>>)`
+ display: flex;
+ gap: ${get('space.4')};
+
+ &[data-orientation='vertical'] {
+ flex-direction: column;
+ }
+
+ &[data-orientation='horizontal'] {
+ flex-direction: row;
+ }
+`;
+
+const StyledTab = styled(BaseTab as ComponentType)`
+ position: relative;
+ cursor: pointer;
+ outline: none;
+ padding: ${get('space.2')} 0;
+ ${textStyles.variants.label1};
+ color: ${getSemanticValue('on-surface-variant')};
+ transition: color 200ms ease;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &[data-hovered] {
+ color: ${getSemanticValue('on-surface')};
+ }
+
+ &[data-selected] {
+ color: ${getSemanticValue('accent')};
+ }
+
+ &[data-disabled] {
+ color: ${getSemanticValue('on-surface-variant')};
+ opacity: 0.38;
+ cursor: default;
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ background: ${getSemanticValue('accent')};
+ opacity: 0;
+ transition: opacity 200ms ease;
+ }
+
+ [data-orientation='vertical'] &::after {
+ top: 50%;
+ transform: translateY(-50%);
+ right: -1px;
+ width: 2px;
+ height: 85%;
+ }
+
+ [data-orientation='horizontal'] &::after {
+ left: 50%;
+ transform: translateX(-50%);
+ bottom: -1px;
+ height: 2px;
+ width: 85%;
+ }
+
+ &[data-selected]::after {
+ opacity: 1;
+ }
+
+ &[data-focus-visible] {
+ outline: 0.125rem solid ${getSemanticValue('accent')};
+ outline-offset: 0.125rem;
+ }
+`;
+
+const StyledTabPanel = styled(BaseTabPanel as ComponentType)`
+ outline: none;
+ ${textStyles.variants.body1};
+`;
+
+function Tabs(props: TabsProps): ReactElement {
+ return ;
+}
+
+function TabList>(props: TabListProps): ReactElement {
+ return ;
+}
+
+function Tab(props: TabProps): ReactElement {
+ return ;
+}
+
+function TabPanel(props: TabPanelProps): ReactElement {
+ return ;
+}
+
+export { Tabs, TabList, Tab, TabPanel };
diff --git a/src/components/experimental/Tabs/docs/Tabs.stories.tsx b/src/components/experimental/Tabs/docs/Tabs.stories.tsx
new file mode 100644
index 00000000..eab5e13c
--- /dev/null
+++ b/src/components/experimental/Tabs/docs/Tabs.stories.tsx
@@ -0,0 +1,78 @@
+import React from 'react';
+import { StoryObj, Meta } from '@storybook/react';
+import { Tabs, TabList, Tab, TabPanel } from '../Tabs';
+
+const meta: Meta = {
+ title: 'Experimental/Components/Tabs',
+ component: Tabs,
+ parameters: {
+ layout: 'centered'
+ },
+ argTypes: {
+ keyboardActivation: {
+ control: 'radio',
+ options: ['automatic', 'manual']
+ },
+ orientation: {
+ control: 'radio',
+ options: ['horizontal', 'vertical']
+ },
+ isDisabled: {
+ control: 'boolean'
+ }
+ }
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {
+ render: args => (
+
+
+ Tab 1
+ Tab 2
+ Tab 3
+
+ Content of Tab 1
+ Content of Tab 2
+ Content of Tab 3
+
+ )
+};
+
+export const DisabledTab: Story = {
+ render: args => (
+
+
+ Tab 1
+
+ Tab 2
+
+ Tab 3
+
+ Content of Tab 1
+ Content of Tab 2
+ Content of Tab 3
+
+ )
+};
+
+export const DisabledTabs: Story = {
+ args: {
+ isDisabled: true
+ },
+ render: args => (
+
+
+ Tab 1
+ Tab 2
+ Tab 3
+
+ Content of Tab 1
+ Content of Tab 2
+ Content of Tab 3
+
+ )
+};
diff --git a/src/components/experimental/index.ts b/src/components/experimental/index.ts
index a283f728..b9395bba 100644
--- a/src/components/experimental/index.ts
+++ b/src/components/experimental/index.ts
@@ -22,6 +22,7 @@ export { Search } from './Search/Search';
export { Select } from './Select/Select';
export { Snackbar, SnackbarProps } from './Snackbar/Snackbar';
export { Table, Row, Cell, Skeleton, Column, TableBody, TableHeader } from './Table/Table';
+export { Tabs, TabList, Tab, TabPanel } from './Tabs/Tabs';
export { Text } from './Text/Text';
export { TextField } from './TextField/TextField';
export { TimeField } from './TimeField/TimeField';