Skip to content

Instantly share code, notes, and snippets.

@carlosspohr
Created March 25, 2022 20:14
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/8e1f03f7e6de40efab570ce83847bf2a to your computer and use it in GitHub Desktop.
Save carlosspohr/8e1f03f7e6de40efab570ce83847bf2a to your computer and use it in GitHub Desktop.
import React from 'react';
interface TabProps {
className?: string,
title: string;
isActive?: boolean;
onClick?: any;
}
interface TabState {
activeIndex: number
}
class Tab extends React.Component<TabProps, TabState> {
protected keyCount:number=0;
constructor(props) {
super(props);
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
}
getKey(){
return this.keyCount++;
}
render() {
const { isActive, onClick, title } = this.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;
return (
<>
<li key={"ul-nav-li-"+this.keyCount} className="mr-2" role="presentation">
<button
className={cssTab}
onClick={onClick}
type="button">
{title}
</button>
</li>
</>
);
}
};
export default Tab;
import cx from 'classnames';
import React, { cloneElement, ReactNode } from 'react';
// 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> {
protected keyCount:number=0;
constructor(props) {
super(props);
this.keyCount = 0;
this.getKey = this.getKey.bind(this);
this.state = {
activeIndex: props.defaultActiveIndex || 0
};
console.log('contrutor:', this.props.children);
}
getKey(){
return this.keyCount++;
}
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;
if (!Array.isArray(children)) {
return this.cloneTabElement(children);
}
return children.map((element, index) => {
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 key={"ul-nav-"+this.keyCount} className="flex flex-wrap -mb-px text-sm font-medium text-center">
{
this.renderChildrenTabs()
}
</ul>
<div key={"dev-content-nav-"+this.keyCount} className="p-2 rounded-lg border-b border-l border-r border-t border-gray-200">
{
this.renderActiveTabContent()
}
</div>
</section>
);
}
};
export default Tabbed;
<Tabbed>
<Tab title={'Tab 1'} >
<p>Content 1</p>
</Tab>
<Tab title={'Tab 2'} >
<p>Content 2 </p>
</Tab>
</Tabbed>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment