Skip to content

Commit

Permalink
fix(tabs): init tabs with custom active index other than zero
Browse files Browse the repository at this point in the history
Merge pull request #677 from remija/fix/tabs-activateindex-oninit
  • Loading branch information
guillaume-chervet committed Sep 11, 2020
2 parents 273dd80 + 3246fd0 commit 04c979a
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 27 deletions.
16 changes: 16 additions & 0 deletions packages/tabs/src/Tabs.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ describe('Tabs', () => {
const secondTabLink = wrapper.find('button').at(1);
secondTabLink.simulate('click');

expect(wrapper.find('.af-tabs__content').text()).toBe('Content 2');
});

it('should display the second tab specified by activeIndex prop', () => {
const wrapper = mount(
<Tabs activeIndex="1">
<Tabs.Tab title="Title 1">Content 1</Tabs.Tab>
<Tabs.Tab title="Title 2">Content 2</Tabs.Tab>
</Tabs>
);

expect(wrapper.find('.af-tabs__content').text()).toBe('Content 2');

const secondTabLink = wrapper.find('button').at(0);
secondTabLink.simulate('click');

expect(wrapper.find('.af-tabs__content').text()).toBe('Content 1');
});
});
51 changes: 45 additions & 6 deletions packages/tabs/src/TabsCore.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,55 @@
import { onChangeEvent, TabsContainerState } from './TabsCore';
import * as React from 'react';
import { create } from 'react-test-renderer';
import TabsCore, { onChangeEvent } from './TabsCore';
import Tab from './Tab';

describe('TabsCore tests suite', () => {

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

it('should init activate index in state function', () => {

// given
const givenActivateIndex = '3';

const setStateMock = jest.fn();
const useStateMock: any = jest.fn().mockImplementation((initState: any) => {
return [initState, setStateMock];
});

jest.spyOn(React, 'useState').mockImplementation(useStateMock);

const onChangeMock = jest.fn(x => {});

create(
<TabsCore
onChange={onChangeMock}
activeIndex={givenActivateIndex}
>
<Tab title="title tab1" classModifier="modifier 1">
<span>Content</span>
</Tab>
<Tab title="title tab2" classModifier="modifier">
<span>Content</span>
</Tab>
<Tab title="title tab3" classModifier="modifier 1">
<span>Content</span>
</Tab>
</TabsCore>
);

expect(useStateMock).toHaveBeenNthCalledWith(1, givenActivateIndex);
});

it('should return correct onChange function', () => {
const onChangeMock = jest.fn(x => {});
const setStateMock = jest.fn(x => {});
const fakeState: TabsContainerState = {
activeIndex: '0',
};
onChangeEvent(onChangeMock)(setStateMock )(fakeState)(
onChangeEvent(onChangeMock)(setStateMock )(
{ id: '3' }
);
expect(setStateMock).toBeCalledWith({activeIndex: '3'});
expect(setStateMock).toBeCalledWith('3');
expect(onChangeMock).toBeCalledWith('3');
});
});
33 changes: 13 additions & 20 deletions packages/tabs/src/TabsCore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import * as React from 'react';
import { useState } from 'react';
import TabsStateless, { TabsStatelessProps } from './TabsStateless';

export type TabsContainerState = {
activeIndex: string;
};

const defaultState = { activeIndex: '0' };
const DEFAULT_ACTIVE_INDEX: string = '0';

export type TabsCoreProps = Tabs & Omit<TabsStatelessProps, 'activeIndex'>;

Expand All @@ -15,30 +11,27 @@ interface Tabs {
activeIndex?: string;
}

export const onChangeEvent = (onChange: Function) => (setState: Function) => (
state: any
) => (e: any) => {
export const onChangeEvent = (onChange: Function) => (setState: Function) => (e: any) => {
if (onChange) {
onChange(e.id);
}
setState({
...state,
activeIndex: e.id,
});
setState(e.id);
};

const TabsCore: React.FunctionComponent<TabsCoreProps> = ({
activeIndex,
onChange,
...otherProps
}) => {
const [state, setState] = useState<TabsContainerState>(defaultState);
const TabsCore: React.FunctionComponent<TabsCoreProps> = (
{
activeIndex = DEFAULT_ACTIVE_INDEX,
onChange,
...otherProps
}) => {

const [stateActiveIndex, setActiveIndex] = useState<string>(activeIndex);

return (
<TabsStateless
activeIndex={activeIndex || state.activeIndex}
activeIndex={stateActiveIndex}
{...otherProps}
onChange={onChangeEvent(onChange)(setState)(state)}
onChange={onChangeEvent(onChange)(setActiveIndex)}
/>
);
};
Expand Down
2 changes: 1 addition & 1 deletion storybook/storybook/src/packages/tabs/src/Tabs.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const titleWithBadgeAndRightIcon = (
);

const TabsStory = () => (
<Tabs onChange={action('OnChange')}>
<Tabs onChange={action('OnChange')} activeIndex={text('activeIndex', '1')}>
<Tabs.Tab
title={titleWithLeftIcon}
classModifier={text('classModifier', 'has-icon-left')}
Expand Down

0 comments on commit 04c979a

Please sign in to comment.