Skip to content

Commit

Permalink
Migrate TimePicker to themr
Browse files Browse the repository at this point in the history
  • Loading branch information
javivelasco committed May 22, 2016
1 parent 709f4b1 commit 6f2d17d
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 108 deletions.
25 changes: 15 additions & 10 deletions components/time_picker/ClockFace.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React from 'react';
import style from './style.clock';
import classnames from 'classnames';

class Face extends React.Component {
static propTypes = {
active: React.PropTypes.number,
numbers: React.PropTypes.array,
radius: React.PropTypes.number,
spacing: React.PropTypes.number,
theme: React.PropTypes.shape({
active: React.PropTypes.string.isRequired,
face: React.PropTypes.string.isRequired,
number: React.PropTypes.string.isRequired
}),
twoDigits: React.PropTypes.bool
};

Expand All @@ -33,29 +38,29 @@ class Face extends React.Component {
}

renderNumber (number, idx) {
let className = style.number;
if (number === this.props.active) className += ` ${style.active}`;
const { active, radius, spacing, theme, twoDigits } = this.props;
return (
<span
className={className}
style={this.numberStyle(this.props.radius - this.props.spacing, idx + 1)}
className={classnames(theme.number, {[theme.active]: number === active})}
style={this.numberStyle(radius - spacing, idx + 1)}
key={number}
>
{this.props.twoDigits ? ('0' + number).slice(-2) : number}
{twoDigits ? ('0' + number).slice(-2) : number}
</span>
);
}

render () {
const { numbers, onTouchStart, onMouseDown, theme } = this.props;
return (
<div
ref='root'
className={style.face}
onTouchStart={this.props.onTouchStart}
onMouseDown={this.props.onMouseDown}
className={theme.face}
onTouchStart={onTouchStart}
onMouseDown={onMouseDown}
style={this.faceStyle()}
>
{this.props.numbers.map(this.renderNumber.bind(this))}
{numbers.map(this.renderNumber.bind(this))}
</div>
);
}
Expand Down
12 changes: 8 additions & 4 deletions components/time_picker/ClockHand.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import style from './style.clock';
import events from '../utils/events';
import prefixer from '../utils/prefixer';
import utils from '../utils/utils';
Expand All @@ -12,7 +11,11 @@ class Hand extends React.Component {
onMove: React.PropTypes.func,
onMoved: React.PropTypes.func,
origin: React.PropTypes.object,
step: React.PropTypes.number
step: React.PropTypes.number,
theme: React.PropTypes.shape({
hand: React.PropTypes.string.isRequired,
knob: React.PropTypes.string.isRequired
})
};

static defaultProps = {
Expand Down Expand Up @@ -104,15 +107,16 @@ class Hand extends React.Component {
}

render () {
const className = `${style.hand} ${this.props.className}`;
const { theme } = this.props;
const className = `${theme.hand} ${this.props.className}`;
const handStyle = prefixer({
height: this.props.length - this.state.knobWidth / 2,
transform: `rotate(${this.props.angle}deg)`
});

return (
<div className={className} style={handStyle}>
<div ref='knob' className={style.knob}></div>
<div ref='knob' className={theme.knob}></div>
</div>
);
}
Expand Down
12 changes: 8 additions & 4 deletions components/time_picker/ClockMinutes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import utils from '../utils/utils';
import style from './style.clock';
import Face from './ClockFace';
import Hand from './ClockHand';

Expand All @@ -13,7 +12,10 @@ class Minutes extends React.Component {
onChange: React.PropTypes.func,
radius: React.PropTypes.number,
selected: React.PropTypes.number,
spacing: React.PropTypes.number
spacing: React.PropTypes.number,
theme: React.PropTypes.shape({
small: React.PropTypes.string.isRequired
})
};

static defaultProps = {
Expand Down Expand Up @@ -42,15 +44,17 @@ class Minutes extends React.Component {
numbers={minutes}
spacing={this.props.spacing}
radius={this.props.radius}
twoDigits
active={this.props.selected}
theme={this.props.theme}
twoDigits
/>
<Hand ref='hand'
className={minutes.indexOf(this.props.selected) === -1 ? style.small : ''}
className={minutes.indexOf(this.props.selected) === -1 ? this.props.theme.small : ''}
angle={this.props.selected * step}
length={this.props.radius - this.props.spacing}
onMove={this.handleHandMove}
origin={this.props.center}
theme={this.props.theme}
step={step}
/>
</div>
Expand Down
12 changes: 8 additions & 4 deletions components/time_picker/TimePicker.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import events from '../utils/events';
import time from '../utils/time';
import style from './style';
import Input from '../input';
import TimePickerDialog from './TimePickerDialog';

Expand All @@ -14,6 +14,9 @@ class TimePicker extends React.Component {
inputClassName: React.PropTypes.string,
label: React.PropTypes.string,
onChange: React.PropTypes.func,
theme: React.PropTypes.shape({
input: React.PropTypes.string.isRequired
}),
value: React.PropTypes.object
};

Expand Down Expand Up @@ -41,12 +44,12 @@ class TimePicker extends React.Component {
};

render () {
const { value, format, inputClassName } = this.props;
const { value, format, inputClassName, theme } = this.props;
const formattedTime = value ? time.formatTime(value, format) : null;
return (
<div data-react-toolbox='time-picker'>
<Input
className={classnames(style.input, {[inputClassName]: inputClassName })}
className={classnames(theme.input, {[inputClassName]: inputClassName })}
error={this.props.error}
label={this.props.label}
onMouseDown={this.handleInputMouseDown}
Expand All @@ -60,11 +63,12 @@ class TimePicker extends React.Component {
format={format}
onDismiss={this.handleDismiss}
onSelect={this.handleSelect}
theme={this.props.theme}
value={this.props.value}
/>
</div>
);
}
}

export default TimePicker;
export default themr('ToolboxTimePicker')(TimePicker);
45 changes: 31 additions & 14 deletions components/time_picker/TimePickerDialog.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import ClassNames from 'classnames';
import style from './style';
import classnames from 'classnames';
import time from '../utils/time';
import Clock from './Clock';
import Dialog from '../dialog';
Expand All @@ -12,6 +11,21 @@ class TimePickerDialog extends React.Component {
format: React.PropTypes.oneOf(['24hr', 'ampm']),
onDismiss: React.PropTypes.func,
onSelect: React.PropTypes.func,
theme: React.PropTypes.shape({
am: React.PropTypes.string.isRequired,
amFormat: React.PropTypes.string.isRequired,
ampm: React.PropTypes.string.isRequired,
button: React.PropTypes.string.isRequired,
dialog: React.PropTypes.string.isRequired,
header: React.PropTypes.string.isRequired,
hours: React.PropTypes.string.isRequired,
hoursDisplay: React.PropTypes.string.isRequired,
minutes: React.PropTypes.string.isRequired,
minutessDisplay: React.PropTypes.string.isRequired,
pm: React.PropTypes.string.isRequired,
pmFormat: React.PropTypes.string.isRequired,
separator: React.PropTypes.string.isRequired
}),
value: React.PropTypes.object
};

Expand Down Expand Up @@ -53,8 +67,8 @@ class TimePickerDialog extends React.Component {
};

actions = [
{ label: 'Cancel', className: style.button, onClick: this.props.onDismiss },
{ label: 'Ok', className: style.button, onClick: this.handleSelect }
{ label: 'Cancel', className: this.props.theme.button, onClick: this.props.onDismiss },
{ label: 'Ok', className: this.props.theme.button, onClick: this.handleSelect }
];

formatHours () {
Expand All @@ -66,28 +80,30 @@ class TimePickerDialog extends React.Component {
}

renderAMPMLabels () {
const { theme } = this.props;
if (this.props.format === 'ampm') {
return (
<div className={style.ampm}>
<span className={style.am} onClick={this.toggleTimeMode}>AM</span>
<span className={style.pm} onClick={this.toggleTimeMode}>PM</span>
<div className={theme.ampm}>
<span className={theme.am} onClick={this.toggleTimeMode}>AM</span>
<span className={theme.pm} onClick={this.toggleTimeMode}>PM</span>
</div>
);
}
}

render () {
const display = `display-${this.state.display}`;
const format = `format-${time.getTimeMode(this.state.displayTime)}`;
const className = ClassNames([style.dialog, style[display], style[format]], this.props.className);
const { theme } = this.props;
const display = `${this.state.display}Display`;
const format = `${time.getTimeMode(this.state.displayTime)}Format`;
const className = classnames([theme.dialog, theme[display], theme[format]], this.props.className);
return (
<Dialog active={this.props.active} className={className} actions={this.actions}>
<header className={style.header}>
<span className={style.hours} onClick={this.switchDisplay.bind(this, 'hours')}>
<header className={theme.header}>
<span className={theme.hours} onClick={this.switchDisplay.bind(this, 'hours')}>
{('0' + this.formatHours()).slice(-2)}
</span>
<span className={style.separator}>:</span>
<span className={style.minutes} onClick={this.switchDisplay.bind(this, 'minutes')}>
<span className={theme.separator}>:</span>
<span className={theme.minutes} onClick={this.switchDisplay.bind(this, 'minutes')}>
{('0' + this.state.displayTime.getMinutes()).slice(-2)}
</span>
{this.renderAMPMLabels()}
Expand All @@ -98,6 +114,7 @@ class TimePickerDialog extends React.Component {
format={this.props.format}
onChange={this.handleClockChange}
onHandMoved={this.handleHandMoved}
theme={this.props.theme}
time={this.state.displayTime}
/>
</Dialog>
Expand Down
45 changes: 42 additions & 3 deletions components/time_picker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,28 @@ A [dialog picker](https://www.google.com/design/spec/components/pickers.html#pic
<!-- example -->
```jsx
import TimePicker from 'react-toolbox/lib/time_picker';
import theme from 'react-toolbox/lib/time_picker/theme'

let time = new Date();
time.setHours(17);
time.setMinutes(28);

class TimePickerTest extends React.Component {
state = {time};
state = {time};

handleChange = (time) => {
this.setState({time});
this.setState({time});
};

render () {
return <TimePicker label='Finishing time' onChange={this.handleChange} value={this.state.time} />;
return (
<TimePicker
label='Finishing time'
onChange={this.handleChange}
value={this.state.time}
theme={theme}
/>
);
}
}
```
Expand All @@ -33,3 +42,33 @@ class TimePickerTest extends React.Component {
| `label` | `String` | | The text string to use for the floating label element in the input component.|
| `onChange` | `Function` | | Callback called when the picker value is changed.|
| `value` | `Date` | | Datetime object with currrently selected time. |

## Theming

You can take a look to the `_config.scss` variables. The themed key for this component is `ToolboxTimePicker`, it should implement the following interface:

| Name | Description|
|:---------|:-----------|
| `active` | Added to the number which is active in clock face.|
| `am` | AM label in dialog header when mode is AM/PM.|
| `amFormat` | Added to the dialog when the selected format is AM.|
| `ampm` | Wrapper for AM and PM labels in header when mode is AM/PM.|
| `button` | Used for buttons inside the dialog of the picker.|
| `clock` | Clock root class element.|
| `clockWrapper` | Wrapper for the proper positioning of the clock.|
| `dialog` | Used for the dialog component.|
| `face` | Used to style the clock face.|
| `hand` | Used for the clock's hand.|
| `header` | Dialog header wrapper class.|
| `hours` | Used for hours in dialog header.|
| `hoursDisplay` | Added to the dialog hours are displayed.|
| `input` | Used for Input element that opens the picker.|
| `knob` | Used for the knob of the hand.|
| `minutes` | Used for minutes in dialog header.|
| `minutesDisplay` | Added to the dialog minutes are displayed.|
| `number` | Each of the numbers in the clock's face.|
| `placeholder` | Placeholder for the clock inside the dialog (inner wrapper).|
| `pm` | PM label in dialog header when mode is AM/PM.|
| `pmFormat` | Added to the dialog when the selected format is PM.|
| `separator` | Is the `:` separator between hours and minutes in dialog header.|
| `small` | Added to the knob when no round number is selected.|
Loading

0 comments on commit 6f2d17d

Please sign in to comment.