Skip to content

Commit

Permalink
feat: add variant prop on the Tabset component
Browse files Browse the repository at this point in the history
fix: #1880
  • Loading branch information
rgah2107 committed Oct 9, 2020
1 parent 3a195e6 commit c8ca1af
Show file tree
Hide file tree
Showing 12 changed files with 395 additions and 23 deletions.
2 changes: 1 addition & 1 deletion library/styleguideComponents/ReactComponent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default class ReactComponent extends Component {
</Pathline>
</div>
<Tabset
className="rainbow-p-horizontal_x-large rainbow-m-bottom_x-large react-rainbow-component_tabset"
className="rainbow-p-horizontal_x-large react-rainbow-component_tabset"
activeTabName={activeTabName}
onSelect={this.handleOnSelect}
>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Tab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class TabItem extends Component {
id,
ariaControls,
fullWidth,
variant,
disabled,
} = this.props;
const isActive = this.isSelected();
Expand All @@ -68,6 +69,7 @@ class TabItem extends Component {
<StyledContainer
className={className}
fullWidth={fullWidth}
variant={variant}
isActive={isActive}
style={style}
title={title}
Expand All @@ -84,6 +86,7 @@ class TabItem extends Component {
isActive={isActive}
disabled={disabled}
fullWidth={fullWidth}
variant={variant}
data-active={isActive}
>
<TruncatedText>{label}</TruncatedText>
Expand Down
71 changes: 55 additions & 16 deletions src/components/Tab/styled/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,42 @@ const StyledAnchor = attachThemeAttrs(styled.button)`
}
&:hover {
background-color: ${props => props.palette.action.hover};
color: ${props => props.palette.text.label};
z-index: 1;
}
&:focus {
text-decoration: none;
outline: 0;
border-radius: 14px 14px 0 0;
}
&::after {
content: '';
position: absolute;
left: -2px;
height: 20px;
width: 1px;
background-color: ${props => props.palette.border.divider};
box-sizing: border-box;
}
${props =>
props.variant === 'card' &&
`
&:hover {
background-color: ${props.palette.action.hover};
}
:hover::after {
background-color: transparent;
}
&::after {
content: '';
position: absolute;
left: -2px;
height: 20px;
width: 1px;
background-color: ${props.palette.border.divider};
box-sizing: border-box;
}
:hover::after {
background-color: transparent;
}
`};
${props =>
props.variant === 'linear' &&
`
border-radius: 0;
`};
@media (max-width: 600px) {
height: 100%;
Expand Down Expand Up @@ -94,15 +106,15 @@ const StyledAnchor = attachThemeAttrs(styled.button)`
border-radius: 0;
}
}
${props =>
props.isActive &&
props.variant === 'card' &&
`
z-index: 2;
background-color: ${props.palette.background.main};
color: ${props.palette.brand.main};
box-shadow: ${props.shadows.shadow_4};
border-radius: 14px 14px 0 0;
&:hover, &:active, &:visited, &:focus {
background-color: ${props.palette.background.main};
Expand Down Expand Up @@ -178,6 +190,33 @@ const StyledAnchor = attachThemeAttrs(styled.button)`
}
}
`};
${props =>
props.isActive &&
props.variant === 'linear' &&
`
z-index: 2;
color: ${props.palette.brand.main};
&:hover, &:active, &:visited, &:focus {
color: ${props.palette.brand.main};
}
@media (max-width: 600px) {
position: relative;
width: 100%;
&::before {
content: "";
height: 0.15rem;
width: 100%;
left: 0;
bottom: 0;
position: absolute;
background-color: ${props.palette.brand.main};
border-radius: 100px;
}
}
`};
${props =>
props.disabled &&
`
Expand Down
14 changes: 14 additions & 0 deletions src/components/Tab/styled/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const StyledContainer = attachThemeAttrs(styled.li)`
`};
${props =>
props.isActive &&
props.variant === 'card' &&
`
background-color: ${props.palette.background.main};
color: ${props.palette.brand.main};
Expand Down Expand Up @@ -109,6 +110,19 @@ const StyledContainer = attachThemeAttrs(styled.li)`
box-sizing: border-box;
}
`};
${props =>
props.isActive &&
props.variant === 'linear' &&
`
color: ${props.palette.brand.main};
z-index: 2;
@media (max-width: 600px) {
border-radius: 0;
position: relative;
width: 100%;
}
`};
`;

export default StyledContainer;
56 changes: 56 additions & 0 deletions src/components/Tabset/__test__/tabset.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
getChildrenTotalWidth,
getChildrenTotalWidthUpToClickedTab,
getTabIndexFromName,
getTabsMeta,
getTabMeta,
} from './../utils';
import StyledButton from './../../Tab/styled/button';

Expand All @@ -23,6 +25,8 @@ jest.mock('./../utils.js', () => ({
isNotSameChildren: jest.fn(() => false),
getUpdatedTabsetChildren: jest.fn(() => []),
getTabIndexFromName: jest.fn(() => 0),
getTabsMeta: jest.fn(() => {}),
getTabMeta: jest.fn(() => {}),
}));

const registerTabMockFn = jest.fn();
Expand Down Expand Up @@ -139,6 +143,58 @@ describe('<Tabset />', () => {
expect(component.instance().updateButtonsVisibility).toHaveBeenCalledTimes(1);
expect(component.instance().isFirstTime).toBe(false);
});
it('should call updateIndicator function if the active tab name is changed', () => {
getTabIndexFromName.mockReset();
getTabIndexFromName.mockReturnValue(0);
const component = mount(
<Tabset activeTabName="tab-1" variant="linear">
<Tab label="Tab-1" name="tab-1" registerTab={registerTabMockFn} />
<Tab label="Tab-2" name="tab-2" registerTab={registerTabMockFn} />
<Tab label="Tab-3" name="tab-3" registerTab={registerTabMockFn} />
</Tabset>,
);
component.instance().updateIndicator = jest.fn();
component.setProps({ activeTabName: 'tab-2' });
expect(component.instance().updateIndicator).toHaveBeenCalledTimes(1);
});
it('should call updateIndicator function when the tabset width is changed', () => {
getTabIndexFromName.mockReset();
getTabIndexFromName.mockReturnValue(0);
getTabsMeta.mockReset();
getTabsMeta.mockReturnValue({ width: 10 });
getTabMeta.mockReset();
getTabMeta.mockReturnValue({ left: 15 });
const component = mount(
<Tabset activeTabName="tab-1">
<Tab label="Tab-1" name="tab-1" registerTab={registerTabMockFn} />
<Tab label="Tab-2" name="tab-2" registerTab={registerTabMockFn} />
<Tab label="Tab-3" name="tab-3" registerTab={registerTabMockFn} />
</Tabset>,
);
component.instance().updateIndicator = jest.fn();
component.setState({ tabsetMeta: { width: 9 }, tabMeta: { left: 15 } });
component.setProps({ variant: 'linear' });
expect(component.instance().updateIndicator).toHaveBeenCalledTimes(1);
});
it('should call updateIndicator function when the tab position is changed', () => {
getTabIndexFromName.mockReset();
getTabIndexFromName.mockReturnValue(0);
getTabsMeta.mockReset();
getTabsMeta.mockReturnValue({ width: 10 });
getTabMeta.mockReset();
getTabMeta.mockReturnValue({ left: 15 });
const component = mount(
<Tabset activeTabName="tab-1">
<Tab label="Tab-1" name="tab-1" registerTab={registerTabMockFn} />
<Tab label="Tab-2" name="tab-2" registerTab={registerTabMockFn} />
<Tab label="Tab-3" name="tab-3" registerTab={registerTabMockFn} />
</Tabset>,
);
component.instance().updateIndicator = jest.fn();
component.setState({ tabsetMeta: { width: 10 }, tabMeta: { left: 14 } });
component.setProps({ variant: 'linear' });
expect(component.instance().updateIndicator).toHaveBeenCalledTimes(1);
});
it('should set the left button disabled to true', () => {
getLeftButtonDisabledState.mockReset();
getLeftButtonDisabledState.mockReturnValue(true);
Expand Down
1 change: 1 addition & 0 deletions src/components/Tabset/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface TabsetProps extends BaseProps {
activeTabName?: string;
onSelect?: (event: MouseEvent<HTMLElement>, name: string) => void;
fullWidth?: boolean;
variant?: 'card' | 'linear';
id?: string;
children?: ReactNode;
}
Expand Down
Loading

0 comments on commit c8ca1af

Please sign in to comment.