Skip to content

Commit

Permalink
Merge 1caad80 into da1fd31
Browse files Browse the repository at this point in the history
  • Loading branch information
eszthoff committed Dec 20, 2019
2 parents da1fd31 + 1caad80 commit 9acce95
Show file tree
Hide file tree
Showing 34 changed files with 423 additions and 648 deletions.
18 changes: 0 additions & 18 deletions src/components/Tabs/Tab/Tab.js

This file was deleted.

14 changes: 0 additions & 14 deletions src/components/Tabs/Tab/__tests__/Tab.spec.js

This file was deleted.

10 changes: 0 additions & 10 deletions src/components/Tabs/Tab/__tests__/__snapshots__/Tab.spec.js.snap

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Tabs/Tab/index.js

This file was deleted.

24 changes: 0 additions & 24 deletions src/components/Tabs/TabContent/TabContent.js

This file was deleted.

8 changes: 0 additions & 8 deletions src/components/Tabs/TabContent/TabContent.scss

This file was deleted.

15 changes: 0 additions & 15 deletions src/components/Tabs/TabContent/__tests__/TabContent.spec.js

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Tabs/TabContent/index.js

This file was deleted.

37 changes: 0 additions & 37 deletions src/components/Tabs/TabItem/TabItem.js

This file was deleted.

53 changes: 23 additions & 30 deletions src/components/Tabs/TabItem/TabItem.scss
Original file line number Diff line number Diff line change
@@ -1,49 +1,42 @@
.TabItem {
background-color: var(--color-neutral-25);
border: {
color: var(--color-neutral);
style: solid;
top-left-radius: var(--border-radius);
top-right-radius: var(--border-radius);
width: var(--line-normal);
bottom-width: 0;
}
color: var(--link-color-normal);
cursor: pointer;
font: {
family: var(--font-family-primary);
size: var(--font-size-normal);
}
margin: {
top: var(--margin);
right: var(--margin);
left: var(--margin);
};
outline: none;
padding: var(--spacing-2x) var(--spacing-4x);
line-height: var(--line-height-normal);
text-decoration: none;
transition: border-color var(--transition-duration);
transition: all var(--transition-duration);
text-align: center;
border-bottom: 4px solid transparent;
margin-bottom: -1px;
font-weight: var(--font-weight-bold);

&:hover {
border-color: var(--color-neutral-60);
border-bottom: 4px solid var(--color-neutral-25);
color: var(--link-color-hover);
}

&:first-child {
margin-left: 0;
&--isActive {
cursor: default;
color: var(--color-foreground);
border-bottom: 4px solid var(--color-brand);

&:hover {
color: var(--color-foreground);
border-bottom: 4px solid var(--color-brand);
}
}

&:last-child {
margin-right: 0;
&--isBlock {
flex-grow: 1;
}

&--isActive {
background-color: var(--color-background);
color: var(--color-foreground);
margin-bottom: -1px;
&--disabled {
cursor: not-allowed;
color: var(--color-muted);

&:hover {
border-color: var(--color-neutral);
border-bottom: 4px solid transparent;
color: var(--color-muted);
}
}
}
52 changes: 52 additions & 0 deletions src/components/Tabs/TabItem/TabItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as React from 'react';
import bem from '../../../utils/bem';
import styles from './TabItem.scss';

export interface Props extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
/** Id of this tab */
tabId: string | number;
/** Renders an active tab. This prop will be set by TabsBar if activeTabId is defined there */
isActive?: boolean;
/** Disabled tab item */
disabled?: boolean;
/** A callback when the tab is clicked. It will not be called for active or disabled tabs. This prop will be set by TabsBar if onSelect is defined there */
onSelect?: (tabId: string | number) => void;
/** Label of the tab. Expected to be a string like node. E.g. `label` or `label <span>(3)</span>` */
children: ReactNode;
/** used for styling when TabsBar is full width. Will be set by TabsBar, no need to set manually */
isBlock?: boolean;
}

const { block } = bem('TabItem', styles);

const TabItem: React.FC<Props> = props => {
const { tabId, isActive, onSelect, disabled, isBlock, children, ...rest } = props;
const handleClick = () => {
if (!isActive && !disabled && onSelect) {
onSelect(tabId);
}
};

return (
<div
tabIndex={0}
{...rest}
{...block(props)}
role="tab"
aria-selected={isActive}
onClick={handleClick}
>
{children}
</div>
);
};

TabItem.displayName = 'TabItem';

TabItem.defaultProps = {
isActive: false,
isBlock: false,
disabled: false,
};

export default TabItem;
49 changes: 42 additions & 7 deletions src/components/Tabs/TabItem/__tests__/TabItem.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,53 @@ import toJson from 'enzyme-to-json';
import TabItem from '../TabItem';

describe('<TabItem>', () => {
it('should render a tab item correctly', () => {
const wrapper = shallow(<TabItem label="Some tab" />);
expect(toJson(wrapper)).toMatchSnapshot();
const onSelectMock = jest.fn();

afterEach(() => {
jest.resetAllMocks();
});

it('should add classes for props', () => {
const wrapper = shallow(<TabItem label="Some tab" isActive />);
it('should render a tab item correctly with minimum props', () => {
const wrapper = shallow(<TabItem tabId="1">Tab label</TabItem>);
expect(toJson(wrapper)).toMatchSnapshot();
});

it('should allow node type labels', () => {
const wrapper = shallow(<TabItem label={<strong>Some tab</strong>} />);
it('should render correctly with all props', () => {
const wrapper = shallow(
<TabItem tabId="1" isBlock isActive onSelect={onSelectMock}>
Tab label <span style={{ color: 'grey' }}>(3)</span>
</TabItem>
);
expect(toJson(wrapper)).toMatchSnapshot();
});

describe('callbacks', () => {
it('should call onSelect on simple tab', () => {
const wrapper = shallow(
<TabItem tabId="1" onSelect={onSelectMock}>
Tab label
</TabItem>
);
wrapper.find('div').simulate('click');
expect(onSelectMock).toHaveBeenCalledTimes(1);
});
it('should not call onSelect on active tab', () => {
const wrapper = shallow(
<TabItem tabId="1" isActive onSelect={onSelectMock}>
Tab label
</TabItem>
);
wrapper.find('div').simulate('click');
expect(onSelectMock).toHaveBeenCalledTimes(0);
});
it('should not call onSelect on disabled tab', () => {
const wrapper = shallow(
<TabItem tabId="1" disabled onSelect={onSelectMock}>
Tab label
</TabItem>
);
wrapper.find('div').simulate('click');
expect(onSelectMock).toHaveBeenCalledTimes(0);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<TabItem> should add classes for props 1`] = `
<a
aria-selected={true}
className="TabItem TabItem--isActive"
href="#"
role="tab"
tabIndex={0}
>
Some tab
</a>
`;
exports[`<TabItem> should allow node type labels 1`] = `
<a
exports[`<TabItem> should render a tab item correctly with minimum props 1`] = `
<div
aria-selected={false}
className="TabItem"
href="#"
onClick={[Function]}
role="tab"
tabIndex={0}
>
<strong>
Some tab
</strong>
</a>
Tab label
</div>
`;
exports[`<TabItem> should render a tab item correctly 1`] = `
<a
aria-selected={false}
className="TabItem"
href="#"
exports[`<TabItem> should render correctly with all props 1`] = `
<div
aria-selected={true}
className="TabItem TabItem--isActive TabItem--isBlock"
onClick={[Function]}
role="tab"
tabIndex={0}
>
Some tab
</a>
Tab label
<span
style={
Object {
"color": "grey",
}
}
>
(3)
</span>
</div>
`;

0 comments on commit 9acce95

Please sign in to comment.