ldx-widgets
Version:
widgets
137 lines (95 loc) • 3.12 kB
text/coffeescript
React = require 'react'
ReactDOM = require 'react-dom'
_ = require 'lodash'
{input} = React.DOM
###
Input Props
Takes standard text input properties
###
InputPlaceholder = React.createClass
displayName: 'InputPlaceholder'
getDefaultProps: ->
{
className: ''
type: 'text'
placeholderIsSupported: document.createElement('input').placeholder isnt undefined
}
componentWillMount: ->
{type, placeholder, placeholderIsSupported} = @props
@needsPlaceholding = placeholder and not placeholderIsSupported and type in ['text', 'password']
componentWillReceiveProps: (props) ->
@needsPlaceholding = props.placeholder and not props.placeholderIsSupported and props.type in ['text', 'password']
componentDidUpdate: ->
@setSelectionIfNeeded ReactDOM.findDOMNode(@)
# keep track of focus
onFocus: (e) ->
@hasFocus = true
@setSelectionIfNeeded e.target
@props.onFocus?(e)
onBlur: (e) ->
@hasFocus = false
@props.onBlur?(e)
onClick: (e) ->
@hasFocus = true
e.target.focus()
@setSelectionIfNeeded e.target
@props.onClick?()
# If placeholder is visible, ensure cursor is at start of input
setSelectionIfNeeded: (node) ->
if @needsPlaceholding and @hasFocus and @isPlaceholding and (node.selectionStart isnt 0 or node.selectionEnd isnt 0)
node.setSelectionRange(0, 0)
onMouseDown: (e) ->
if @isPlaceholding
@setSelectionIfNeeded e.target
e.preventDefault()
@props.onMouseDown?(e)
onKeydown: (e) ->
{key} = e
e.preventDefault() if key is 'Enter' and @needsPlaceholding
if @isPlaceholding and key in ['ArrowRight', 'ArrowLeft']
e.preventDefault()
@setSelectionIfNeeded e.target
@props.onKeydown?(e)
onChange: (e) ->
if @isPlaceholding
# remove placeholder when text is added
value = e.target.value
i = value.indexOf @props.placeholder
e.target.value = value.slice(0, i) unless i is -1
@props.onChange?(e)
onSelect: (e) ->
if @isPlaceholding
@setSelectionIfNeeded e.target
e.preventDefault()
@props.onSelect?(e)
getValue: ->
{value} = ReactDOM.findDOMNode(@)
return value unless @needsPlaceholding
if value is @props.placeholder then return ''
else return value
onPaste: (e) ->
if @isPlaceholding
e.target.value = ''
render: ->
unless @needsPlaceholding
return input(@props)
{value, placeholder, type, className} = @props
if not value or value is ''
@isPlaceholding = true
className += ' placeholder'
else
@isPlaceholding = false
props = _.assign _.clone(@props),
className: className
onFocus: @onFocus
onBlur: @onBlur
onClick: @onClick
onChange: @onChange
onFocus: @onFocus
onKeyDown: @onKeydown
onMouseDown: @onMouseDown
value: if @isPlaceholding then placeholder else value
type: if @isPlaceholding then 'text' else type
onPaste: @onPaste
input props
module.exports = InputPlaceholder