Skip to content

Commit 4b06b29

Browse files
committed
TabNav component
1 parent 44d53e0 commit 4b06b29

File tree

7 files changed

+136
-0
lines changed

7 files changed

+136
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import TabNavLink from './fragments/TabNavLink';
2+
import TabNavRoot from './fragments/TabNavRoot';
3+
4+
const TabNav = () => {
5+
console.warn('Direct usage of TabNav is not supported. Please use TabNav.Root, TabNav.Link instead.');
6+
return null;
7+
};
8+
9+
export default TabNav;
10+
11+
TabNav.Root = TabNavRoot;
12+
TabNav.Link = TabNavLink;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { createContext } from 'react';
2+
3+
interface TabNavContextType {
4+
rootClass?: string;
5+
}
6+
7+
const TabNavContext = createContext<TabNavContextType>({
8+
rootClass: 'TabNav'
9+
});
10+
11+
export default TabNavContext;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React, { useContext } from 'react';
2+
import { clsx } from 'clsx';
3+
import RovingFocusGroup from '~/core/utils/RovingFocusGroup';
4+
import Primitive from '~/core/primitives/Primitive';
5+
import TabNavContext from '../context/TabNav.context';
6+
7+
export type TabNavLinkProps = {
8+
children: React.ReactNode,
9+
className?: string,
10+
href?: string,
11+
disabled?: boolean,
12+
13+
}
14+
15+
const TabNavLink = ({ className = '', href = '#', children, disabled }: TabNavLinkProps) => {
16+
const { rootClass } = useContext(TabNavContext);
17+
18+
return (
19+
<RovingFocusGroup.Item>
20+
<Primitive.a
21+
className={clsx(`${rootClass}-link`, className)}
22+
data-disabled={disabled}
23+
{...disabled ? {} : { href }}
24+
>
25+
{children}
26+
</Primitive.a>
27+
</RovingFocusGroup.Item>
28+
);
29+
};
30+
31+
export default TabNavLink;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React, { Children } from 'react';
2+
import { customClassSwitcher } from '~/core';
3+
import { clsx } from 'clsx';
4+
import RovingFocusGroup from '~/core/utils/RovingFocusGroup';
5+
import TabNavContext from '../context/TabNav.context';
6+
7+
const COMPONENT_NAME = 'TabNav';
8+
9+
export type TabNavRootProps = {
10+
className?: string,
11+
loop?: boolean,
12+
orientation?: 'horizontal' | 'vertical',
13+
children: React.ReactNode,
14+
customRootClass?: string,
15+
}
16+
17+
const TabNavRoot = ({ className, loop = true, orientation = 'horizontal', children, customRootClass = '', ...props }: TabNavRootProps) => {
18+
const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME);
19+
return (
20+
<TabNavContext.Provider
21+
value={{
22+
rootClass
23+
}}>
24+
<RovingFocusGroup.Root loop={loop} orientation={orientation} >
25+
<RovingFocusGroup.Group className={clsx(rootClass, className)}>
26+
{children}
27+
</RovingFocusGroup.Group>
28+
</RovingFocusGroup.Root>
29+
</TabNavContext.Provider>
30+
31+
);
32+
};
33+
34+
export default TabNavRoot;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import TabNav from '../TabNav';
3+
import SandboxEditor from '~/components/tools/SandboxEditor/SandboxEditor';
4+
5+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
6+
export default {
7+
title: 'WIP/TabNav',
8+
component: TabNav,
9+
render: (args: React.JSX.IntrinsicAttributes) => <SandboxEditor>
10+
<div >
11+
<TabNav.Root>
12+
<TabNav.Link disabled href={'###'}>Tab 1</TabNav.Link>
13+
<TabNav.Link>Tab 2</TabNav.Link>
14+
<TabNav.Link>Tab 3</TabNav.Link>
15+
</TabNav.Root>
16+
</div>
17+
</SandboxEditor>
18+
};
19+
20+
export const All = {
21+
args: {
22+
className: 'text-gray-950'
23+
}
24+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.rad-ui-tab-nav{
2+
display: flex;
3+
gap: 6px;
4+
5+
.rad-ui-tab-nav-link {
6+
background-color: white;
7+
color: #65636d;
8+
display: flex;
9+
align-items: center;
10+
justify-content: center;
11+
margin-left: 1px;
12+
13+
&:focus-visible {
14+
outline: 2px solid var(--rad-ui-color-accent-900);
15+
outline-offset: 2px;
16+
}
17+
18+
&:hover{
19+
background-color: var(--rad-ui-color-accent-300);
20+
color: var(--rad-ui-color-accent-950);
21+
}
22+
}
23+
}

styles/themes/default.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
@use "components/skeleton";
2929
@use "components/visuallyhidden";
3030
@use "components/collapsible";
31+
@use "components/tab-nav";
3132

3233
// import .css file
3334
@use "../cssTokens/base.tokens";

0 commit comments

Comments
 (0)