Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/components/ui/TabNav/TabNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import TabNavLink from './fragments/TabNavLink';
import TabNavRoot from './fragments/TabNavRoot';

const TabNav = () => {
console.warn('Direct usage of TabNav is not supported. Please use TabNav.Root, TabNav.Link instead.');
return null;
};

export default TabNav;

TabNav.Root = TabNavRoot;
TabNav.Link = TabNavLink;
11 changes: 11 additions & 0 deletions src/components/ui/TabNav/context/TabNav.context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createContext } from 'react';

interface TabNavContextType {
rootClass?: string;
}

const TabNavContext = createContext<TabNavContextType>({
rootClass: ''
});

export default TabNavContext;
35 changes: 35 additions & 0 deletions src/components/ui/TabNav/fragments/TabNavLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useContext, useRef } from 'react';

Check warning on line 1 in src/components/ui/TabNav/fragments/TabNavLink.tsx

View workflow job for this annotation

GitHub Actions / lint

'useRef' is defined but never used
import { clsx } from 'clsx';
import RovingFocusGroup from '~/core/utils/RovingFocusGroup';
import Primitive from '~/core/primitives/Primitive';
import TabNavContext from '../context/TabNav.context';

export type TabNavLinkProps = {
children: React.ReactNode,
className?: string,
href?: string,
disabled?: boolean,
asChild?: boolean
}

const TabNavLink = ({ className = '', href = '#', children, disabled, asChild }: TabNavLinkProps) => {
const { rootClass } = useContext(TabNavContext);
if (asChild) disabled = false;

return (
<RovingFocusGroup.Item >
<Primitive.a
className={clsx(`${rootClass}-link`, className)}
asChild={asChild}
aria-disabled={disabled}
// @ts-expect-error
disabled={disabled}
{...disabled ? {} : { href }}
>
{children}
</Primitive.a>
</RovingFocusGroup.Item>
);
};

export default TabNavLink;
39 changes: 39 additions & 0 deletions src/components/ui/TabNav/fragments/TabNavRoot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useEffect } from 'react';

Check warning on line 1 in src/components/ui/TabNav/fragments/TabNavRoot.tsx

View workflow job for this annotation

GitHub Actions / lint

'useEffect' is defined but never used
import { customClassSwitcher } from '~/core';
import { clsx } from 'clsx';
import RovingFocusGroup from '~/core/utils/RovingFocusGroup';
import TabNavContext from '../context/TabNav.context';
import useControllableState from '~/core/hooks/useControllableState';

Check warning on line 6 in src/components/ui/TabNav/fragments/TabNavRoot.tsx

View workflow job for this annotation

GitHub Actions / lint

'useControllableState' is defined but never used

const COMPONENT_NAME = 'TabNav';

export type TabNavRootProps = {
className?: string,
loop?: boolean,
orientation?: 'horizontal' | 'vertical',
children: React.ReactNode,
customRootClass?: string,
color?: string;
}

const TabNavRoot = ({
className, loop = true, orientation = 'horizontal', children, color, customRootClass = '', ...props
}: TabNavRootProps) => {
const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME);

const contextValues = {
rootClass
};
return (
<TabNavContext.Provider value={contextValues}>
<RovingFocusGroup.Root loop={loop} orientation={orientation} {...props} >
<RovingFocusGroup.Group className={clsx(rootClass, className)}>
{children}
</RovingFocusGroup.Group>
</RovingFocusGroup.Root>
</TabNavContext.Provider>

);
};

export default TabNavRoot;
24 changes: 24 additions & 0 deletions src/components/ui/TabNav/stories/TabNav.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import TabNav from '../TabNav';
import SandboxEditor from '~/components/tools/SandboxEditor/SandboxEditor';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
export default {
title: 'WIP/TabNav',
component: TabNav,
render: (args: React.JSX.IntrinsicAttributes) => <SandboxEditor>
<div >
<TabNav.Root>
<TabNav.Link disabled href={'###'}>Tab 1</TabNav.Link>
<TabNav.Link>Tab 2</TabNav.Link>
<TabNav.Link>Tab 3</TabNav.Link>
</TabNav.Root>
</div>
</SandboxEditor>
};

export const All = {
args: {
className: 'text-gray-950'
}
};
27 changes: 27 additions & 0 deletions styles/themes/components/tab-nav.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.rad-ui-tab-nav{
display: flex;
box-shadow: inset 0 -1px 0 0 var(--rad-ui-color-gray-500);

.rad-ui-tab-nav-link {
color: var(--rad-ui-color-accent-600);
font-family: inherit;
padding: 10px;
display: flex;
align-items: center;
height:42px;
font-size: 15px;
line-height: 1;
cursor: pointer;

&[aria-selected="true"]{
color: var(--rad-ui-color-accent-950);
border-bottom:2px solid var(--rad-ui-color-accent-900);
}

&:hover{
color: var(--rad-ui-color-accent-900);
}


}
}
1 change: 1 addition & 0 deletions styles/themes/default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@use "components/skeleton";
@use "components/visuallyhidden";
@use "components/collapsible";
@use "components/tab-nav";

// import .css file
@use "../cssTokens/base.tokens";
Expand Down
Loading