Skip to content

Commit

Permalink
fix(Tabs): support for scrollable tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
zettca committed Jan 9, 2025
1 parent 95724e5 commit fa2704a
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 34 deletions.
2 changes: 1 addition & 1 deletion apps/docs/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
65 changes: 45 additions & 20 deletions apps/docs/src/pages/components/tabs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export const getStaticProps = async ({ params }) => {

### Usage

The `HvTabs` is controlled via the `value` and `onChange` props.
The `value` prop contains the `value` of the `HvTab`, which is its index by default.

```tsx live
import { useState } from "react";

Expand All @@ -30,9 +33,42 @@ export default function Demo() {
<HvTab label="Page 2" />
<HvTab label="Page 3" />
</HvTabs>
<HvTypography
style={{ padding: 16 }}
>{`Page ${value + 1} content`}</HvTypography>
<HvTypography className="p-sm">
{`Page ${value + 1} content`}
</HvTypography>
</div>
);
}
```

### Variants

The tabs supports `fullWidth` and `scrollable` variants, based on the [MUI Tabs](https://mui.com/material-ui/api/tabs/#tabs-prop-variant) component.

```tsx live
import { useState } from "react";

export default function Demo() {
const [value, setValue] = useState(0);

const handleChange: HvTabsProps["onChange"] = (evt, newValue) => {
setValue(newValue);
};

return (
<div className="grid gap-xs w-full">
<HvTabs variant="fullWidth" value={value}>
<HvTab label="Clickable tab 1" />
<HvTab label="Clickable tab 2" />
<HvTab label="Clickable tab 3" />
</HvTabs>
<div className="max-w-400px">
<HvTabs variant="scrollable" scrollButtons="auto" value={value}>
{[...Array(12).keys()].map((i) => (
<HvTab key={i} label={`Clickable tab ${i + 1}`} />
))}
</HvTabs>
</div>
</div>
);
}
Expand All @@ -51,19 +87,15 @@ export default function Demo() {
const [showLabels, setShowLabels] = useState(true);
const [iconPosition, setIconPosition] = useState("start");

const handleChange: HvTabsProps["onChange"] = (_, newValue) => {
setValue(newValue);
};

return (
<div className="flex flex-col w-full gap-4">
<div className="flex gap-2">
<div className="flex flex-col w-full gap-md">
<div className="flex gap-sm">
<HvCheckBox
checked={showLabels}
onChange={() => setShowLabels((p) => !p)}
label="Show labels"
/>
<div className="flex gap-2 items-center">
<div className="flex gap-sm items-center">
<HvLabel>Icon position:</HvLabel>
<HvSelect
value={iconPosition}
Expand All @@ -78,7 +110,7 @@ export default function Demo() {
</HvSelect>
</div>
</div>
<HvTabs value={value} onChange={handleChange}>
<HvTabs value={value} onChange={(_, val) => setValue(val)}>
{tabs.map((tab, index) => (
<HvTab
key={index}
Expand All @@ -96,17 +128,14 @@ const tabs = [
{
label: "Clickable tab 1",
icon: <Alert />,
iconPosition: "start",
},
{
label: "Clickable tab 2",
icon: <Reload />,
iconPosition: "start",
},
{
label: "Clickable tab 3",
icon: <Calendar />,
iconPosition: "start",
},
];
```
Expand Down Expand Up @@ -164,13 +193,9 @@ import { useState } from "react";
export default function Demo() {
const [value, setValue] = useState(0);

const handleChange: HvTabsProps["onChange"] = (_, newValue) => {
setValue(newValue);
};

return (
<div className="flex flex-col w-full gap-4">
<HvTabs value={value} onChange={handleChange} floating>
<div className="flex flex-col w-full gap-md">
<HvTabs floating value={value} onChange={(_, val) => setValue(val)}>
<HvTab label="Videos" icon={<PlayVideo />} iconPosition="start" />
<HvTab label="Photos" icon={<Picture />} iconPosition="start" />
<HvTab label="Text files" icon={<DocWord />} iconPosition="start" />
Expand Down
55 changes: 46 additions & 9 deletions packages/core/src/Tabs/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,34 @@ export const FullWidth: StoryObj<HvTabsProps> = {
},
};

export const Scrollable: StoryObj<HvTabsProps> = {
parameters: {
docs: {
description: {
story: "Tabs with scroll buttons.",
},
},
},
render: () => {
const [value, setValue] = useState(0);

return (
<div className="max-w-400px">
<HvTabs
variant="scrollable"
scrollButtons="auto"
value={value}
onChange={(_, newValue) => setValue(newValue)}
>
{[...Array(12).keys()].map((i) => (
<HvTab key={i} label={`Clickable tab ${i + 1}`} />
))}
</HvTabs>
</div>
);
},
};

export const ContentChanging: StoryObj<HvTabsProps> = {
parameters: {
docs: {
Expand Down Expand Up @@ -281,15 +309,24 @@ export const Test: StoryObj = {
iconPosition="top"
/>
</HvTabs>
<HvTabs value={0}>
<HvTab icon={<Alert />} aria-label="Alert" />
<HvTab icon={<Reload />} aria-label="Reload" />
<HvTab disabled icon={<Calendar />} aria-label="Calendar" />
</HvTabs>
<HvTabs value={0}>
<HvTab label={<HvBadge showCount count={2} text="Track events" />} />
<HvTab label={<HvBadge count={1} text="Vehicle events" />} />
</HvTabs>
<div className="max-w-500px">
<HvTabs variant="scrollable" scrollButtons="auto" value={0}>
{[...Array(12).keys()].map((i) => (
<HvTab key={i} label={`Clickable tab ${i + 1}`} />
))}
</HvTabs>
</div>
<div className="flex flex-wrap gap-xs">
<HvTabs value={0}>
<HvTab icon={<Alert />} aria-label="Alert" />
<HvTab icon={<Reload />} aria-label="Reload" />
<HvTab disabled icon={<Calendar />} aria-label="Calendar" />
</HvTabs>
<HvTabs value={0}>
<HvTab label={<HvBadge showCount count={2} text="Track events" />} />
<HvTab label={<HvBadge count={1} text="Vehicle events" />} />
</HvTabs>
</div>
</HvSimpleGrid>
),
};
Expand Down
5 changes: 1 addition & 4 deletions packages/core/src/Tabs/Tabs.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import { createClasses } from "@hitachivantara/uikit-react-utils";
export const { staticClasses, useClasses } = createClasses("HvTabs", {
root: {
minHeight: 0,
overflow: "visible",
},
indicator: {},
scroller: {
overflow: "visible !important",
},
scroller: {},
flexContainer: {
marginLeft: "3px",
},
Expand Down

0 comments on commit fa2704a

Please sign in to comment.