@@ -240,15 +240,53 @@ class ColorComponentEntry extends React.Component {
240240 size = '4'
241241 maxLength = '4'
242242 style = { { textAlign : 'center' } }
243- value = { this . props . value } />
243+ value = { this . props . value }
244+ onChange = { event => {
245+ const strValueEntered = event . target . value ;
246+
247+ // Need to normalize the user input to a valid
248+ // value, which is 0 <= valid <= 255
249+
250+ // Inputs of non-digits will be ignored.
251+ if ( ! strValueEntered . match ( / ^ \d * $ / g) ) {
252+ return ;
253+ }
254+
255+ // Value must be converted to an integer.
256+ const convertValue = strValueToConvert => {
257+ // Blank / falsy input will be treated as 0.
258+ if ( ! strValueToConvert ) {
259+ return 0 ;
260+ }
261+
262+ const valueConverted = parseInt (
263+ strValueToConvert ) ;
264+
265+ // If the integer is <= 255 then it is a valid
266+ // value and safe to return.
267+ if ( valueConverted <= 255 ) {
268+ return valueConverted ;
269+ }
270+
271+ // Otherwise will remove the left-most digit
272+ // and try to convert again until the value
273+ // becomes <= 255
274+ return convertValue ( strValueToConvert
275+ . substr ( 1 ) ) ;
276+ } ;
277+
278+ this . props . onChangeValue ( convertValue (
279+ strValueEntered ) ) ;
280+ } } />
244281 </ div >
245282 ) ;
246283 }
247284}
248285
249286ColorComponentEntry . propTypes = {
250287 label : PropTypes . string . isRequired ,
251- value : PropTypes . number . isRequired
288+ value : PropTypes . number . isRequired ,
289+ onChangeValue : PropTypes . func . isRequired
252290 } ;
253291
254292class ColorSelector extends React . Component {
@@ -272,9 +310,39 @@ class ColorSelector extends React.Component {
272310 height : '3em' ,
273311 border : 'solid 2px black' } } />
274312 < div style = { { marginTop : '-1em' } } >
275- < ColorComponentEntry label = "R" value = { this . state . color . r } />
276- < ColorComponentEntry label = "G" value = { this . state . color . g } />
277- < ColorComponentEntry label = "B" value = { this . state . color . b } />
313+ < ColorComponentEntry label = "R" value = { this . state . color . r } onChangeValue = {
314+ ( value ) => {
315+ this . setState ( {
316+ ...this . state ,
317+ color : {
318+ ...this . state . color ,
319+ r : value
320+ }
321+ } ) ;
322+ }
323+ } />
324+ < ColorComponentEntry label = "G" value = { this . state . color . g } onChangeValue = {
325+ ( value ) => {
326+ this . setState ( {
327+ ...this . state ,
328+ color : {
329+ ...this . state . color ,
330+ g : value
331+ }
332+ } ) ;
333+ }
334+ } />
335+ < ColorComponentEntry label = "B" value = { this . state . color . b } onChangeValue = {
336+ ( value ) => {
337+ this . setState ( {
338+ ...this . state ,
339+ color : {
340+ ...this . state . color ,
341+ b : value
342+ }
343+ } ) ;
344+ }
345+ } />
278346 </ div >
279347 </ div >
280348 ) ;
0 commit comments