Remove child flattening mechanism
parent
da75597999
commit
4537b890b1
|
@ -1,25 +1,31 @@
|
|||
import React, {Component, CSSProperties, Fragment} from 'react'
|
||||
// Librarries
|
||||
import React, {Component, CSSProperties} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import _ from 'lodash'
|
||||
|
||||
// Components
|
||||
import {ClickOutside} from 'src/shared/components/ClickOutside'
|
||||
import DropdownDivider from 'src/reusable_ui/components/dropdowns/DropdownDivider'
|
||||
import DropdownItem from 'src/reusable_ui/components/dropdowns/DropdownItem'
|
||||
import DropdownButton from 'src/reusable_ui/components/dropdowns/DropdownButton'
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
|
||||
// Types
|
||||
import {
|
||||
ComponentColor,
|
||||
ComponentSize,
|
||||
IconFont,
|
||||
DropdownMenuColors,
|
||||
} from 'src/reusable_ui/types'
|
||||
import DropdownDivider from 'src/reusable_ui/components/dropdowns/DropdownDivider'
|
||||
import DropdownItem from 'src/reusable_ui/components/dropdowns/DropdownItem'
|
||||
import DropdownButton from 'src/reusable_ui/components/dropdowns/DropdownButton'
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
// Styles
|
||||
import './Dropdown.scss'
|
||||
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface Props {
|
||||
children: Array<JSX.Element | JSX.Element[]>
|
||||
children: JSX.Element[]
|
||||
onChange: (value: any) => void
|
||||
selectedItem: string
|
||||
selectedItemKey: string
|
||||
color?: ComponentColor
|
||||
menuColor?: DropdownMenuColors
|
||||
size?: ComponentSize
|
||||
|
@ -68,7 +74,7 @@ class Dropdown extends Component<Props, State> {
|
|||
<ClickOutside onClickOutside={this.collapseMenu}>
|
||||
<div className={this.containerClassName} style={{width}}>
|
||||
{this.button}
|
||||
{this.menu}
|
||||
{this.menuItems}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
)
|
||||
|
@ -93,24 +99,29 @@ class Dropdown extends Component<Props, State> {
|
|||
}
|
||||
|
||||
private get button(): JSX.Element {
|
||||
const {selectedItem, disabled, color, size, icon} = this.props
|
||||
const {selectedItemKey, disabled, color, size, icon, children} = this.props
|
||||
const {expanded} = this.state
|
||||
|
||||
const selectedChild = children.find(
|
||||
child => child.props.itemKey === selectedItemKey
|
||||
)
|
||||
|
||||
return (
|
||||
<DropdownButton
|
||||
label={selectedItem}
|
||||
active={expanded}
|
||||
color={color}
|
||||
size={size}
|
||||
icon={icon}
|
||||
disabled={disabled}
|
||||
onClick={this.toggleMenu}
|
||||
/>
|
||||
>
|
||||
{selectedChild.props.children}
|
||||
</DropdownButton>
|
||||
)
|
||||
}
|
||||
|
||||
private get menu(): JSX.Element {
|
||||
const {selectedItem, maxMenuHeight, menuColor} = this.props
|
||||
private get menuItems(): JSX.Element {
|
||||
const {selectedItemKey, maxMenuHeight, menuColor, children} = this.props
|
||||
const {expanded} = this.state
|
||||
|
||||
if (expanded) {
|
||||
|
@ -125,11 +136,11 @@ class Dropdown extends Component<Props, State> {
|
|||
maxHeight={maxMenuHeight}
|
||||
>
|
||||
<div className="dropdown--menu">
|
||||
{this.flatChildren.map((child: JSX.Element) =>
|
||||
{React.Children.map(children, (child: JSX.Element) =>
|
||||
React.cloneElement(child, {
|
||||
...child.props,
|
||||
key: `dropdown-menu--${child.props.text}`,
|
||||
selected: child.props.text === selectedItem,
|
||||
key: child.props.itemKey,
|
||||
selected: child.props.itemKey === selectedItemKey,
|
||||
onClick: this.handleItemClick,
|
||||
})
|
||||
)}
|
||||
|
@ -142,21 +153,6 @@ class Dropdown extends Component<Props, State> {
|
|||
return null
|
||||
}
|
||||
|
||||
private get flatChildren() {
|
||||
const children = React.Children.toArray(this.props.children)
|
||||
|
||||
const childrenWithoutFragments = children.map((child: JSX.Element) => {
|
||||
if (child.type === Fragment) {
|
||||
const childArray = React.Children.toArray(child.props.children)
|
||||
return childArray
|
||||
}
|
||||
|
||||
return child
|
||||
})
|
||||
|
||||
return _.flattenDeep(childrenWithoutFragments)
|
||||
}
|
||||
|
||||
private get menuStyle(): CSSProperties {
|
||||
const {wrapText, width} = this.props
|
||||
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
import React, {Component} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import {ComponentColor, ComponentSize, IconFont} from 'src/reusable_ui/types'
|
||||
import {
|
||||
ComponentColor,
|
||||
ComponentSize,
|
||||
IconFont,
|
||||
DropdownChild,
|
||||
} from 'src/reusable_ui/types'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import './DropdownButton.scss'
|
||||
|
||||
interface Props {
|
||||
children: DropdownChild
|
||||
onClick: () => void
|
||||
disabled?: boolean
|
||||
active?: boolean
|
||||
color?: ComponentColor
|
||||
size?: ComponentSize
|
||||
icon?: IconFont
|
||||
label: string
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -24,11 +29,11 @@ class DropdownButton extends Component<Props> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {onClick, disabled, label} = this.props
|
||||
const {onClick, disabled, children} = this.props
|
||||
return (
|
||||
<button className={this.classname} onClick={onClick} disabled={disabled}>
|
||||
{this.icon}
|
||||
<span className="dropdown--selected">{label}</span>
|
||||
<span className="dropdown--selected">{children}</span>
|
||||
<span className="dropdown--caret icon caret-down" />
|
||||
</button>
|
||||
)
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
import React, {SFC} from 'react'
|
||||
import React, {Component} from 'react'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import {DropdownChild} from 'src/reusable_ui/types'
|
||||
|
||||
interface Props {
|
||||
children: DropdownChild
|
||||
itemKey: string
|
||||
text?: string
|
||||
}
|
||||
|
||||
const DropdownDivider: SFC<Props> = ({text}): JSX.Element => (
|
||||
<div className={classnames('dropdown--divider', {line: !text})}>{text}</div>
|
||||
)
|
||||
class DropdownDivider extends Component<Props> {
|
||||
public static defaultProps: Partial<Props> = {
|
||||
text: '',
|
||||
}
|
||||
|
||||
DropdownDivider.defaultProps = {
|
||||
text: '',
|
||||
public render() {
|
||||
const {text} = this.props
|
||||
|
||||
return (
|
||||
<div className={classnames('dropdown--divider', {line: !text})}>
|
||||
{text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default DropdownDivider
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import React, {Component} from 'react'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import {DropdownChild} from 'src/reusable_ui/types'
|
||||
|
||||
interface Props {
|
||||
text: string
|
||||
itemKey: string
|
||||
children: DropdownChild
|
||||
value: any
|
||||
selected?: boolean
|
||||
checkbox?: boolean
|
||||
onClick?: (value: any) => void
|
||||
value: any
|
||||
}
|
||||
|
||||
class DropdownItem extends Component<Props> {
|
||||
|
@ -15,8 +18,8 @@ class DropdownItem extends Component<Props> {
|
|||
selected: false,
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {text, selected, checkbox} = this.props
|
||||
public render(): JSX.Element {
|
||||
const {selected, checkbox} = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -28,7 +31,7 @@ class DropdownItem extends Component<Props> {
|
|||
>
|
||||
{this.checkBox}
|
||||
{this.dot}
|
||||
{text}
|
||||
{this.childElements}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -56,6 +59,12 @@ class DropdownItem extends Component<Props> {
|
|||
return <div className="dropdown-item--dot" />
|
||||
}
|
||||
}
|
||||
|
||||
private get childElements(): JSX.Element {
|
||||
const {children} = this.props
|
||||
|
||||
return <div className="dropdown-item--children">{children}</div>
|
||||
}
|
||||
}
|
||||
|
||||
export default DropdownItem
|
||||
|
|
|
@ -14,6 +14,8 @@ export enum DropdownMenuColors {
|
|||
Onyx = 'onyx',
|
||||
}
|
||||
|
||||
export type DropdownChild = Array<string | JSX.Element | Element>
|
||||
|
||||
export enum ComponentSize {
|
||||
ExtraSmall = 'xs',
|
||||
Small = 'sm',
|
||||
|
@ -63,6 +65,7 @@ export enum IconFont {
|
|||
CaretUp = 'caret-up',
|
||||
Checkmark = 'checkmark',
|
||||
Circle = 'circle',
|
||||
CircleThick = 'circle-thick',
|
||||
Clock = 'clock',
|
||||
CogOutline = 'cog-outline',
|
||||
CogThick = 'cog-thick',
|
||||
|
|
Loading…
Reference in New Issue