Skip to content

Commit

Permalink
Merge pull request #61 from JayaShakthi97/feat-tabs
Browse files Browse the repository at this point in the history
feat(react): add `Tabs` component
  • Loading branch information
JayaShakthi97 authored Mar 9, 2023
2 parents 7276448 + 2d08149 commit 0d93e20
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/react/.storybook/story-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type Stories =
| 'SignIn'
| 'Stepper'
| 'Tab'
| 'Tabs'
| 'TextField'
| 'Toolbar'
| 'Tooltip'
Expand Down Expand Up @@ -252,6 +253,9 @@ const StoryConfig: StorybookConfig = {
Tab: {
hierarchy: `${StorybookCategories.Navigation}/Tab`,
},
Tabs: {
hierarchy: `${StorybookCategories.Navigation}/Tabs`,
},
TextField: {
hierarchy: `${StorybookCategories.Inputs}/Text Field`,
},
Expand Down
86 changes: 86 additions & 0 deletions packages/react/src/components/Tabs/Tabs.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs';
import {useArgs} from '@storybook/client-api';
import dedent from 'ts-dedent';
import StoryConfig from '../../../.storybook/story-config.ts';
import Tabs from './Tabs.tsx';
import Tab from '../Tab';

export const meta = {
component: Tabs,
title: StoryConfig.Tabs.hierarchy,
};

<Meta title={meta.title} component={meta.component} />

export const Template = args => {
const [{value}, updateArgs] = useArgs();
const handleChange = (event, newValue) => {
updateArgs({value: newValue});
};
return (
<Tabs value={value} onChange={handleChange} {...args}>
<Tab label="Tab One" />
<Tab label="Tab Two" />
<Tab label="Tab Three" />
<Tab label="Tab Four" />
<Tab label="Tab Five" />
</Tabs>
);
};

# Tabs

- [Overview](#overview)
- [Props](#props)
- [Usage](#usage)
- [Variants](#variants)

## Overview

Tabs component can be used to implement navigation between different views or sections at the same level of hierarchy.

<Canvas>
<Story name="Overview">
{Template.bind({})}
</Story>
</Canvas>

## Props

<ArgsTable story="Overview" />

## Usage

Import and use the `Tabs` component in your components as follows.

<Source
language="jsx"
dark
format
code={dedent`
import Tab from '@oxygen-ui/react/Tab';
import Tabs from '@oxygen-ui/react/Tabs';\n
function Demo() {
return (
<Tabs value={value} onChange={handleChange}>
<Tab label="Tab One" />
<Tab label="Tab Two" />
<Tab label="Tab Three" />
<Tab label="Tab Four" />
<Tab label="Tab Five" />
</Tabs>
);
}`}
/>

## Variants

### Scrollable

Variation that makes the tabs header scrollable based on the viewport width.

<Canvas>
<Story name="Scrollable" args={{variant: 'scrollable'}}>
{Template.bind({})}
</Story>
</Canvas>
52 changes: 52 additions & 0 deletions packages/react/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import MuiTabs, {TabsProps as MuiTabsProps} from '@mui/material/Tabs';
import clsx from 'clsx';
import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react';
import {WithWrapperProps} from '../../models';
import {composeComponentDisplayName} from '../../utils';
import Box from '../Box';
import Divider from '../Divider';
import './tabs.scss';

export type TabsProps<C extends ElementType = ElementType> = {
component?: C;
} & Omit<MuiTabsProps<C>, 'component'>;

const COMPONENT_NAME: string = 'Tabs';

const Tabs: ForwardRefExoticComponent<TabsProps> & WithWrapperProps = forwardRef(
<C extends ElementType>(props: TabsProps<C>, ref: MutableRefObject<HTMLButtonElement>): ReactElement => {
const {className, ...rest} = props;

const classes: string = clsx('oxygen-tabs', className);

return (
<Box className={classes}>
<MuiTabs ref={ref} {...rest} />
<Divider />
</Box>
);
},
) as ForwardRefExoticComponent<TabsProps> & WithWrapperProps;

Tabs.displayName = composeComponentDisplayName(COMPONENT_NAME);
Tabs.muiName = COMPONENT_NAME;

export default Tabs;
32 changes: 32 additions & 0 deletions packages/react/src/components/Tabs/__test__/Tabs.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import {render} from '@unit-testing';
import Tabs from '../Tabs';

describe('Tabs', () => {
it('should render successfully', () => {
const {baseElement} = render(<Tabs />);
expect(baseElement).toBeTruthy();
});

it('should match the snapshot', () => {
const {baseElement} = render(<Tabs />);
expect(baseElement).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Tabs should match the snapshot 1`] = `
<body>
<div>
<div
class="oxygen-box oxygen-tabs MuiBox-root css-0"
>
<div
class="MuiTabs-root css-1ujnqem-MuiTabs-root"
>
<div
class="MuiTabs-scroller MuiTabs-fixed css-jpln7h-MuiTabs-scroller"
style="overflow: hidden; margin-bottom: 0px;"
>
<div
class="MuiTabs-flexContainer css-heg063-MuiTabs-flexContainer"
role="tablist"
/>
<span
class="MuiTabs-indicator css-e656d-MuiTabs-indicator"
style="left: 0px; width: 0px;"
/>
</div>
</div>
<hr
class="MuiDivider-root MuiDivider-fullWidth oxygen-divider css-f1a6nn-MuiDivider-root"
/>
</div>
</div>
</body>
`;
20 changes: 20 additions & 0 deletions packages/react/src/components/Tabs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export {default} from './Tabs';
export type {TabsProps} from './Tabs';
21 changes: 21 additions & 0 deletions packages/react/src/components/Tabs/tabs.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

.oxygen-tabs {
/** Add Styles */
}

0 comments on commit 0d93e20

Please sign in to comment.