Skip to content

Commit 4b9dc86

Browse files
authored
refactor: alternative header (#269)
1 parent 062758e commit 4b9dc86

7 files changed

+214
-351
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Meta, Story } from '@storybook/react/types-6-0';
2+
import React, { useMemo, useState } from 'react';
3+
import { Box } from 'rebass';
4+
import Value from '../typography/value';
5+
import { AlternativeHeader, AlternativeHeaderProps } from './AlternativeHeader';
6+
7+
export default {
8+
title: 'Quartz/AlternativeHeader',
9+
component: AlternativeHeader,
10+
} as Meta;
11+
12+
const Template: Story<AlternativeHeaderProps> = (props) => {
13+
const [active, setActive] = useState('tab');
14+
15+
const tabs = useMemo(
16+
() => [
17+
{
18+
title: 'tab',
19+
isActive: active === 'tab',
20+
onClick: () => setActive('tab'),
21+
},
22+
{
23+
title: 'another tab',
24+
isActive: active === 'another tab',
25+
onClick: () => setActive('another tab'),
26+
},
27+
{
28+
title: 'one more tab',
29+
isActive: active === 'one more tab',
30+
onClick: () => setActive('one more tab'),
31+
},
32+
{
33+
title: 'last tab',
34+
isActive: active === 'last tab',
35+
altContent: (
36+
<Value as="span" lineHeight="13px">
37+
altContent
38+
</Value>
39+
),
40+
onClick: () => setActive('last tab'),
41+
},
42+
],
43+
[active],
44+
);
45+
46+
return (
47+
<Box overflow="hidden" minHeight="200px">
48+
<AlternativeHeader {...props} tabs={tabs} />
49+
</Box>
50+
);
51+
};
52+
53+
export const Default = Template.bind({});
54+
55+
Default.args = {
56+
title: 'Cluster settings',
57+
};
58+
59+
Default.argTypes = {
60+
title: {
61+
summary: 'Title',
62+
control: {
63+
type: 'text',
64+
},
65+
},
66+
tabs: {
67+
summary: 'Tabs of header',
68+
control: {
69+
type: 'object',
70+
},
71+
},
72+
withBase: {
73+
summary: 'Adds a line under the menu',
74+
control: {
75+
type: 'boolean',
76+
},
77+
},
78+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import React, { FC, useMemo } from 'react';
2+
import { Box, BoxProps, Flex } from 'rebass';
3+
import Value from '../typography/value';
4+
import * as S from './styles';
5+
6+
export interface Tab {
7+
title: string;
8+
altContent?: React.ReactElement | null;
9+
isActive: boolean;
10+
onClick: () => void;
11+
}
12+
13+
export interface AlternativeHeaderProps extends Omit<BoxProps, 'css'> {
14+
title?: string;
15+
tabs: Tab[];
16+
withBase?: boolean;
17+
}
18+
19+
export const AlternativeHeader: FC<AlternativeHeaderProps> = ({
20+
title,
21+
tabs,
22+
withBase,
23+
...props
24+
}: AlternativeHeaderProps) => {
25+
const activeTabIndex = useMemo(() => {
26+
const index = tabs.findIndex(({ isActive }) => isActive);
27+
28+
return index < 0 ? 0 : index;
29+
}, [tabs]);
30+
31+
return (
32+
<Flex sx={S.wrapper(Boolean(title))} {...props}>
33+
<Flex justifyContent="space-between" width="100%" height="fit-content">
34+
<Value fontSize="20px" fontFamily="Inter" fontWeight="bold">
35+
{title && title}
36+
</Value>
37+
</Flex>
38+
39+
<Flex
40+
width="100%"
41+
mt="25px"
42+
justifyContent="space-between"
43+
sx={{ position: 'relative' }}
44+
>
45+
{withBase && <Flex sx={S.base} />}
46+
<Flex>
47+
{tabs.map((tab, index) => (
48+
<Box
49+
onClick={tab.onClick}
50+
key={tab.title}
51+
sx={S.tab(activeTabIndex === index)}
52+
>
53+
<Flex alignItems="baseline" pb="10px">
54+
<Value fontFamily="Inter">{tab.title}</Value>
55+
{React.isValidElement(tab.altContent) && (
56+
<Flex ml="10px">
57+
<Flex
58+
as="span"
59+
variant="light"
60+
alignItems="center"
61+
tx="variants.badges.primary"
62+
justifyContent="center"
63+
px="4px"
64+
py="2px"
65+
sx={{ borderRadius: '1px' }}
66+
>
67+
{tab.altContent}
68+
</Flex>
69+
</Flex>
70+
)}
71+
</Flex>
72+
</Box>
73+
))}
74+
</Flex>
75+
</Flex>
76+
</Flex>
77+
);
78+
};

src/components/alternative-header/alternative-header.stories.tsx

-155
This file was deleted.

src/components/alternative-header/alternative-header.styles.ts

-60
This file was deleted.

0 commit comments

Comments
 (0)