react-dyn-tabs
React Dynamic Tabs with full API
Features
- Based on React hook
- Open & Close & Select & Refresh
- lazy/eager loading
- Customizable style
- Full API
- Return to last used tab when closing selected tab
- PanelList can be rendered outside the TabList container
- ARIA accessible
- Supporting custom Tab component
Table of Contents
Installation
$ npm install react-dyn-tabs --save
Basic Example
import React from 'react';
import useDynTabs from 'react-dyn-tabs';
import 'react-dyn-tabs/style/react-dyn-tabs.css';
import 'react-dyn-tabs/themes/default.css';
import ContactComponent from './contact-component';
export default () => {
const options = {
tabs: [
{
id: '1',
title: 'home',
closable: false,
panelComponent: porps => <p> home content </p>
},
{
id: '2',
title: 'contact',
panelComponent: ContactComponent
}
],
selectedTabID: '1',
onLoad: function(){
}
};
const [TabList, PanelList, api] = useDynTabs(options);
return (
<div>
<TabList></TabList>
<PanelList></PanelList>
</div>
);
};
NOTE :
api Object will not be changed after re-rendering multiple times.
Its value always refers to same reference.
Options
tabs
type | default value | required | description |
---|
Array of tabData
| [] | false | initial opened tabs |
Example
const [ TabList , PanelList , api ] = useDynTabs({
tabs : [
{
id: '1',
title: 'home',
iconClass : 'fa fa-home',
closable: true,
panelComponent: porps => <p> home content </p>
},
{
id: '2',
title: 'contact',
tooltip: 'contact',
disable: true,
closable: false,
panelComponent: porps => <p> contact content </p>
}
]
});
selectedTabID
type | default value | required | description |
---|
string | ' ' | false | initial selected tab id |
Example
const [ TabList , PanelList , api ] = useDynTabs({
tabs : [
{
id: '1',
title: 'home',
iconClass : 'fa fa-home',
closable: true,
panelComponent: porps => <p> home content </p>
},
{
id: '2',
title: 'contact',
tooltip: 'contact',
disable: true,
closable: false,
panelComponent: porps => <p> contact content </p>
}
],
selectedTabID : '2'
});
direction
type | default value | required | description |
---|
string | 'ltr' | false | can be either of 'ltr' or 'rtl' |
Example
const [ TabList , PanelList , api ] = useDynTabs({ direction : 'rtl' });
or
if( api.getOption('direction') !== 'ltr') {
api.setOption('direction','ltr');
api.refresh();
}
tabComponent
type | required | description |
---|
React component | false | custom tab component |
Example
const [ TabList , PanelList , api ] = useDynTabs({
tabComponent : props => {
const { id , isSelected , api } = props;
return (
<button {...props.tabProps}>
{props.children}
{
props.iconProps &&
<span {...props.iconProps}></span>
}
</button>
);
}
});
or
const CustomTabComponent = props => {
const { id, isSelected, api } = props;
return (
<button {...props.tabProps}>
{props.children}
{
props.iconProps &&
<span {...props.iconProps}></span>
}
</button>
);
};
api.setOption('tabComponent', CustomTabComponent);
api.refresh();
defaultPanelComponent
Default value for panelComponent option.
type | required | description |
---|
React component | React element | false | |
Example
const [ TabList , PanelList , api ] = useDynTabs({
defaultPanelComponent : props => {
const { id , isSelected , api } = props;
return <div></div>
}
});
or
api.setOption('defaultPanelComponent', props => <p></p>);
api.refresh();
accessibility
type | default value | required | description |
---|
boolean | true | false | |
Example
const [ TabList , PanelList , api ] = useDynTabs({ accessibility : false });
or
if( api.getOption('accessibility') == true ){
api.setOption('accessibility',false).refresh();
}
NOTE :
This option assigns id attribute on panel element and text element inside the tab.
for having elements without id attribute, set this option to false.
onLoad
type | required | description |
---|
function | false | This event is fired only once, after first render |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onLoad : function() {
} });
api.setOption('onLoad', () => { } ).refresh();
onInit
type | required | description |
---|
function | false | This event is triggered after every render. |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onInit : function() {
} });
api.setOption('onInit', () => { } ).refresh();
onChange
type | required | description |
---|
function | false | fires when we open|close|select a tab. this event is not fired initially |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onChange : function({ currentData , perviousData }) {
} });
api.setOption('onChange', ({ currentData , perviousData }) => { } ).refresh();
beforeSelect
type | required | description |
---|
function | false |
fires when the user click on the tab, but before select them.
This event should return boolean true or false, If the event return false the tab is not selected.
|
Example
const [ TabList , PanelList , api ] = useDynTabs({ beforeSelect : function(e, id) {
} });
api.setOption('beforeSelect', (e, id) => { } ).refresh();
onSelect
type | required | description |
---|
function | false | fires after selecting tabs |
Example
const [ TabList , PanelList , api ] = useDynTabs({
onSelect : function({currentSelectedTabId , perviousSelectedTabId}) {
}
});
api.setOption('onSelect', ({currentSelectedTabId , perviousSelectedTabId}) => { } ).refresh();
onOpen
type | required | description |
---|
function | false | fires after opening tabs |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onOpen : function(openedTabIDs) {
}});
api.setOption('onOpen', (openedTabIDs) => { } ).refresh();
beforeClose
type | required | description |
---|
function | false |
fires when the user click on the close icon, but before close them.
This event should return boolean true or false, If the event return false the tab is not closed.
|
Example
const [ TabList , PanelList , api ] = useDynTabs({ beforeClose : function(e, id) {
} });
api.setOption('beforeClose', (e, id) => { } ).refresh();
onClose
type | required | description |
---|
function | false | fires after closing tabs |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onClose : function(closedTabIDs) {
}});
api.setOption('onClose', closedTabIDs => { } ).refresh();
onDestroy
type | required | description |
---|
function | false | fires before destroying useDynTabs hook |
Example
const [ TabList , PanelList , api ] = useDynTabs({ onDestroy : function() {
}});
api.setOption('onDestroy', () => { } ).refresh();
Methodes
isOpen
Return value : boolean
Parameters:
Example
const result = api.isOpen('tab ID');
open
triggers 'onInit', 'onChange' and 'onOpen' event.
Return value : Promise
Parameters:
Example
if( api.isOpen('2') == false ){
api.open({
id: '2',
title: 'contact',
tooltip: 'contact',
disable: false,
closable: true,
iconClass: '',
panelComponent: <ContactPanel></ContactPanel>
}).then(({currentDta,instance})=>{
});
}
isSelected
Return value : boolean
Parameters:
Example
const result = api.isSelected('tab ID');
select
triggers 'onInit', 'onChange' and 'onSelect' event.
Return value : Promise
Parameters:
Example
if( api.isSelected('your tab id') == false ){
api.select('your tab id').then(({currentDta,instance})=>{
});
}
close
triggers 'onInit', 'onChange' and 'onClose' event.
Return value : Promise
Parameters:
Example
if( api.isOpen('2') == true ){
api.close('2').then(({currentDta,instance})=>{
});
}
refresh
triggers onInit event.
Return value : Promise
Example
api.refresh().then(({currentDta,instance})=>{
});
getOption
Parameters:
Example
const direction = api.getOption('direction');
const onSelect = api.getOption('onSelect');
setOption
for re-rendering immediately after this function, you should call refresh method after it.
Return value : api
Parameters:
optionName : String
optionValue : string|boolean|object|function
Example
api.setOption('direction','rtl');
api.setOption('onSelect',()=>{});
getTab
get tabData by id
Return value : tabData object
Parameters:
Example
const tabData = api.getTab('3');
console.log(tabData.id);
setTab
set tabData by id.
for re-rendering immediately after this function, you should call refresh method after it.
Return value : api
Parameters:
optionName : String
optionValue : string|boolean|object|function
Example
api.setTab('disable',true);
api.setTab('panelComponent' , props => <p/>);
on
Attach an event handler function for one event.
Return value : api
Parameters:
event Name : String (can be either of of onSelect|onClose|onOpen|onInit|onChange|onDestroy)
handler : function
Example
api.on('onSelect',function(params){
const {currentSelectedTabId , perviousSelectedTabId} = params;
});
one
Attach a handler to an event. The handler is executed at most once.
Return value : api
Parameters:
event Name : String (can be either of of onSelect|onClose|onOpen|onInit|onChange|onDestroy)
handler : function
Example
api.one('onSelect',function({currentSelectedTabId , perviousSelectedTabId}){
});
off
Remove an event handler.
Return value : api
Parameters:
event Name : String (can be either of of onSelect|onClose|onOpen|onInit|onChange|onDestroy)
handler : function (A handler function previously attached for the event)
Example
const onSelectHandler = function(params){
const {currentSelectedTabId , perviousSelectedTabId} = params;
this.off('onSelect', onSelectHandler);
};
api.on('onSelect', onSelectHandler);
getCopyData
Return value : Object
Example
const { selectedTabID , openTabIDs } = api.getCopyData();
tabData
property name | type | default value | required |
---|
id | string | | false |
title | string | ' ' | false |
tooltip | string | ' ' | false |
panelComponent | can be either of React Element or React Component | | false |
closable | boolean | true | false |
iconClass | string | ' ' | false |
disable | boolean | false | false |
Example
const tabData = {
id: 'contactID',
title: 'contactTitle',
tooltip: 'contactTooltip',
disable: true,
iconClass : 'fa fa-home',
closable: false,
panelComponent: porps => <p> contact content </p>
};
const [ TabList , PanelList , api ] = useDynTabs( { tabs : [tabData] } );
if(api.isOpen(tabData.id) == false ){
api.open(tabData).then(()=>{});
}
Lazy Loading
upcoming...
Styling
react-dyn-tabs does not include any style loading by default. Default stylesheets and themes are provided and can be included in your application if desired.
import 'react-dyn-tabs/style/react-dyn-tabs.css';
import 'react-dyn-tabs/themes/default.css';
Caveats
Some actions like open, select, close and refresh cause re-rendering,
and using them immediately after calling useDynTabs hook will create an infinite loop and other bugs that most likely you don't want to cause.
you should use them inside event listeners or subscriptions.
Test
$ npm run test
License
MIT