11import _ from 'lodash'
2- import React , { PropTypes } from 'react'
2+ import React , { Component , PropTypes } from 'react'
33import cx from 'classnames'
44
55import {
@@ -42,91 +42,7 @@ export const htmlInputPropNames = [
4242 'value' ,
4343]
4444
45- /**
46- * An Input is a field used to elicit a response from a user
47- * @see Button
48- * @see Form
49- * @see Icon
50- * @see Label
51- */
52- function Input ( props ) {
53- const {
54- action,
55- actionPosition,
56- children,
57- className,
58- disabled,
59- error,
60- focus,
61- fluid,
62- icon,
63- iconPosition,
64- inverted,
65- label,
66- labelPosition,
67- loading,
68- size,
69- type,
70- input,
71- transparent,
72- } = props
73-
74- const classes = cx (
75- 'ui' ,
76- size ,
77- useValueAndKey ( actionPosition , 'action' ) || useKeyOnly ( action , 'action' ) ,
78- useKeyOnly ( disabled , 'disabled' ) ,
79- useKeyOnly ( error , 'error' ) ,
80- useKeyOnly ( focus , 'focus' ) ,
81- useKeyOnly ( fluid , 'fluid' ) ,
82- useKeyOnly ( inverted , 'inverted' ) ,
83- useValueAndKey ( labelPosition , 'labeled' ) || useKeyOnly ( label , 'labeled' ) ,
84- useKeyOnly ( loading , 'loading' ) ,
85- useKeyOnly ( transparent , 'transparent' ) ,
86- useValueAndKey ( iconPosition , 'icon' ) || useKeyOnly ( icon , 'icon' ) ,
87- className ,
88- 'input' ,
89- )
90- const unhandled = getUnhandledProps ( Input , props )
91-
92- const rest = _ . omit ( unhandled , htmlInputPropNames )
93- const htmlInputProps = _ . pick ( props , htmlInputPropNames )
94- const ElementType = getElementType ( Input , props )
95-
96- if ( children ) {
97- return < ElementType { ...rest } className = { classes } > { children } </ ElementType >
98- }
99-
100- const actionElement = Button . create ( action , elProps => ( {
101- className : cx (
102- // all action components should have the button className
103- ! _ . includes ( elProps . className , 'button' ) && 'button' ,
104- ) ,
105- } ) )
106- const iconElement = Icon . create ( icon )
107- const labelElement = Label . create ( label , elProps => ( {
108- className : cx (
109- // all label components should have the label className
110- ! _ . includes ( elProps . className , 'label' ) && 'label' ,
111- // add 'left|right corner'
112- _ . includes ( labelPosition , 'corner' ) && labelPosition ,
113- ) ,
114- } ) )
115-
116- return (
117- < ElementType { ...rest } className = { classes } >
118- { actionPosition === 'left' && actionElement }
119- { iconPosition === 'left' && iconElement }
120- { labelPosition !== 'right' && labelElement }
121- { createHTMLInput ( input || type , htmlInputProps ) }
122- { actionPosition !== 'left' && actionElement }
123- { iconPosition !== 'left' && iconElement }
124- { labelPosition === 'right' && labelElement }
125- </ ElementType >
126- )
127- }
128-
129- Input . _meta = {
45+ const _meta = {
13046 name : 'Input' ,
13147 type : META . TYPES . ELEMENT ,
13248 props : {
@@ -137,73 +53,173 @@ Input._meta = {
13753 } ,
13854}
13955
140- Input . defaultProps = {
141- type : 'text' ,
142- }
56+ /**
57+ * An Input is a field used to elicit a response from a user
58+ * @see Button
59+ * @see Form
60+ * @see Icon
61+ * @see Label
62+ */
63+ class Input extends Component {
64+ static propTypes = {
65+ /** An element type to render as (string or function). */
66+ as : customPropTypes . as ,
67+
68+ /** An Input can be formatted to alert the user to an action they may perform */
69+ action : PropTypes . oneOfType ( [
70+ PropTypes . bool ,
71+ customPropTypes . itemShorthand ,
72+ ] ) ,
14373
144- Input . propTypes = {
145- /** An element type to render as (string or function). */
146- as : customPropTypes . as ,
74+ /** An action can appear along side an Input on the left or right */
75+ actionPosition : PropTypes . oneOf ( _meta . props . actionPosition ) ,
14776
148- /** An Input can be formatted to alert the user to an action they may perform */
149- action : PropTypes . oneOfType ( [
150- PropTypes . bool ,
151- customPropTypes . itemShorthand ,
152- ] ) ,
77+ /** Primary content. */
78+ children : PropTypes . node ,
15379
154- /** An action can appear along side an Input on the left or right */
155- actionPosition : PropTypes . oneOf ( Input . _meta . props . actionPosition ) ,
80+ /** Additional classes. */
81+ className : PropTypes . string ,
15682
157- /** Primary content. */
158- children : PropTypes . node ,
83+ /** An Input field can show that it is disabled */
84+ disabled : PropTypes . bool ,
15985
160- /** Additional classes. */
161- className : PropTypes . string ,
86+ /** An Input field can show the data contains errors */
87+ error : PropTypes . bool ,
16288
163- /** An Input field can show that it is disabled */
164- disabled : PropTypes . bool ,
89+ /** An Input field can show a user is currently interacting with it */
90+ focus : PropTypes . bool ,
16591
166- /** An Input field can show the data contains errors */
167- error : PropTypes . bool ,
92+ /** Take on the size of it's container */
93+ fluid : PropTypes . bool ,
16894
169- /** An Input field can show a user is currently interacting with it */
170- focus : PropTypes . bool ,
95+ /** Optional Icon to display inside the Input */
96+ icon : PropTypes . oneOfType ( [
97+ PropTypes . bool ,
98+ customPropTypes . itemShorthand ,
99+ ] ) ,
171100
172- /** Take on the size of it's container */
173- fluid : PropTypes . bool ,
101+ /** An Icon can appear inside an Input on the left or right */
102+ iconPosition : PropTypes . oneOf ( _meta . props . iconPosition ) ,
174103
175- /** Optional Icon to display inside the Input */
176- icon : PropTypes . oneOfType ( [
177- PropTypes . bool ,
178- customPropTypes . itemShorthand ,
179- ] ) ,
104+ /** Format to appear on dark backgrounds */
105+ inverted : PropTypes . bool ,
180106
181- /** An Icon can appear inside an Input on the left or right */
182- iconPosition : PropTypes . oneOf ( Input . _meta . props . iconPosition ) ,
107+ /** Shorthand for creating the HTML Input */
108+ input : customPropTypes . itemShorthand ,
183109
184- /** Format to appear on dark backgrounds */
185- inverted : PropTypes . bool ,
110+ /** Optional Label to display along side the Input */
111+ label : customPropTypes . itemShorthand ,
186112
187- /** Shorthand for creating the HTML Input */
188- input : customPropTypes . itemShorthand ,
113+ /** A Label can appear outside an Input on the left or right */
114+ labelPosition : PropTypes . oneOf ( _meta . props . labelPosition ) ,
189115
190- /** Optional Label to display along side the Input */
191- label : customPropTypes . itemShorthand ,
116+ /** An Icon Input field can show that it is currently loading data */
117+ loading : PropTypes . bool ,
192118
193- /** A Label can appear outside an Input on the left or right */
194- labelPosition : PropTypes . oneOf ( Input . _meta . props . labelPosition ) ,
119+ /** Called with (e, props) on change. */
120+ onChange : PropTypes . func ,
195121
196- /** An Icon Input field can show that it is currently loading data */
197- loading : PropTypes . bool ,
122+ /** An Input can vary in size */
123+ size : PropTypes . oneOf ( _meta . props . size ) ,
198124
199- /** An Input can vary in size */
200- size : PropTypes . oneOf ( Input . _meta . props . size ) ,
125+ /** Transparent Input has no background */
126+ transparent : PropTypes . bool ,
201127
202- /** Transparent Input has no background */
203- transparent : PropTypes . bool ,
128+ /** The HTML input type */
129+ type : PropTypes . string ,
130+ }
204131
205- /** The HTML input type */
206- type : PropTypes . string ,
132+ static defaultProps = {
133+ type : 'text' ,
134+ }
135+
136+ static _meta = _meta
137+
138+ handleChange = ( e ) => {
139+ const { onChange } = this . props
140+ if ( onChange ) onChange ( e , this . props )
141+ }
142+
143+ render ( ) {
144+ const {
145+ action,
146+ actionPosition,
147+ children,
148+ className,
149+ disabled,
150+ error,
151+ focus,
152+ fluid,
153+ icon,
154+ iconPosition,
155+ inverted,
156+ label,
157+ labelPosition,
158+ loading,
159+ onChange,
160+ size,
161+ type,
162+ input,
163+ transparent,
164+ } = this . props
165+
166+ const classes = cx (
167+ 'ui' ,
168+ size ,
169+ useValueAndKey ( actionPosition , 'action' ) || useKeyOnly ( action , 'action' ) ,
170+ useKeyOnly ( disabled , 'disabled' ) ,
171+ useKeyOnly ( error , 'error' ) ,
172+ useKeyOnly ( focus , 'focus' ) ,
173+ useKeyOnly ( fluid , 'fluid' ) ,
174+ useKeyOnly ( inverted , 'inverted' ) ,
175+ useValueAndKey ( labelPosition , 'labeled' ) || useKeyOnly ( label , 'labeled' ) ,
176+ useKeyOnly ( loading , 'loading' ) ,
177+ useKeyOnly ( transparent , 'transparent' ) ,
178+ useValueAndKey ( iconPosition , 'icon' ) || useKeyOnly ( icon , 'icon' ) ,
179+ className ,
180+ 'input' ,
181+ )
182+ const unhandled = getUnhandledProps ( Input , this . props )
183+
184+ const rest = _ . omit ( unhandled , htmlInputPropNames )
185+
186+ const htmlInputProps = _ . pick ( this . props , htmlInputPropNames )
187+ if ( onChange ) htmlInputProps . onChange = this . handleChange
188+
189+ const ElementType = getElementType ( Input , this . props )
190+
191+ if ( children ) {
192+ return < ElementType { ...rest } className = { classes } > { children } </ ElementType >
193+ }
194+
195+ const actionElement = Button . create ( action , elProps => ( {
196+ className : cx (
197+ // all action components should have the button className
198+ ! _ . includes ( elProps . className , 'button' ) && 'button' ,
199+ ) ,
200+ } ) )
201+ const iconElement = Icon . create ( icon )
202+ const labelElement = Label . create ( label , elProps => ( {
203+ className : cx (
204+ // all label components should have the label className
205+ ! _ . includes ( elProps . className , 'label' ) && 'label' ,
206+ // add 'left|right corner'
207+ _ . includes ( labelPosition , 'corner' ) && labelPosition ,
208+ ) ,
209+ } ) )
210+
211+ return (
212+ < ElementType { ...rest } className = { classes } >
213+ { actionPosition === 'left' && actionElement }
214+ { iconPosition === 'left' && iconElement }
215+ { labelPosition !== 'right' && labelElement }
216+ { createHTMLInput ( input || type , htmlInputProps ) }
217+ { actionPosition !== 'left' && actionElement }
218+ { iconPosition !== 'left' && iconElement }
219+ { labelPosition === 'right' && labelElement }
220+ </ ElementType >
221+ )
222+ }
207223}
208224
209225export default Input
0 commit comments