Selectable dropdown list

This commit is contained in:
John Lyon-Smith
2018-03-26 10:29:35 -07:00
parent 90a920264b
commit bc051e3551
5 changed files with 79 additions and 39 deletions

12
website/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"version": "0.1.0",
"configurations": [
{
"name": "Chrome: Launch",
"type": "chrome",
"request": "launch",
"webRoot": "${workspaceFolder}/src"
},
]
}

View File

@@ -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>

View File

@@ -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>
)

View File

@@ -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>
)

View File

@@ -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,