mirror of
https://github.com/chenasraf/redar-browser.git
synced 2026-05-17 17:58:04 +00:00
Add Tab component
This commit is contained in:
@@ -14,7 +14,8 @@ class {{Name}} extends React.Component<I.IProps, I.IState> {
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{{Name}} Component
|
||||
<h3>{{Name}} Component</h3>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as css from './Header.css'
|
||||
import * as I from './Header.module'
|
||||
import AddressBar from 'components/AddressBar/AddressBar'
|
||||
import RequestPayload from 'components/RequestPayload/RequestPayload'
|
||||
import { Tab, TabContainer } from 'components/Tabs/Tabs'
|
||||
import SelectBox, { Option, styles as selectBoxStyle } from 'components/SelectBox/SelectBox'
|
||||
import Button from 'components/Button/Button'
|
||||
import axios, { AxiosResponse } from 'axios'
|
||||
@@ -25,10 +26,12 @@ class Header extends React.Component<I.IProps, I.IState> {
|
||||
<img src={logo} />
|
||||
<NavBar store={this.props.store} />
|
||||
</div>
|
||||
<div className={css.requestDataContainer}>
|
||||
<RequestPayload store={this.props.store} />
|
||||
<RequestHeaders store={this.props.store} />
|
||||
</div>
|
||||
<TabContainer collapsible={true}>
|
||||
<Tab label="Data" className={css.requestDataContainer}>
|
||||
<RequestPayload store={this.props.store} />
|
||||
<RequestHeaders store={this.props.store} />
|
||||
</Tab>
|
||||
</TabContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
36
src/components/Tabs/Tabs.css
Normal file
36
src/components/Tabs/Tabs.css
Normal file
@@ -0,0 +1,36 @@
|
||||
@import "../../_variables.css";
|
||||
|
||||
.TabsContainer {
|
||||
/* */
|
||||
}
|
||||
|
||||
.tab-strip {
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-top: -1px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
padding: 7px 16px;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border: 1px solid #ccc;
|
||||
display: inline-block;
|
||||
background: #f0f0f0;
|
||||
text-align: center;
|
||||
margin-bottom: -1px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background: white;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
width: 100%;
|
||||
}
|
||||
6
src/components/Tabs/Tabs.css.d.ts
vendored
Normal file
6
src/components/Tabs/Tabs.css.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export const TabsContainer: string;
|
||||
export const tabsContainer: string;
|
||||
export const tabStrip: string;
|
||||
export const tabLabel: string;
|
||||
export const active: string;
|
||||
export const tabContent: string;
|
||||
22
src/components/Tabs/Tabs.module.d.ts
vendored
Normal file
22
src/components/Tabs/Tabs.module.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as React from 'react'
|
||||
|
||||
export interface ContainerProps {
|
||||
className?: string
|
||||
children: JSX.Element[] | JSX.Element
|
||||
collapsible?: boolean
|
||||
}
|
||||
|
||||
export interface ContainerState {
|
||||
children: JSX.Element[]
|
||||
activeIdx: number
|
||||
collapsed: boolean
|
||||
}
|
||||
|
||||
export interface TabProps {
|
||||
className?: string
|
||||
children: any | any[]
|
||||
label: string
|
||||
onClick?: (event: React.MouseEvent<HTMLDivElement>) => void
|
||||
}
|
||||
|
||||
export type Tab = React.ComponentElement<TabProps, React.Component<TabProps>>
|
||||
102
src/components/Tabs/Tabs.tsx
Normal file
102
src/components/Tabs/Tabs.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import * as React from 'react'
|
||||
import * as css from './Tabs.css'
|
||||
import * as I from './Tabs.module'
|
||||
import * as classNames from 'classnames'
|
||||
|
||||
export const Tab = (props: I.TabProps) => {
|
||||
const children = (props.children.constructor === Array
|
||||
? props.children : [props.children]) as I.Tab[]
|
||||
const newProps = Object.assign({}, props)
|
||||
delete newProps.children
|
||||
|
||||
return React.createElement('div', newProps, children)
|
||||
}
|
||||
|
||||
export class TabContainer extends React.Component<I.ContainerProps, I.ContainerState> {
|
||||
constructor(props: I.ContainerProps) {
|
||||
const children = (props.children.constructor === Array
|
||||
? props.children : [props.children]) as JSX.Element[]
|
||||
|
||||
super(props)
|
||||
this.checkChildrenTypes(this.props.children, this.constructor.name)
|
||||
this.state = {
|
||||
children,
|
||||
activeIdx: 0,
|
||||
collapsed: false,
|
||||
}
|
||||
}
|
||||
|
||||
private checkChildrenTypes(children: React.ReactNode | JSX.Element[] | JSX.Element, componentName: string) {
|
||||
let error: Error | null = null
|
||||
|
||||
React.Children.forEach(children, function (child: React.ReactElement<any>) {
|
||||
if (child.type !== Tab) {
|
||||
throw new Error('`' + componentName + '` children should be of type `Tab`.')
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private tabStrip() {
|
||||
return this.state.children.map((child, idx) => {
|
||||
const cls = classNames(css.tabLabel, {
|
||||
[css.active]: idx === this.state.activeIdx
|
||||
})
|
||||
const { onClick }: I.TabProps = child.props
|
||||
const onTabClick = this.onTabClick(idx, onClick)
|
||||
|
||||
return (
|
||||
<div className={cls} key={`tab-${idx}`}
|
||||
onClick={onTabClick}>
|
||||
{child.props.label}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
private tabContents() {
|
||||
const Child = this.state.children[this.state.activeIdx]
|
||||
const { children, className: tabClasses, ...rest }: I.TabProps = Child.props
|
||||
const cls = classNames(tabClasses, css.tabContent)
|
||||
|
||||
return (
|
||||
<Child.type className={cls}
|
||||
{...rest}>
|
||||
{children}
|
||||
</Child.type>
|
||||
)
|
||||
}
|
||||
|
||||
private onTabClick(idx: number, callback?: (e: React.MouseEvent<HTMLDivElement>) => void) {
|
||||
const commonClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
this.setState({ activeIdx: idx })
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
return (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
commonClick(e)
|
||||
callback(e)
|
||||
}
|
||||
}
|
||||
|
||||
return (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
commonClick(e)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const className = classNames(css.TabsContainer, this.props.className)
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className={css.tabStrip}>
|
||||
{this.tabStrip()}
|
||||
</div>
|
||||
{this.tabContents()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TabContainer
|
||||
Reference in New Issue
Block a user