Skip to content

Commit

Permalink
add secondary tabs #305
Browse files Browse the repository at this point in the history
  • Loading branch information
ukorvl committed Jul 2, 2024
1 parent 430fa13 commit 27de17c
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 33 deletions.
24 changes: 14 additions & 10 deletions src/components/tabs/Tab.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { FC, ReactNode, cloneElement, isValidElement } from "react";
import { Tab as BaseTab, TabProps as BaseTabProps } from "baseui/tabs";
import { Tab as BaseTab } from "baseui/tabs";
import { getTabOverrides } from "./overrides";
import { useStyletron } from "baseui";
import { contentWrapperStyles } from "./styles";
import { contentWrapperSecondaryStyles, contentWrapperStyles } from "./styles";
import { getMergedOverrides } from "../../shared/utils/getMergedOverrides";

export type TabProps = BaseTabProps & {
startEnhancer?: ReactNode;
endEnhancer?: ReactNode;
};
import { TAB_KIND, TabProps } from "./types";

const getEnhancer = (node: ReactNode) => {
if (isValidElement(node)) {
Expand All @@ -19,15 +15,23 @@ const getEnhancer = (node: ReactNode) => {
return node;
};

const Tab: FC<TabProps> = ({ startEnhancer, endEnhancer, children, overrides: baseOverrides, ...props }) => {
const Tab: FC<TabProps> = ({
startEnhancer,
endEnhancer,
children,
overrides: baseOverrides,
kind = TAB_KIND.primary,
...props
}) => {
const [css] = useStyletron();

const tabOverrides = getTabOverrides();
const tabOverrides = getTabOverrides(kind);
const overrides = getMergedOverrides(tabOverrides, baseOverrides);
const wrapperCn = kind === TAB_KIND.primary ? css(contentWrapperStyles) : css(contentWrapperSecondaryStyles);

return (
<BaseTab {...props} overrides={overrides}>
<div className={css(contentWrapperStyles)}>
<div className={wrapperCn}>
{startEnhancer && getEnhancer(startEnhancer)}
{children}
{endEnhancer && getEnhancer(endEnhancer)}
Expand Down
27 changes: 23 additions & 4 deletions src/components/tabs/Tabs.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,30 @@ import Tabs, { ORIENTATION } from "./Tabs";
import Tab from "./Tab";
import { HeartIcon } from "../icons";
import { useState } from "react";
import { TAB_KIND } from "./types";

<Meta title="Disclosure/Tabs" component={Tabs} />

export const Template = ({ startEnhancer, endEnhancer, activeKey: baseActiveKey = "0", ...args }) => {
export const Template = ({
startEnhancer,
endEnhancer,
activeKey: baseActiveKey = "0",
tabKind = TAB_KIND.primary,
...args
}) => {
const [activeKey, setActiveKey] = useState(baseActiveKey);
const onChangeHandler = (currentKey) => {
setActiveKey(currentKey.activeKey);
};
return (
<Tabs {...args} activeKey={activeKey} onChange={onChangeHandler}>
<Tab title="Tab Link 1" startEnhancer={startEnhancer} endEnhancer={endEnhancer}>
<Tab title="Tab Link 1" startEnhancer={startEnhancer} endEnhancer={endEnhancer} kind={tabKind}>
<span>Tab Content 1</span>
</Tab>
<Tab title="Tab Link 2">
<Tab title="Tab Link 2" kind={tabKind}>
<span>Tab Content 2</span>
</Tab>
<Tab title="Tab Link 3">
<Tab title="Tab Link 3" kind={tabKind}>
<span>Tab Content 3</span>
</Tab>
</Tabs>
Expand Down Expand Up @@ -47,6 +54,12 @@ export const Template = ({ startEnhancer, endEnhancer, activeKey: baseActiveKey
<Story name="With End Enhancer" args={{ endEnhancer: <HeartIcon /> }}>
{Template.bind({})}
</Story>
<Story name="With Secondary Tab Kind" args={{ tabKind: TAB_KIND.secondary, startEnhancer: <HeartIcon /> }}>
{Template.bind({})}
</Story>
<Story name="Disabled With Secondary Tab Kind" args={{ tabKind: TAB_KIND.secondary, disabled: true }}>
{Template.bind({})}
</Story>
</Canvas>

### Tabs props
Expand Down Expand Up @@ -91,5 +104,11 @@ To use, import the components `Tabs` and `Tab` from `@nilfoundation/ui-kit`.
<Tabs orientation={TABS_ORIENTATION.vertical}>
...
</Tabs>
// With secondary tab kind
<Tabs>
<Tab title="Tab Link 3" kind={TAB_KIND.secondary}>
<span>Tab Content 3</span>
</Tab>
</Tabs>
`}
/>
5 changes: 2 additions & 3 deletions src/components/tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { FC } from "react";
import { Tabs as BaseTabs, TabsProps as BaseTabsProps, ORIENTATION } from "baseui/tabs";
import { Tabs as BaseTabs, ORIENTATION } from "baseui/tabs";
import { getTabsOverrides } from "./overrides";
import { getMergedOverrides } from "../../shared/utils/getMergedOverrides";

export type TabsProps = BaseTabsProps;
import { TabsProps } from "./types";

const Tabs: FC<TabsProps> = ({ overrides: baseOverrides, ...props }) => {
const tabsOverrides = getTabsOverrides();
Expand Down
3 changes: 1 addition & 2 deletions src/components/tabs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ import Tab from "./Tab";

export { Tabs, Tab, TABS_ORIENTATION };

export type { TabsProps } from "./Tabs";
export type { TabProps } from "./Tab";
export type { TabProps, TabsProps, TAB_KIND } from "./types";
24 changes: 17 additions & 7 deletions src/components/tabs/overrides.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { ORIENTATION, TabOverrides, TabsOverrides } from "baseui/tabs";
import {
tabActiveStyles,
tabPrimaryActiveStyles,
tabContentStyles,
tabDisabledStyles,
tabPrimaryDisabledStyles,
tabsBarStyles,
tabStyles,
tabVerticalStyles,
tabSecondaryActiveStyles,
tabSecondaryStyles,
tabPrimaryStyles,
tabPrimaryVerticalStyles,
tabSecondaryDisabledStyles,
} from "./styles";
import { TAB_KIND } from "./types";

export const getTabOverrides = (kind: TAB_KIND): TabOverrides => {
const tabStyles = kind === TAB_KIND.primary ? tabPrimaryStyles : tabSecondaryStyles;
const activeStyles = kind === TAB_KIND.primary ? tabPrimaryActiveStyles : tabSecondaryActiveStyles;
const tabDisabledStyles = kind === TAB_KIND.primary ? tabPrimaryDisabledStyles : tabSecondaryDisabledStyles;
const tabVerticalStyles = kind === TAB_KIND.primary ? tabPrimaryVerticalStyles : {};

export const getTabOverrides = (): TabOverrides => {
return {
Tab: {
style: ({ $disabled, $active, $orientation, $isFocusVisible }) => {
return {
...($orientation === ORIENTATION.vertical ? tabVerticalStyles : tabStyles),
...($active || $isFocusVisible ? tabActiveStyles : {}),
...tabStyles,
...($orientation === ORIENTATION.vertical ? tabVerticalStyles : {}),
...($active || $isFocusVisible ? activeStyles : {}),
...($disabled ? tabDisabledStyles : {}),
};
},
Expand Down
58 changes: 51 additions & 7 deletions src/components/tabs/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { COLORS } from "../../shared";
import { withoutMarginStyles } from "../../shared/styles/withoutMarginStyles";
import { expandProperty } from "inline-style-expand-shorthand";

export const tabBaseStyles = {
export const tabPrimaryBaseStyles = {
...withoutMarginStyles,
fontSize: "12px",
paddingLeft: "24px",
paddingRight: "24px",
color: COLORS.gray50,
Expand All @@ -14,26 +15,26 @@ export const tabBaseStyles = {
},
};

export const tabStyles = {
...tabBaseStyles,
export const tabPrimaryStyles = {
...tabPrimaryBaseStyles,
borderBottom: `4px solid ${COLORS.gray500}`,
};

export const tabVerticalStyles = {
...tabBaseStyles,
export const tabPrimaryVerticalStyles = {
...tabPrimaryBaseStyles,
borderRight: `4px solid ${COLORS.gray500}`,
borderBottom: "none",
};

export const tabActiveStyles = {
export const tabPrimaryActiveStyles = {
borderColor: `${COLORS.gray50} !important`,

":hover": {
borderColor: `${COLORS.gray50} !important`,
},
};

export const tabDisabledStyles = {
export const tabPrimaryDisabledStyles = {
borderColor: COLORS.gray500,
color: COLORS.gray600,

Expand All @@ -56,4 +57,47 @@ export const contentWrapperStyles = {
display: "flex",
alignItems: "center",
gridGap: "8px",
boxSizing: "border-box",
} as const;

export const contentWrapperSecondaryStyles = {
...contentWrapperStyles,
height: "32px",
...expandProperty("padding", "8px 16px"),
};

export const tabSecondaryStyles = {
color: COLORS.gray200,
height: "32px",
background: "transparent",
...expandProperty("borderRadius", "8px"),
...expandProperty("padding", "0"),
...expandProperty("margin", "4px"),
borderBottom: "none",
fontSize: "12px",
lineHeight: "16px",
transition: "background-color 0.15s, color 0.15s",

":hover": {
backgroundColor: COLORS.gray800,
},
};

export const tabSecondaryActiveStyles = {
backgroundColor: COLORS.gray50,
color: COLORS.gray900,

":hover": {
backgroundColor: COLORS.gray50,
color: COLORS.gray900,
},
};

export const tabSecondaryDisabledStyles = {
color: COLORS.gray500,
backgroundColor: "transparent",

":hover": {
backgroundColor: "transparent",
},
};
15 changes: 15 additions & 0 deletions src/components/tabs/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ReactNode } from "react";
import { TabProps as BaseTabProps, TabsProps as BaseTabsProps } from "baseui/tabs";

export type TabProps = BaseTabProps & {
startEnhancer?: ReactNode;
endEnhancer?: ReactNode;
kind?: TAB_KIND;
};

export type TabsProps = BaseTabsProps;

export enum TAB_KIND {
primary = "primary",
secondary = "secondary",
}

0 comments on commit 27de17c

Please sign in to comment.