Skip to content

Commit

Permalink
feature: croz-ltd#119 Greater control over Tab
Browse files Browse the repository at this point in the history
Added index and onTabChange props to Tab for grater crotrol

ref: croz-ltd#119
  • Loading branch information
mkatanec-croz committed Jul 5, 2023
1 parent dff0a55 commit ce5b633
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
26 changes: 19 additions & 7 deletions libs/core/src/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ type TabsProps = {
children: React.ReactNode;

/**
* Sets a tab with the corresponding index as an active tab on component render.
* Sets a tab with the corresponding index as default selected tab on component render.
*/
defaultIndex?: number;

/**
* Sets a tab with the corresponding index as an active tab on component render.
*/
index?: number;

/**
* Callback function that is called on all tab changes
*/
onTabChange?: (index: number) => void;

/**
* Determines the placement of the icon.
* Defaults to 'leading'.
Expand Down Expand Up @@ -205,6 +215,8 @@ function Tabs({
fullWidth,
children,
defaultIndex,
index,
onTabChange,
className,
iconPlacement = "leading",
scrollButtons = false,
Expand Down Expand Up @@ -235,7 +247,7 @@ function Tabs({
</CustomTab>
);
}),
[childrenArray]
[childrenArray],
);

const tabPanels = React.useMemo(
Expand All @@ -245,12 +257,12 @@ function Tabs({
{child.props.children}
</TabPanel>
)),
[childrenArray]
[childrenArray],
);

return (
<CustomTabsContext.Provider value={tabsContext}>
<ReachTabs defaultIndex={defaultIndex}>
<ReachTabs defaultIndex={defaultIndex} index={index} onChnage={onTabChange}>
<WithScrollButtons shouldWrap={scrollButtons}>
<TabList className={className}>
<CustomTabs hasScrollButtons={scrollButtons} tokens={tokens}>
Expand Down Expand Up @@ -381,7 +393,7 @@ function CustomTab({
"flex justify-center items-center h-full",
{ [tokens.Tab.withIcon.leading]: icon !== null && iconPlacement === "leading" },
{ [tokens.Tab.withIcon.trailing]: icon !== null && iconPlacement === "trailing" },
{ "flex-row-reverse text-end": iconPlacement === "trailing" }
{ "flex-row-reverse text-end": iconPlacement === "trailing" },
);

const tabClassName = cx(
Expand All @@ -398,14 +410,14 @@ function CustomTab({
tokens.Tab.base.master,
tokens.Tab.base.borderBottomWidth,
tokens.Tab.base.fontWeight,
tokens.Tab.base.fontSize
tokens.Tab.base.fontSize,
);

const iconClassName = cx(
{ [tokens.Icon.base.leading]: iconPlacement === "leading" },
{ [tokens.Icon.base.trailing]: iconPlacement === "trailing" },
{ [tokens.Icon.active]: index === selectedIndex },
{ [tokens.Icon.inactive]: index !== selectedIndex }
{ [tokens.Icon.inactive]: index !== selectedIndex },
);

const handleClick = () => {
Expand Down
2 changes: 2 additions & 0 deletions storybook/src/core/Tabs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ You can also define the icon placement to be before or after the label via `icon
(see the [leading icons](#with-leading-icons) or [trailing icons](#with-trailing-icons) stories).

Furthermore, the `defaultIndex` prop allows you to specify which tab is the default one on component render.
If you wish to have more control over your Tabs you can use `index` prop to set currently selected tab,
note that if you use `index` prop you also need to handle index changes so prop `onTabChange` must also be present

## Usage

Expand Down
16 changes: 15 additions & 1 deletion storybook/src/core/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as React from "react";

import { withDesign } from "storybook-addon-designs";

import { Tabs } from "@tiller-ds/core";
import { Button, Tabs } from "@tiller-ds/core";
import { Icon } from "@tiller-ds/icons";
import { defaultThemeConfig } from "@tiller-ds/theme";

Expand Down Expand Up @@ -203,6 +203,20 @@ export const ScrollButtons = () => (
</div>
);

export const WithIndex = () => {
const [index, setIndex] = React.useState(0);

return (
<div className="flex flex-col gap-4 w-fit">
<Tabs index={index} onTabChange={setIndex}>
<Tabs.Tab label={myAccount}>{billingTab}</Tabs.Tab>
<Tabs.Tab label={company}>{companyTab}</Tabs.Tab>
</Tabs>
<Button onClick={() => setIndex((currentIndex) => (currentIndex + 1) % 2)}>Change tab</Button>
</div>
);
};

const HideControls = {
children: { control: { disable: true } },
iconPlacement: { control: { disable: true } },
Expand Down

0 comments on commit ce5b633

Please sign in to comment.