Skip to content

Instantly share code, notes, and snippets.

@carlosspohr
Created March 25, 2022 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlosspohr/3e2c5c127a61bfa0065966bfa472d3fe to your computer and use it in GitHub Desktop.
Save carlosspohr/3e2c5c127a61bfa0065966bfa472d3fe to your computer and use it in GitHub Desktop.
<Tabbed>
<Tab title={'Tab 1'} >
<p>Content 1</p>
</Tab>
<Tab title={'Tab 2'} >
<p>Content 2 </p>
</Tab>
</Tabbed>
import PropTypes from 'prop-types';
import React from 'react';
const Tab = (props) => {
const { className, label, isActive, onClick, onTabChange} = props;
const nonSelectedTabCss="inline-block p-4 rounded-t-lg border-b-2 border-transparent hover:text-gray-600 hover:border-blue-300 dark:hover:text-gray-300";
const selectedTabCss="inline-block p-4 rounded-t-lg border-b-2 border-transparent text-blue-600 "+
"hover:text-blue-600 dark:text-blue-500 dark:hover:text-blue-400 border-blue-600 dark:border-blue-500";
let cssTab = isActive ? selectedTabCss : nonSelectedTabCss;
console.log('aba.title:', label);
return (
<>
<li className="mr-2" role="presentation">
<button
className={cssTab}
onClick={onClick}
type="button">
{label}
</button>
</li>
</>
);
};
Tab.propTypes = {
className: PropTypes.string,
label: PropTypes.string.isRequired,
isActive: PropTypes.bool,
onClick: PropTypes.func,
onTabChange:PropTypes.func
};
export default Tab;
import cx from 'classnames';
import React, { cloneElement, ReactNode } from 'react';
import Tab from './Tab';
// Leitura: https://rafaell-lycan.com/2018/criando-um-simples-tabs-component-em-react/
// Baseado no gist: https://gist.github.com/rafaell-lycan/fa4afbe3e4a1d94c4a5b5609afd017ed
// Leitura: https://rafaell-lycan.com/2018/dicas-que-todo-desenvolvedor-react-deveria-saber/
interface TabsV2Props{
className?: string,
defaultActiveIndex?: number,
Tab?:ReactNode
}
interface TabsV2State{
activeIndex: number
}
class Tabbed extends React.Component<TabsV2Props, TabsV2State> { //<TabsV2Props, TabsV2State> ou <any, any>
constructor(props) {
super(props);
this.state = {
activeIndex: props.defaultActiveIndex || 0
};
console.log('contrutor:', this.props.children);
}
handleTabClick = (tabIndex) => {
if (tabIndex !== this.state.activeIndex) {
this.setState({ activeIndex: tabIndex });
}
}
cloneTabElement = (tab, index = 0) => {
const { activeIndex } = this.state;
return (
cloneElement(tab, {
onClick: () => this.handleTabClick(index),
tabIndex: index,
isActive: index === activeIndex,
})
);
}
renderChildrenTabs = () => {
const { children } = this.props;
console.log(this);
//console.log('props: ', this.props);
if (!Array.isArray(children)) {
return this.cloneTabElement(children);
}
for (let i = 0; i < children.length; i++) {
const c = children[i];
//console.log('children: ', c.props);
//return this.cloneTabElement(c.props.children);
}
return children.map( (element, index) =>{
//console.log('element: ', element);
return this.cloneTabElement(element, index);
});
}
renderActiveTabContent(): any {
const { children } = this.props;
const { activeIndex } = this.state;
if (children[activeIndex]) {
return children[activeIndex].props.children;
}
return children[0].props.children;
}
render() {
const { className } = this.props;
const cssClass = cx('tabs', className);
return (
<section className={cssClass}>
<ul className="flex flex-wrap -mb-px text-sm font-medium text-center">
{
this.renderChildrenTabs()
}
</ul>
<div className="p-2 rounded-lg border-b border-l border-r border-t border-gray-200">
{
this.renderActiveTabContent()
}
</div>
</section>
);
}
};
//Tabbed.Tab = Tab;
export default Tabbed;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment