Basic dropdown
This commit is contained in:
156
website/src/ui/DropdownList.js
Normal file
156
website/src/ui/DropdownList.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import Radium from 'radium'
|
||||
import PropTypes from 'prop-types'
|
||||
import React, { Component } from 'react'
|
||||
import { Box, Icon } from '.'
|
||||
import { sizeInfo, colorInfo, fontInfo } from './style'
|
||||
import downArrowImage from './images/down-arrow.svg'
|
||||
import upArrowImage from './images/up-arrow.svg'
|
||||
import autobind from 'autobind-decorator'
|
||||
|
||||
@Radium
|
||||
export class DropdownList extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.array,
|
||||
render: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
open: false,
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleClick(e) {
|
||||
this.setState({ open: !this.state.open })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, render } = this.props
|
||||
const { open } = this.state
|
||||
const dropDownIconSize = 20
|
||||
const dropdownIconMargin = 8
|
||||
const dropdownBackground = 'white'
|
||||
const selectedItem = data ? data[0] : <span />
|
||||
const border = { width: sizeInfo.listBorderWidth, color: colorInfo.listBorder }
|
||||
|
||||
let dropdown = null
|
||||
|
||||
if (open) {
|
||||
dropdown = (
|
||||
<Box
|
||||
borderLeft={border}
|
||||
borderRight={border}
|
||||
borderBottom={border}
|
||||
radius={{ bottomLeft: sizeInfo.formBoxRadius, bottomRight: sizeInfo.formBoxRadius }}
|
||||
background={dropdownBackground}
|
||||
style={{
|
||||
height: 200,
|
||||
zIndex: 100,
|
||||
position: 'absolute',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Box
|
||||
borderTop={border}
|
||||
borderLeft={border}
|
||||
borderRight={border}
|
||||
borderBottom={open ? { width: sizeInfo.listBorderWidth, color: 'transparent' } : { width: sizeInfo.listBorderWidth, color: colorInfo.listBorder }}
|
||||
radius={open ? { topLeft: sizeInfo.formBoxRadius, topRight: sizeInfo.formBoxRadius } : sizeInfo.formBoxRadius}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
fontSize: fontInfo.size.large,
|
||||
fontFamily: fontInfo.family,
|
||||
}}>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
{render(selectedItem)}
|
||||
</div>
|
||||
<div>
|
||||
<img src={open ? upArrowImage : downArrowImage}
|
||||
style={{
|
||||
verticalAlign: 'middle',
|
||||
width: dropDownIconSize,
|
||||
height: dropDownIconSize,
|
||||
margin: dropdownIconMargin,
|
||||
}}
|
||||
onClick={this.handleClick} />
|
||||
</div>
|
||||
</Box>
|
||||
{dropdown}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
DropdownList.Item = Radium(class ListItem extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
active: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, active, onClick } = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: active ? colorInfo.listBackgroundActive : 'transparent',
|
||||
':hover': {
|
||||
background: colorInfo.listBackgroundHover
|
||||
},
|
||||
}} onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
DropdownList.Icon = Radium(class ListIcon extends Component {
|
||||
static propTypes = {
|
||||
name: PropTypes.string,
|
||||
size: PropTypes.number,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { size, name } = this.props
|
||||
let source = Icon.svgs[name] || Icon.svgs['placeholder']
|
||||
|
||||
return (
|
||||
<img src={source} style={{
|
||||
verticalAlign: 'middle',
|
||||
width: size,
|
||||
height: size,
|
||||
margin: sizeInfo.listIconMargin,
|
||||
}} />
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
DropdownList.Text = Radium(class ListText extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props
|
||||
|
||||
return (
|
||||
<span style={{
|
||||
color: fontInfo.color.normal,
|
||||
align: 'left',
|
||||
textAlign: 'left',
|
||||
cursor: 'default',
|
||||
paddingLeft: 8,
|
||||
}}>{children}</span>
|
||||
)
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user