Selectable dropdown list
This commit is contained in:
12
website/.vscode/launch.json
vendored
Normal file
12
website/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Chrome: Launch",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"webRoot": "${workspaceFolder}/src"
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -112,6 +112,16 @@ export class UserForm extends React.Component {
|
||||
|
||||
render() {
|
||||
const { binder } = this.state
|
||||
const teams = [
|
||||
{ id: 1, name: 'Sign of the Times' },
|
||||
{ id: 2, name: 'Trash Monsters' },
|
||||
{ id: 3, name: 'The Bigger Picker Uppers' },
|
||||
{ id: 4, name: 'Carcass Masters' },
|
||||
{ id: 5, name: 'Dust Bunnies' },
|
||||
{ id: 6, name: 'Pavement Busters' },
|
||||
{ id: 7, name: 'Don\'t Hug That Tree' },
|
||||
{ id: 8, name: 'Broken Swingers' },
|
||||
]
|
||||
|
||||
return (
|
||||
<form style={{ width: '100%', height: '100%', overflow: 'scroll' }} id='userForm' onSubmit={this.handleSubmit}>
|
||||
@@ -145,9 +155,9 @@ export class UserForm extends React.Component {
|
||||
</Row>
|
||||
</Column.Item>
|
||||
<Column.Item>
|
||||
<DropdownList render={(item) => (
|
||||
<DropdownList.Item style={{ paddingLeft: 8 }}>
|
||||
<DropdownList.Text>Team Name</DropdownList.Text>
|
||||
<DropdownList items={teams} render={(item) => (
|
||||
<DropdownList.Item key={item.id} style={{ paddingLeft: 8 }}>
|
||||
<DropdownList.Text>{item.name}</DropdownList.Text>
|
||||
</DropdownList.Item>
|
||||
)} />
|
||||
</Column.Item>
|
||||
|
||||
@@ -18,13 +18,13 @@ export class Box extends Component {
|
||||
background: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
children: PropTypes.node,
|
||||
inputRef: PropTypes.func,
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
children, background,
|
||||
children, background, inputRef, border, style, radius,
|
||||
borderTop, borderBottom, borderLeft, borderRight,
|
||||
border, style, radius,
|
||||
radiusTopLeft, radiusTopRight, radiusBottomLeft, radiusBottomRight } = this.props
|
||||
const stringify = (border) => {
|
||||
if (!border) {
|
||||
@@ -66,8 +66,9 @@ export class Box extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={[
|
||||
{
|
||||
<div
|
||||
ref={inputRef}
|
||||
style={[{
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
boxSizing: 'border-box',
|
||||
@@ -79,10 +80,7 @@ export class Box extends Component {
|
||||
borderTopRightRadius,
|
||||
borderBottomLeftRadius,
|
||||
borderBottomRightRadius,
|
||||
},
|
||||
background && { backgroundColor: background },
|
||||
style,
|
||||
]}>
|
||||
}, background && { backgroundColor: background }, style ]}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import autobind from 'autobind-decorator'
|
||||
@Radium
|
||||
export class DropdownList extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.array,
|
||||
items: PropTypes.array,
|
||||
render: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ export class DropdownList extends Component {
|
||||
super(props)
|
||||
this.state = {
|
||||
open: false,
|
||||
selectedItem: (props.items && props.items.length > 0) ? props.items[0] : {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,14 +27,15 @@ export class DropdownList extends Component {
|
||||
this.setState({ open: !this.state.open })
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleItemClick(e, item) {
|
||||
this.setState({ selectedItem: item, open: false })
|
||||
}
|
||||
|
||||
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 }
|
||||
const { render, items } = this.props
|
||||
const { open, selectedItem } = this.state
|
||||
const border = { width: sizeInfo.dropdownBorderWidth, color: colorInfo.dropdownBorder }
|
||||
|
||||
let dropdown = null
|
||||
|
||||
@@ -44,23 +46,33 @@ export class DropdownList extends Component {
|
||||
borderRight={border}
|
||||
borderBottom={border}
|
||||
radius={{ bottomLeft: sizeInfo.formBoxRadius, bottomRight: sizeInfo.formBoxRadius }}
|
||||
background={dropdownBackground}
|
||||
background={colorInfo.dropdownBackground}
|
||||
style={{
|
||||
height: 200,
|
||||
height: (this.itemHeight - sizeInfo.dropdownBorderWidth * 2) * sizeInfo.dropdownItems,
|
||||
zIndex: 100,
|
||||
position: 'absolute',
|
||||
}}
|
||||
/>
|
||||
fontSize: fontInfo.size.large,
|
||||
fontFamily: fontInfo.family,
|
||||
overflowY: 'scroll',
|
||||
}}>
|
||||
{ items && items.map((item) => (React.cloneElement(render(item), { onClick: (e) => (this.handleItemClick(e, item)), hover: true }))) }
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Box
|
||||
inputRef={(e) => {
|
||||
if (e) {
|
||||
const r = e.getBoundingClientRect()
|
||||
this.itemHeight = r.bottom - r.top
|
||||
}
|
||||
}}
|
||||
borderTop={border}
|
||||
borderLeft={border}
|
||||
borderRight={border}
|
||||
borderBottom={open ? { width: sizeInfo.listBorderWidth, color: 'transparent' } : { width: sizeInfo.listBorderWidth, color: colorInfo.listBorder }}
|
||||
borderBottom={open ? { width: sizeInfo.dropdownBorderWidth, color: 'transparent' } : border}
|
||||
radius={open ? { topLeft: sizeInfo.formBoxRadius, topRight: sizeInfo.formBoxRadius } : sizeInfo.formBoxRadius}
|
||||
style={{
|
||||
display: 'flex',
|
||||
@@ -69,15 +81,15 @@ export class DropdownList extends Component {
|
||||
fontFamily: fontInfo.family,
|
||||
}}>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
{render(selectedItem)}
|
||||
{(React.cloneElement(render(selectedItem), { hover: false }))}
|
||||
</div>
|
||||
<div>
|
||||
<img src={open ? upArrowImage : downArrowImage}
|
||||
style={{
|
||||
verticalAlign: 'middle',
|
||||
width: dropDownIconSize,
|
||||
height: dropDownIconSize,
|
||||
margin: dropdownIconMargin,
|
||||
width: sizeInfo.dropDownIconSize,
|
||||
height: sizeInfo.dropDownIconSize,
|
||||
margin: sizeInfo.dropdownIconMargin,
|
||||
}}
|
||||
onClick={this.handleClick} />
|
||||
</div>
|
||||
@@ -93,21 +105,19 @@ DropdownList.Item = Radium(class ListItem extends Component {
|
||||
children: PropTypes.node,
|
||||
active: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
hover: PropTypes.bool,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, active, onClick } = this.props
|
||||
const { children, active, hover, onClick } = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: active ? colorInfo.listBackgroundActive : 'transparent',
|
||||
':hover': {
|
||||
background: colorInfo.listBackgroundHover
|
||||
},
|
||||
}} onClick={onClick}>
|
||||
style={[
|
||||
{ width: '100%', background: active ? colorInfo.listBackgroundActive : 'transparent' },
|
||||
hover && { ':hover': { background: colorInfo.listBackgroundHover } },
|
||||
]}
|
||||
onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -26,6 +26,11 @@ let colorInfo = {
|
||||
checkboxUnchecked: '#A0A0A0',
|
||||
checkboxUncheckedHover: '#808080',
|
||||
checkmark: '#FFFFFF',
|
||||
|
||||
listBackground: '#FFFFFF',
|
||||
listBackgroundActive: '#E7E5E5',
|
||||
|
||||
dropdownBackground: '#FFFFFF',
|
||||
}
|
||||
|
||||
Object.assign(colorInfo, {
|
||||
@@ -34,10 +39,10 @@ Object.assign(colorInfo, {
|
||||
panelButtonBackgroundActive: colorInfo.headerButtonBackgroundActive,
|
||||
panelDisabledButtonBackground: colorInfo.buttonDisabledBackground,
|
||||
|
||||
listBackground: '#FFFFFF',
|
||||
listBackgroundHover: colorInfo.headerButtonBackgroundHover,
|
||||
listBackgroundActive: '#E7E5E5',
|
||||
listBorder: colorInfo.headerBorder,
|
||||
|
||||
dropdownBorder: colorInfo.headerBorder,
|
||||
})
|
||||
|
||||
const sizeInfo = {
|
||||
@@ -80,6 +85,11 @@ const sizeInfo = {
|
||||
listIcon: 25,
|
||||
listIconMargin: '5px 10px 5px 10px',
|
||||
|
||||
dropDownIconSize: 20,
|
||||
dropdownIconMargin: 5,
|
||||
dropdownItems: 6,
|
||||
dropdownBorderWidth: 1,
|
||||
|
||||
modalWidth: 450,
|
||||
modalShadowWidth: 25,
|
||||
modalMessageIcon: 150,
|
||||
|
||||
Reference in New Issue
Block a user