Selectable List in place

This commit is contained in:
John Lyon-Smith
2018-03-03 11:24:48 -08:00
parent 7756963eb2
commit 3ef0a3bdc9
19 changed files with 312 additions and 194 deletions

View File

@@ -6,7 +6,7 @@ import { reactAutoBind } from 'auto-bind2'
export default class BoundButton extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired,
content: PropTypes.string,
text: PropTypes.string,
binder: PropTypes.object.isRequired,
submit: PropTypes.string,
onClick: PropTypes.func
@@ -39,14 +39,11 @@ export default class BoundButton extends React.Component {
}
render() {
const { name, content, submit, onClick } = this.props
const { name, text, submit, onClick } = this.props
const { visible, disabled } = this.state
return (
<Button disabled={disabled} submit={submit}
onClick={onClick} name={name} visible={visible}>
{content}
</Button>
<Button disabled={disabled} submit={submit} onClick={onClick} name={name} visible={visible} text={text} />
)
}
}

View File

@@ -50,7 +50,7 @@ export default class BoundInput extends React.Component {
onChange={this.handleChange}
placeholder={placeholder} />
<br />
<Text size='small' color='alert'>{valid ? ' ' : message}</Text>
<Text size='small' color='alert' hidden={valid}>{message}</Text>
</div>
)
}

View File

@@ -2,6 +2,8 @@ import Radium from 'radium'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
// TODO: Refactor this to allow setting each border property separately
class Box extends Component {
static propTypes = {
borderTop: PropTypes.string,
@@ -9,17 +11,19 @@ class Box extends Component {
borderRight: PropTypes.string,
borderLeft: PropTypes.string,
border: PropTypes.string,
radius: PropTypes.number,
color: PropTypes.string,
children: PropTypes.node,
}
render() {
const { children, color, borderTop, borderBottom, borderLeft, borderRight, border } = this.props
const { children, color, borderTop, borderBottom, borderLeft, borderRight, border, radius } = this.props
return (
<div style={[
{ height: '100%', width: '100%' },
color && { backgroundColor: color },
radius && { borderRadius: radius },
border ? { border } : { borderTop, borderBottom, borderLeft, borderRight }]}>
{children}
</div>

View File

@@ -3,15 +3,17 @@ import PropTypes from 'prop-types'
import React, { Component } from 'react'
import style from './Button.style'
import { sizeInfo } from './style'
import { Text } from '.'
class Button extends Component {
static propTypes = {
children: PropTypes.node,
text: PropTypes.node,
visible: PropTypes.bool,
disabled: PropTypes.bool,
name: PropTypes.string,
onClick: PropTypes.func,
submit: PropTypes.string,
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
}
static defaultProps = {
@@ -20,13 +22,14 @@ class Button extends Component {
}
render() {
const { name, children, submit, visible, disabled, onClick } = this.props
const { name, submit, visible, disabled, width, text, onClick } = this.props
return (
<button name={name} type={!visible ? 'hidden' : submit ? 'submit' : 'button'}
disabled={disabled} form={submit}
style={[style.base, { minWidth: sizeInfo.minButtonWidth }]} onClick={onClick}>
{children}
style={[style.base, { width, minWidth: sizeInfo.minButtonWidth }]}
onClick={onClick}>
<Text color='inverse'>{text}</Text>
</button>
)
}

View File

@@ -1,12 +1,9 @@
import { colorInfo, fontInfo } from './style'
import { colorInfo } from './style'
export default {
base: {
height: '100%',
borderRadius: '10px',
fontFamily: fontInfo.family,
color: '#FFFFFF',
fontSize: fontInfo.size.large,
borderRadius: 10,
background: colorInfo.buttonBackgroundHover,
verticalAlign: 'middle',
padding: '0 15px 0 15px',
@@ -16,6 +13,10 @@ export default {
},
':disabled': {
background: colorInfo.disabledButtonBackground,
},
':active': {
borderWidth: 0,
background: colorInfo.buttonBackgroundActive,
}
}
}

View File

@@ -7,13 +7,17 @@ class Column extends Component {
children: PropTypes.node,
minHeight: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
height: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
fillParent: PropTypes.bool,
}
render() {
const { children, minHeight, height } = this.props
const { children, minHeight, height, fillParent } = this.props
return (
<div style={{ width: '100%', display: 'flex', height, minHeight, flexDirection: 'column' }}>{children}</div>
<div style={[
{ display: 'flex', height, minHeight, flexDirection: 'column' },
fillParent && { position: 'absolute', width: '100%', height: '100%' },
]}>{children}</div>
)
}
}
@@ -31,7 +35,7 @@ Column.Item = Radium(class StackLayoutItem extends Component {
const flexGrow = grow ? 1 : null
return (
<div style={{ height, minHeight, flexGrow }}>
<div style={{ position: 'relative', height, minHeight, flexGrow }}>
{children}
</div>
)

View File

@@ -8,10 +8,12 @@ export default class Icon extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
size: PropTypes.number,
margin: PropTypes.number,
}
static defaultProps = {
size: 50
size: 50,
margin: sizeInfo.iconMargin,
}
static svgs = {
@@ -25,9 +27,8 @@ export default class Icon extends Component {
}
render() {
let { size, name } = this.props
let { size, name, margin } = this.props
let source = Icon.svgs[name] || Icon.svgs['placeholder']
const margin = sizeInfo.iconMargin
size -= margin * 2

View File

@@ -1,30 +1,99 @@
import Radium from 'radium'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { fontInfo } from './style'
import { Box, Icon } from '.'
import { sizeInfo, colorInfo, fontInfo } from './style'
class List extends Component {
static propTypes = {
size: PropTypes.string,
margin: PropTypes.number,
children: PropTypes.node
}
static defaultProps = {
size: 'medium',
margin: 0
}
render() {
const { children } = this.props
const listGapItem = (<div style={{ background: 'transparent', height: sizeInfo.listTopBottomGap }} />)
return (
<span style={{
display: 'inline-block',
fontSize: fontInfo.size[this.props.size],
<div style={{
position: 'absolute',
width: '100%',
height: '100%',
fontSize: fontInfo.size.medium,
fontFamily: fontInfo.family,
margin: this.props.margin
}}>{this.props.children}</span>
}}>
<Box border={`${sizeInfo.listBorderWidth}px solid ${colorInfo.listBorder}`} radius={sizeInfo.formBoxRadius}>
{listGapItem}
<div style={{ overflow: scroll }}>
{children}
</div>
{listGapItem}
</Box>
</div>
)
}
}
List.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={{
display: 'table-row',
background: active ? colorInfo.listBackgroundActive : colorInfo.listBackground,
}} onClick={onClick}>
{children}
</div>
)
}
})
List.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={{
display: 'table-cell',
verticalAlign: 'middle',
width: size,
height: size,
margin: '5px 10px 5px 10px', // TODO: Put in style.js
}} />
)
}
})
List.Text = Radium(class ListText extends Component {
static propTypes = {
children: PropTypes.node,
}
render() {
const { children } = this.props
return (
<span style={{
display: 'table-cell',
width: '100%',
color: fontInfo.color.normal,
align: 'left',
verticalAlign: 'middle',
textAlign: 'left'
}}>{children}</span>
)
}
})
export default Radium(List)

View File

@@ -22,7 +22,7 @@ class PanelButton extends Component {
]}
onClick={onClick}>
<div style={{ position: 'relative' }}>
<Icon name={icon} size={sizeInfo.panelIconSize} />
<Icon name={icon} size={sizeInfo.panelIconSize} margin={0} />
<span style={{
position: 'absolute',
top: sizeInfo.panelTextOffset,

View File

@@ -7,13 +7,17 @@ class Row extends Component {
children: PropTypes.node,
minWidth: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
fillParent: PropTypes.bool,
}
render() {
const { children, width, minWidth } = this.props
const { children, width, minWidth, fillParent } = this.props
return (
<div style={{ height: '100%', display: 'flex', width, minWidth, flexDirection: 'row' }}>{children}</div>
<div style={[
{ display: 'flex', minWidth, width, flexDirection: 'row' },
fillParent && { position: 'absolute', width: '100%', height: '100%' },
]}>{children}</div>
)
}
}
@@ -31,7 +35,9 @@ Row.Item = Radium(class RowLayoutItem extends Component {
const flexGrow = grow ? 1 : null
return (
<div style={{ width, minWidth, flexGrow }}>{children}</div>
<div style={{ position: 'relative', width, minWidth, flexGrow }}>
{children}
</div>
)
}
})

View File

@@ -10,6 +10,7 @@ class Text extends Component {
margin: PropTypes.number,
children: PropTypes.node,
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
hidden: PropTypes.bool,
align: PropTypes.string,
}
@@ -21,10 +22,10 @@ class Text extends Component {
}
render() {
const { margin, width, align, children } = this.props
const { margin, width, align, hidden, children } = this.props
return (
<span style={{
<span style={[{
display: 'inline-block',
fontSize: fontInfo.size[this.props.size],
fontFamily: fontInfo.family,
@@ -32,7 +33,7 @@ class Text extends Component {
textAlign: align,
margin,
width,
}}>{children}</span>
}, hidden && { visibility: 'hidden' }]}>{children}</span>
)
}
}

View File

@@ -6,9 +6,11 @@ let colorInfo = {
grayText: '#B0B0B0',
buttonBackground: '#3498DB',
buttonBackgroundHover: '#3CB0FD',
buttonBackgroundActive: '#1A72AC',
headerButtonBackground: '#FAFAFA',
headerButtonBackgroundHover: '#DADADA',
headerButtonBackgroundActive: '#AAAAAA',
headerBorder: '#B2B2B2',
disabledButtonBackground: '#E0E0E0',
modalBackground: '#FFFFFF',
uncheckedCheckbox: '#A0A0A0',
@@ -20,6 +22,10 @@ Object.assign(colorInfo, {
panelButtonBackgroundHover: colorInfo.headerButtonBackgroundHover,
panelButtonBackgroundActive: colorInfo.headerButtonBackgroundActive,
disabledPanelButtonBackground: colorInfo.disabledButtonBackground,
listBackground: '#FFFFFF',
listBackgroundHover: colorInfo.headerButtonBackgroundHover,
listBackgroundActive: '#E7E5E5',
listBorder: colorInfo.headerBorder,
})
const sizeInfo = {
@@ -27,12 +33,15 @@ const sizeInfo = {
imageMargin: 5, // The margin around images
iconMargin: 10, // The margin around icons
headerBorderWidth: 1,
listBorderWidth: 1,
buttonHeight: 40,
minButtonWidth: 100,
checkboxSize: 25,
panelButtonSize: 200,
panelIconSize: 170,
panelTextOffset: 130,
panelTextOffset: 120,
formBoxRadius: 5,
listTopBottomGap: 10,
}
const fontInfo = {