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

@@ -7,7 +7,7 @@ import { HeaderButton, Column, Row, Text, Box } from 'ui'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import logoImage from 'images/logo.png'
import { versionInfo } from './version'
import { sizeInfo } from 'ui/style'
import { sizeInfo, colorInfo } from 'ui/style'
import { api } from 'src/API'
import { reactAutoBind } from 'auto-bind2'
@@ -59,7 +59,7 @@ export class App extends Component {
<Router basename='/'>
<Column minHeight='100vh'>
<Column.Item height={sizeInfo.headerHeight - sizeInfo.headerBorderWidth}>
<Box color='#FAFAFA' borderBottom={`${sizeInfo.headerBorderWidth}px solid #B2B2B2`}>
<Box color={colorInfo.headerButtonBackground} borderBottom={`${sizeInfo.headerBorderWidth}px solid ${colorInfo.headerBorder}`}>
<Row minWidth='100vw'>
<Row.Item>{headerButtonsLeft}</Row.Item>
<Row.Item grow />
@@ -67,24 +67,20 @@ export class App extends Component {
</Row>
</Box>
</Column.Item>
<Column.Item grow />
<Switch>
<Route path='/login' component={Login} />
<Route path='/confirm-email' component={ConfirmEmail} />
<Route path='/reset-password' component={ResetPassword} />
<Route path='/forgot-password' component={ForgotPassword} />
<ProtectedRoute path='/profile' component={Profile} />
<ProtectedRoute path='/users' component={Users} />
<ProtectedRoute path='/teams' component={Users} />
<ProtectedRoute path='/system' component={Users} />
<ProtectedRoute path='/logout' component={Logout} />
<ProtectedRoute path='/' component={Home} />
</Switch>
<Column.Item>
<Switch>
<Route path='/login' component={Login} />
<Route path='/confirm-email' component={ConfirmEmail} />
<Route path='/reset-password' component={ResetPassword} />
<Route path='/forgot-password' component={ForgotPassword} />
<ProtectedRoute path='/profile' component={Profile} />
<ProtectedRoute path='/users' component={Users} />
<ProtectedRoute path='/teams' component={Users} />
<ProtectedRoute path='/system' component={Users} />
<ProtectedRoute path='/logout' component={Logout} />
<ProtectedRoute path='/' component={Home} />
</Switch>
</Column.Item>
<Column.Item grow />
<Column.Item>
<Box color='#FAFAFA' borderTop={`${sizeInfo.headerBorderWidth}px solid #B2B2B2`}>
<Box color={colorInfo.headerButtonBackground} borderTop={`${sizeInfo.headerBorderWidth}px solid ${colorInfo.headerBorder}`}>
<Text color='dimmed' margin={10}>{'v' + versionInfo.version} {versionInfo.copyright}</Text>
</Box>
</Column.Item>

View File

@@ -1,4 +1,4 @@
import React from 'react'
import React, { Component, Fragment } from 'react'
import PropTypes from 'prop-types'
import { regExpPattern } from 'regexp-pattern'
import { api } from 'src/API'
@@ -10,7 +10,7 @@ import { FormBinder } from 'react-form-binder'
import { reactAutoBind } from 'auto-bind2'
import { sizeInfo } from 'ui/style'
export class Login extends React.Component {
export class Login extends Component {
static propTypes = {
history: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
}
@@ -96,68 +96,74 @@ export class Login extends React.Component {
const { messageModal, waitModal } = this.state
return (
<Row minHeight='100%'>
<Row.Item grow />
<Row.Item width='450px'>
<form onSubmit={this.handleSubmit} id='loginForm'>
<Column minHeight='100%'>
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item>
<Image source={headerLogo} width={250} />
</Row.Item>
<Row.Item grow />
</Row>
</Column.Item>
<Column.Item>
<BoundInput label='Email' name='email'
placeholder='example@xyz.com' binder={this.state.binder}
message='Enter the email address associated with your account.' />
</Column.Item>
<Column.Item>
<BoundInput password label='Password' name='password'
binder={this.state.binder} message='Enter your password.' />
</Column.Item>
<Column.Item>
<Row>
<Row.Item>
<Link to='/forgot-password'>Forgot your password?</Link>
</Row.Item>
<Row.Item grow />
<Row.Item>
<BoundCheckbox label='Remember Me' name='rememberMe' binder={this.state.binder} />
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={20} />
<Column.Item height={sizeInfo.buttonHeight}>
<Row>
<Row.Item grow />
<Row.Item>
<BoundButton name='submit' content='Login' submit='loginForm' binder={this.state.binder} />
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={20} />
<Column.Item>
<Text>
Please contact <Link to={`mailto:${versionInfo.supportEmail}`}>{versionInfo.supportEmail}</Link> to request login credentials.
</Text>
</Column.Item>
</Column>
</form>
</Row.Item>
<Row.Item grow />
<Fragment>
<Column.Item grow />
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item width='450px'>
<form onSubmit={this.handleSubmit} id='loginForm'>
<Column minHeight='100%'>
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item>
<Image source={headerLogo} width={250} />
</Row.Item>
<Row.Item grow />
</Row>
</Column.Item>
<Column.Item>
<BoundInput label='Email' name='email'
placeholder='example@xyz.com' binder={this.state.binder}
message='Enter the email address associated with your account.' />
</Column.Item>
<Column.Item>
<BoundInput password label='Password' name='password'
binder={this.state.binder} message='Enter your password.' />
</Column.Item>
<Column.Item>
<Row>
<Row.Item>
<Link to='/forgot-password'>Forgot your password?</Link>
</Row.Item>
<Row.Item grow />
<Row.Item>
<BoundCheckbox label='Remember Me' name='rememberMe' binder={this.state.binder} />
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={20} />
<Column.Item height={sizeInfo.buttonHeight}>
<Row>
<Row.Item grow />
<Row.Item>
<BoundButton name='submit' text='Login' submit='loginForm' binder={this.state.binder} />
</Row.Item>
</Row>
</Column.Item>
<Column.Item height={20} />
<Column.Item>
<Text>
Please contact <Link to={`mailto:${versionInfo.supportEmail}`}>{versionInfo.supportEmail}</Link> to request login credentials.
</Text>
</Column.Item>
</Column>
</form>
</Row.Item>
<Row.Item grow />
</Row>
</Column.Item>
<Column.Item grow>
<WaitModal active={waitModal} message='Logging in...' />
<WaitModal active={waitModal} message='Logging in...' />
<MessageModal error open={!!messageModal}
icon={messageModal ? messageModal.icon : ''}
message={messageModal ? messageModal.message : ''}
detail={messageModal ? messageModal.detail : ''}
onDismiss={this.handleMessageModalDismiss} />
</Row>
<MessageModal error open={!!messageModal}
icon={messageModal ? messageModal.icon : ''}
message={messageModal ? messageModal.message : ''}
detail={messageModal ? messageModal.detail : ''}
onDismiss={this.handleMessageModalDismiss} />
</Column.Item>
</Fragment>
)
}
}

View File

@@ -1,21 +1,21 @@
import React from 'react'
import React, { Component, Fragment } from 'react'
import PropTypes from 'prop-types'
import { Row, Column, PanelButton } from 'ui'
export class Home extends React.Component {
export class Home extends Component {
static propTypes = {
history: PropTypes.object
}
render() {
return (
<Column>
<Fragment>
<Column.Item grow />
<Column.Item>
<Row>
<Row.Item grow />
<Row.Item>
<PanelButton icon='users' text='Users' onClick={() => (this.props.history.replace('/users'))} />
<PanelButton icon='users' text='Users' onClick={() => (this.props.history.push('/users'))} />
</Row.Item>
<Row.Item width={30} />
<Row.Item>
@@ -29,7 +29,7 @@ export class Home extends React.Component {
</Row>
</Column.Item>
<Column.Item grow />
</Column>
</Fragment>
)
}
}

View File

@@ -68,7 +68,7 @@ export class ChangeEmailModal extends React.Component {
binder={this.state.binder} />
</Column.Item>
<Column.Item>
<BoundButton primary submit form='emailForm' name='submit' binder={this.state.binder}>
<BoundButton primary submit='emailForm' name='submit' binder={this.state.binder}>
<Icon name='checkmark' /> OK
</BoundButton>
<Button color='red' onClick={this.handleClick}>

View File

@@ -1,8 +1,14 @@
import React from 'react'
import { Column, Text } from 'ui'
export const UserFormPlaceholder = () => (
<div className='user-form-placeholder'>
<h3>Select a registered user to view details here</h3>
<h5>Or 'Add New User'</h5>
</div>
<Column fillParent>
<Column.Item grow />
<Column.Item>
<Text size='large' align='center' width='100%'>Select a registered user to view details here</Text>
<br />
<Text size='small' align='center' width='100%'>Or 'Add New User'</Text>
</Column.Item>
<Column.Item grow />
</Column>
)

View File

@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { List, Icon, Button } from 'ui'
import { Column, List, Button } from 'ui'
import { sizeInfo } from 'ui/style'
export class UserList extends React.Component {
static propTypes = {
@@ -20,8 +21,6 @@ export class UserList extends React.Component {
}
componentWillReceiveProps(nextProps) {
// This ensures that the original list is populated with 'all' by default,
// due to the component mounting before users are returned (by api)
if (nextProps.users !== this.props.users) {
this.setState({ users: nextProps.users })
}
@@ -38,26 +37,30 @@ export class UserList extends React.Component {
render() {
return (
<div>
<List className='user-list' selection>
{
this.state.users
? this.state.users.map((user, index) =>
(<List.Item className='user-list-item' key={user._id || '0'} onClick={this.props.onUserListClick}
active={user === this.props.selectedUser} data-index={index}>
<Icon name='profile' size={20} />
<List.Content>
{ user._id ? user.firstName + ' ' + user.lastName : '[New User]' }
{ user === this.props.selectedUser && this.props.selectionModified ? <Icon className='user-update'
name='edit' /> : null }
</List.Content>
</List.Item>)
)
: null
}
</List>
<Button className='add-new-user' content='Add New User' primary onClick={this.props.onAddNewUser} />
</div>
<Column fillParent>
<Column.Item grow>
<List>
{
this.state.users
? this.state.users.map((user, index) =>
(<List.Item className='user-list-item' key={user._id || '0'} onClick={this.props.onUserListClick}
active={true || user === this.props.selectedUser} data-index={index}>
<List.Icon name='profile' size={30} />
<List.Text>
{ user._id ? user.firstName + ' ' + user.lastName : '[New User]' }
</List.Text>
{ user === this.props.selectedUser && this.props.selectionModified ? <List.Icon className='user-update' name='edit' /> : null }
</List.Item>)
)
: null
}
</List>
</Column.Item>
<Column.Item height={20} />
<Column.Item height={sizeInfo.buttonHeight}>
<Button className='add-new-user' width='100%' color='inverse' onClick={this.props.onAddNewUser} text='Add New User' />
</Column.Item>
</Column>
)
}
}

View File

@@ -1,13 +1,14 @@
import React from 'react'
import React, { Component, Fragment } from 'react'
import { reactAutoBind } from 'auto-bind2'
import { UserList } from './UserList'
import { UserForm } from './UserForm'
import { UserFormPlaceholder } from './UserFormPlaceholder'
import { api } from 'src/API'
import { Row } from 'ui'
import { Row, Column, Box } from 'ui'
import { YesNoMessageModal, MessageModal, ChangeEmailModal, WaitModal } from '../Modal'
import { sizeInfo, colorInfo } from 'ui/style'
export class Users extends React.Component {
export class Users extends Component {
constructor() {
super()
reactAutoBind(this)
@@ -236,42 +237,53 @@ export class Users extends React.Component {
}
render() {
const { messageModal } = this.state
return (
<div>
<div>Users</div>
<Row>
<Row.Item width={5}>
<UserList users={this.state.users} selectedUser={this.state.selectedUser}
selectionModified={this.state.modified} onUserListClick={this.handleUserListClick}
onAddNewUser={this.handleAddNewUser} />
</Row.Item>
<Row.Item>
{
this.state.selectedUser
? <UserForm user={this.state.selectedUser} onSave={this.handleSave}
onRemove={this.handleRemove} onModifiedChanged={this.handleModifiedChanged}
onChangeEmail={this.handleChangeEmail} onResendEmail={this.handleResendEmail} />
: <UserFormPlaceholder />
}
</Row.Item>
</Row>
<Fragment>
<Column.Item height={20} />
<Column.Item grow>
<Row fillParent>
<Row.Item width={20} />
<Row.Item width='25vw'>
<UserList users={this.state.users} selectedUser={this.state.selectedUser}
selectionModified={this.state.modified} onUserListClick={this.handleUserListClick}
onAddNewUser={this.handleAddNewUser} />
</Row.Item>
<Row.Item width={20} />
<Row.Item grow>
<Box border={`${sizeInfo.headerBorderWidth}px solid ${colorInfo.headerBorder}`} radius={sizeInfo.formBoxRadius}>
{
this.state.selectedUser
? <UserForm user={this.state.selectedUser} onSave={this.handleSave}
onRemove={this.handleRemove} onModifiedChanged={this.handleModifiedChanged}
onChangeEmail={this.handleChangeEmail} onResendEmail={this.handleResendEmail} />
: <UserFormPlaceholder />
}
</Box>
</Row.Item>
<Row.Item width={20} />
</Row>
</Column.Item>
<Column.Item height={20}>
<ChangeEmailModal open={!!this.state.changeEmailModal} onDismiss={this.handleChangeEmailDismiss} />
<ChangeEmailModal open={!!this.state.changeEmailModal} onDismiss={this.handleChangeEmailDismiss} />
<YesNoMessageModal open={!!this.state.yesNoModal}
title={this.state.yesNoModal ? this.state.yesNoModal.title : ''}
message={this.state.yesNoModal ? this.state.yesNoModal.message : ''}
onDismiss={this.state.yesNoModal ? this.state.yesNoModal.onDismiss : null} />
<YesNoMessageModal open={!!this.state.yesNoModal}
title={this.state.yesNoModal ? this.state.yesNoModal.title : ''}
message={this.state.yesNoModal ? this.state.yesNoModal.message : ''}
onDismiss={this.state.yesNoModal ? this.state.yesNoModal.onDismiss : null} />
<MessageModal
open={!!messageModal}
icon={messageModal ? messageModal.icon : ''}
error={messageModal ? messageModal.error : false}
title={messageModal ? messageModal.title : ''}
message={messageModal ? messageModal.message : ''}
onDismiss={this.handleMessageModalDismiss} />
<MessageModal
open={!!this.state.messageModal}
error={this.state.messageModal ? this.state.messageModal.error : false}
title={this.state.messageModal ? this.state.messageModal.title : ''}
message={this.state.messageModal ? this.state.messageModal.message : ''}
onDismiss={this.handleMessageModalDismiss} />
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
</div>
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
</Column.Item>
</Fragment>
)
}
}

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 = {