Skip to content

Commit

Permalink
Time picker first implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
javivelasco committed Aug 30, 2015
1 parent 9aeebc8 commit 5f62ce2
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 87 deletions.
91 changes: 91 additions & 0 deletions components/time_picker/dialog.cjsx
@@ -0,0 +1,91 @@
css = require './style'
dateUtils = require '../date_utils'

Button = require '../button'
Clock = require '../clock'
Dialog = require '../dialog'

module.exports = React.createClass

# -- States & Properties
propTypes:
className : React.PropTypes.string
initialTime : React.PropTypes.object
format : React.PropTypes.oneOf(['24hr', 'ampm'])
onTimeSelected : React.PropTypes.func

getDefaultProps: ->
className : ''
initialTime : new Date()
format : '24hr'

getInitialState: ->
display : 'hours'
time : @props.initialTime
actions: [
{ caption: "Cancel", type: "flat accent", onClick: @onTimeCancel },
{ caption: "Ok", type: "flat accent", onClick: @onTimeSelected }
]

# -- Events
onClockChange: (time) ->
@setState time: time

onTimeCancel: (ref, method) ->
@refs.dialog.hide()

onTimeSelected: ->
@props.onTimeSelected(@state.time) if @props.onTimeSelected
@refs.dialog.hide()

# -- Public methods
displayMinutes: ->
@setState display: 'minutes'

displayHours: ->
@setState display: 'hours'

toggleTimeMode: ->
@refs.clock.toggleTimeMode()

show: ->
@refs.dialog.show()
setTimeout @refs.clock.handleResize, 500

# -- Private helpers
_formatHours: ->
if @props.format == 'ampm' then @state.time.getHours() % 12 || 12 else @state.time.getHours()

# -- Render
render: ->
className = " "
className += " display-#{@state.display}"
className += " format-#{dateUtils.timeMode(@state.time)}"

<Dialog ref="dialog" type={css.dialog} className={className} actions={@state.actions}>
<header className={css.header}>
<span className={css.hours} onClick={@displayHours} >
{_twoDigits(@_formatHours())}
</span>
<span className={css.separator}>:</span>
<span className={css.minutes} onClick={@displayMinutes}>
{_twoDigits(@state.time.getMinutes())}
</span>
{
if @props.format == 'ampm'
<div className={css.ampm}>
<span className={css.am} onClick={@toggleTimeMode}>AM</span>
<span className={css.pm} onClick={@toggleTimeMode}>PM</span>
</div>
}
</header>
<Clock ref="clock"
display={@state.display}
format={@props.format}
initialTime={@props.initialTime}
onChange={@onClockChange} />
</Dialog>

# -- Private helpers
_twoDigits = (number) ->
('0' + number).slice(-2)
95 changes: 42 additions & 53 deletions components/time_picker/index.cjsx
@@ -1,72 +1,61 @@
css = require './style'
Clock = require '../clock'
dateUtils = require '../date_utils'
css = require './style'
Input = require '../input'
TimeDialog = require './dialog'

module.exports = React.createClass

# -- States & Properties
propTypes:
className : React.PropTypes.string
initialTime : React.PropTypes.object
format : React.PropTypes.oneOf(['24hr', 'ampm'])
value : React.PropTypes.object

getDefaultProps: ->
className : ''
initialTime : new Date()
format : '24hr'

getInitialState: ->
display : 'hours'
time : @props.initialTime
value : @props.value

# -- Events
onClockChange: (time) ->
@setState time: time

# -- Public methods
displayMinutes: ->
@setState display: 'minutes'

displayHours: ->
@setState display: 'hours'

toggleTimeMode: ->
@refs.clock.toggleTimeMode()

# -- Private helpers
_formatHours: ->
if @props.format == 'ampm' then @state.time.getHours() % 12 || 12 else @state.time.getHours()
onTimeSelected: (time) ->
@refs.input.setValue(@formatTime(time))
@setState value: time

openTimeDialog: ->
@refs.dialog.show()

# -- Private methods
formatTime: (date) ->
hours = date.getHours()
mins = date.getMinutes().toString()

if (@props.format == "ampm")
isAM = hours < 12
hours = hours % 12
additional = if isAM then " am" else " pm"
hours = (hours || 12).toString()
mins = "0" + mins if (mins.length < 2 )
return hours + (if mins == "00" then "" else ":" + mins) + additional

hours = hours.toString()
hours = "0" + hours if (hours.length < 2)
mins = "0" + mins if (mins.length < 2)
return hours + ":" + mins

# -- Render
render: ->
className = " #{@props.className}"
className += " display-#{@state.display}"
className += " format-#{dateUtils.timeMode(@state.time)}"

<div className={css.root + className}>
<header className={css.header}>
<span className={css.hours} onClick={@displayHours} >
{_twoDigits(@_formatHours())}
</span>
<span className={css.separator}>:</span>
<span className={css.minutes} onClick={@displayMinutes}>
{_twoDigits(@state.time.getMinutes())}
</span>
{
if @props.format == 'ampm'
<div className={css.ampm}>
<span className={css.am} onClick={@toggleTimeMode}>AM</span>
<span className={css.pm} onClick={@toggleTimeMode}>PM</span>
</div>
}
</header>
<Clock ref="clock"
display={@state.display}
format={@props.format}
initialTime={@props.initialTime}
onChange={@onClockChange} />
<div>
<Input
ref="input"
type="text"
disabled={true}
onClick={@openTimeDialog}
placeholder="Pick up time"
value={@formatTime(@state.value) if @state.value} />
<TimeDialog
ref="dialog"
initialTime={@state.value}
format={@props.format}
onTimeSelected={@onTimeSelected} />
</div>

# -- Private helpers
_twoDigits = (number) ->
('0' + number).slice(-2)
73 changes: 39 additions & 34 deletions components/time_picker/style.styl
Expand Up @@ -4,52 +4,57 @@ AMPM_HEIGHT = 22px
AMPM_WIDTH = 40px
PICKER_WIDTH = 280px

:local(.root)
width : PICKER_WIDTH
// Picker dialog
:local(.dialog)
padding : 0
width : PICKER_WIDTH
> nav
margin-top : 0
padding-bottom : 10px

:local(.header)
background : ACCENT
color : WHITE
font-size : 52px
padding : 10px
text-align : center
position : relative
width : 100%
background : ACCENT
color : WHITE
font-size : 52px
padding : 10px
text-align : center
position : relative
width : 100%

:local(.hours), :local(.minutes)
cursor : pointer
display : inline-block
opacity : .6
cursor : pointer
display : inline-block
opacity : .6

:local(.separator)
margin : 0 5px
opacity : .6
margin : 0 5px
opacity : .6

:local(.ampm)
font-size : 16px
height : AMPM_HEIGHT * 2
line-height : AMPM_HEIGHT
margin-top : - AMPM_HEIGHT
position : absolute
right : 20px
text-align : center
top : 50%
width : AMPM_WIDTH
font-size : 16px
height : AMPM_HEIGHT * 2
line-height : AMPM_HEIGHT
margin-top : - AMPM_HEIGHT
position : absolute
right : 20px
text-align : center
top : 50%
width : AMPM_WIDTH

:local(.am), :local(.pm)
cursor : pointer
display : block
opacity : .6
cursor : pointer
display : block
opacity : .6

// Modifiers
:local(.root).display-hours :local(.hours)
opacity : 1
:local(.dialog).display-hours :local(.hours)
opacity : 1

:local(.root).display-minutes :local(.minutes)
opacity : 1
:local(.dialog).display-minutes :local(.minutes)
opacity : 1

:local(.root).format-am :local(.am)
opacity : 1
:local(.dialog).format-am :local(.am)
opacity : 1

:local(.root).format-pm :local(.pm)
opacity : 1
:local(.dialog).format-pm :local(.pm)
opacity : 1

0 comments on commit 5f62ce2

Please sign in to comment.