🎨 style: adjust vertical tab theme
This commit is contained in:
parent
1ab155c638
commit
e57591187c
@ -4,8 +4,9 @@ export type TabsVariants = VariantProps<typeof tabsTheme>;
|
|||||||
|
|
||||||
export const tabsTheme = tv({
|
export const tabsTheme = tv({
|
||||||
slots: {
|
slots: {
|
||||||
root: ['flex', 'flex-col', 'w-full'],
|
root: ['flex', 'data-[orientation=horizontal]:w-full'],
|
||||||
triggerWrapper: [
|
triggerWrapper: [
|
||||||
|
// Horizontal – default
|
||||||
'px-1',
|
'px-1',
|
||||||
'pb-5',
|
'pb-5',
|
||||||
'text-elements-low-em',
|
'text-elements-low-em',
|
||||||
@ -17,6 +18,24 @@ export const tabsTheme = tv({
|
|||||||
'data-[state=active]:font-medium',
|
'data-[state=active]:font-medium',
|
||||||
'data-[state=active]:text-elements-high-em',
|
'data-[state=active]:text-elements-high-em',
|
||||||
'data-[state=active]:border-elements-high-em',
|
'data-[state=active]:border-elements-high-em',
|
||||||
|
// Vertical
|
||||||
|
'data-[orientation=vertical]:px-3',
|
||||||
|
'data-[orientation=vertical]:py-3',
|
||||||
|
'data-[orientation=vertical]:min-w-[240px]',
|
||||||
|
'data-[orientation=vertical]:focus-ring',
|
||||||
|
'data-[orientation=vertical]:rounded-xl',
|
||||||
|
'data-[orientation=vertical]:border-transparent',
|
||||||
|
'data-[orientation=vertical]:hover:bg-base-bg-emphasized',
|
||||||
|
'data-[orientation=vertical]:hover:text-elements-mid-em',
|
||||||
|
'data-[orientation=vertical]:hover:border-transparent',
|
||||||
|
'data-[orientation=vertical]:focus-visible:border-transparent',
|
||||||
|
'data-[orientation=vertical]:focus-visible:bg-base-bg-emphasized',
|
||||||
|
'data-[orientation=vertical]:focus-visible:text-elements-mid-em',
|
||||||
|
'data-[orientation=vertical]:data-[state=active]:font-normal',
|
||||||
|
'data-[orientation=vertical]:data-[state=active]:bg-base-bg-emphasized',
|
||||||
|
'data-[orientation=vertical]:data-[state=active]:border-transparent',
|
||||||
|
'data-[orientation=vertical]:data-[state=active]:hover:text-elements-high-em',
|
||||||
|
'data-[orientation=vertical]:data-[state=active]:focus-visible:text-elements-high-em',
|
||||||
],
|
],
|
||||||
trigger: [
|
trigger: [
|
||||||
'flex',
|
'flex',
|
||||||
@ -29,14 +48,22 @@ export const tabsTheme = tv({
|
|||||||
'leading-none',
|
'leading-none',
|
||||||
'tracking-[-0.006em]',
|
'tracking-[-0.006em]',
|
||||||
'rounded-md',
|
'rounded-md',
|
||||||
'focus-ring',
|
// Horizontal – default
|
||||||
|
'data-[orientation=horizontal]:focus-ring',
|
||||||
|
// Vertical
|
||||||
|
'data-[orientation=vertical]:gap-2',
|
||||||
],
|
],
|
||||||
triggerList: [
|
triggerList: [
|
||||||
'flex',
|
'flex',
|
||||||
'shrink-0',
|
'shrink-0',
|
||||||
'gap-5',
|
'gap-5',
|
||||||
'border-b',
|
'border-b',
|
||||||
'border-border-interactive/10',
|
'border-transparent',
|
||||||
|
// Horizontal – default
|
||||||
|
'data-[orientation=horizontal]:border-border-interactive/10',
|
||||||
|
// Vertical
|
||||||
|
'data-[orientation=vertical]:flex-col',
|
||||||
|
'data-[orientation=vertical]:gap-0.5',
|
||||||
],
|
],
|
||||||
content: ['text-elements-high-em', 'grow', 'outline-none', 'tab-content'],
|
content: ['text-elements-high-em', 'grow', 'outline-none', 'tab-content'],
|
||||||
},
|
},
|
||||||
|
@ -18,12 +18,21 @@ export interface TabsProps extends ComponentPropsWithoutRef<typeof TabsRoot> {
|
|||||||
* A component that allows users to switch between different tabs.
|
* A component that allows users to switch between different tabs.
|
||||||
* @returns JSX element representing the tabs component.
|
* @returns JSX element representing the tabs component.
|
||||||
*/
|
*/
|
||||||
export const Tabs = ({ config, className, ...props }: TabsProps) => {
|
export const Tabs = ({
|
||||||
|
config,
|
||||||
|
className,
|
||||||
|
orientation = 'horizontal',
|
||||||
|
...props
|
||||||
|
}: TabsProps) => {
|
||||||
const { root } = tabsTheme(config);
|
const { root } = tabsTheme(config);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabsProvider {...config}>
|
<TabsProvider {...config} orientation={orientation}>
|
||||||
<TabsRoot {...props} className={root({ className })} />
|
<TabsRoot
|
||||||
|
{...props}
|
||||||
|
orientation={orientation}
|
||||||
|
className={root({ className })}
|
||||||
|
/>
|
||||||
</TabsProvider>
|
</TabsProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,10 +2,14 @@ import React, {
|
|||||||
createContext,
|
createContext,
|
||||||
useContext,
|
useContext,
|
||||||
type PropsWithChildren,
|
type PropsWithChildren,
|
||||||
|
ComponentPropsWithoutRef,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { TabsVariants } from './Tabs.theme';
|
import { TabsVariants } from './Tabs.theme';
|
||||||
|
import { Root as TabsRoot } from '@radix-ui/react-tabs';
|
||||||
|
|
||||||
export interface TabsProviderProps extends Partial<TabsVariants> {}
|
export interface TabsProviderProps
|
||||||
|
extends Partial<TabsVariants>,
|
||||||
|
ComponentPropsWithoutRef<typeof TabsRoot> {}
|
||||||
|
|
||||||
type TabsProviderContext = ReturnType<typeof useTabsValues>;
|
type TabsProviderContext = ReturnType<typeof useTabsValues>;
|
||||||
|
|
||||||
|
@ -27,18 +27,28 @@ const TabsTrigger = forwardRef<
|
|||||||
>(({ className, icon, children, ...props }, ref) => {
|
>(({ className, icon, children, ...props }, ref) => {
|
||||||
const config = useTabs();
|
const config = useTabs();
|
||||||
const { triggerWrapper, trigger } = tabsTheme(config);
|
const { triggerWrapper, trigger } = tabsTheme(config);
|
||||||
|
const orientation = config.orientation;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Trigger
|
<Trigger
|
||||||
ref={ref}
|
ref={ref}
|
||||||
tabIndex={-1}
|
// Disabled focus state for horizontal tabs
|
||||||
|
tabIndex={orientation === 'horizontal' ? -1 : undefined}
|
||||||
className={triggerWrapper({ className })}
|
className={triggerWrapper({ className })}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{/* Need to add button in the trigger children because there's focus state inside the children */}
|
{/* Need to add button in the trigger children because there's focus state inside the children */}
|
||||||
<button className={trigger()}>
|
<button
|
||||||
|
data-orientation={orientation}
|
||||||
|
// Disabled focus state for vertical tabs
|
||||||
|
tabIndex={orientation === 'vertical' ? -1 : undefined}
|
||||||
|
className={trigger()}
|
||||||
|
>
|
||||||
|
{/* Put the icon on the left of the text for veritcal tab */}
|
||||||
|
{orientation === 'vertical' && icon}
|
||||||
{children}
|
{children}
|
||||||
{icon}
|
{/* Put the icon on the right of the text for horizontal tab */}
|
||||||
|
{orientation === 'horizontal' && icon}
|
||||||
</button>
|
</button>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user