@@ -30,7 +30,7 @@ export default class TagsInput extends BaseComponent {
30
30
31
31
static propTypes = {
32
32
/**
33
- * list of tags. can be string or custom object when implementing getLabel
33
+ * list of tags. can be string boolean or custom object when implementing getLabel
34
34
*/
35
35
tags : PropTypes . arrayOf ( PropTypes . oneOfType ( [ PropTypes . object , PropTypes . string ] ) ) ,
36
36
/**
@@ -53,6 +53,10 @@ export default class TagsInput extends BaseComponent {
53
53
* callback for when pressing a tag in the following format (tagIndex, markedTagIndex) => {...}
54
54
*/
55
55
onTagPress : PropTypes . func ,
56
+ /**
57
+ * validation message error appears when tag isn't validate
58
+ */
59
+ validationErrorMessage : PropTypes . string ,
56
60
/**
57
61
* if true, tags *removal* Ux won't be available
58
62
*/
@@ -139,7 +143,6 @@ export default class TagsInput extends BaseComponent {
139
143
140
144
const newTag = _ . isFunction ( onCreateTag ) ? onCreateTag ( value ) : value ;
141
145
const newTags = [ ...tags , newTag ] ;
142
-
143
146
this . setState ( {
144
147
value : '' ,
145
148
tags : newTags
@@ -242,9 +245,17 @@ export default class TagsInput extends BaseComponent {
242
245
243
246
return (
244
247
< View row centerV >
245
- { shouldMarkTag && < Image style = { styles . removeIcon } source = { Assets . icons . x } /> }
246
- < Text style = { [ styles . tagLabel , typography ] } accessibilityLabel = { `${ label } tag` } >
247
- { shouldMarkTag ? 'Remove' : label }
248
+ { shouldMarkTag && (
249
+ < Image
250
+ style = { [ styles . removeIcon , tag . invalid && styles . inValidTagRemoveIcon ] }
251
+ source = { Assets . icons . x }
252
+ /> )
253
+ }
254
+ < Text
255
+ style = { [ tag . invalid ? ( shouldMarkTag ? styles . errorMessageWhileMarked : styles . errorMessage )
256
+ : styles . tagLabel , typography ] } accessibilityLabel = { `${ label } tag` }
257
+ >
258
+ { ! tag . invalid && shouldMarkTag ? 'Remove' : label }
248
259
</ Text >
249
260
</ View >
250
261
) ;
@@ -255,6 +266,17 @@ export default class TagsInput extends BaseComponent {
255
266
const { tagIndexToRemove} = this . state ;
256
267
const shouldMarkTag = tagIndexToRemove === index ;
257
268
269
+ if ( tag . invalid ) {
270
+ return (
271
+ < View
272
+ key = { index }
273
+ style = { [ styles . inValidTag , tagStyle , shouldMarkTag && styles . inValidMarkedTag ] }
274
+ >
275
+ { this . renderLabel ( tag , shouldMarkTag ) }
276
+ </ View >
277
+ ) ;
278
+ }
279
+
258
280
if ( _ . isFunction ( renderTag ) ) {
259
281
return renderTag ( tag , index , shouldMarkTag , this . getLabel ( tag ) ) ;
260
282
}
@@ -310,16 +332,24 @@ export default class TagsInput extends BaseComponent {
310
332
}
311
333
312
334
render ( ) {
313
- const { disableTagRemoval, containerStyle, hideUnderline} = this . getThemeProps ( ) ;
335
+ const { disableTagRemoval, containerStyle, hideUnderline, validationErrorMessage } = this . getThemeProps ( ) ;
314
336
const tagRenderFn = disableTagRemoval ? this . renderTag : this . renderTagWrapper ;
315
- const { tags} = this . state ;
337
+ const { tags, tagIndexToRemove } = this . state ;
316
338
317
339
return (
318
340
< View style = { [ ! hideUnderline && styles . withUnderline , containerStyle ] } >
319
341
< View style = { styles . tagsList } >
320
342
{ _ . map ( tags , tagRenderFn ) }
321
343
{ this . renderTextInput ( ) }
322
344
</ View >
345
+ { validationErrorMessage ?
346
+ (
347
+ < View >
348
+ < Text style = { [ styles . errorMessage , tagIndexToRemove && styles . errorMessageWhileMarked ] } >
349
+ { validationErrorMessage }
350
+ </ Text >
351
+ </ View >
352
+ ) : null }
323
353
</ View >
324
354
) ;
325
355
}
@@ -336,6 +366,19 @@ export default class TagsInput extends BaseComponent {
336
366
this . input . clear ( ) ;
337
367
}
338
368
}
369
+ const basicTagStyle = {
370
+ borderRadius : BorderRadiuses . br100 ,
371
+ paddingVertical : 4.5 ,
372
+ paddingHorizontal : 12 ,
373
+ marginRight : GUTTER_SPACING ,
374
+ marginVertical : GUTTER_SPACING / 2
375
+ } ;
376
+
377
+ const basicIconStyle = {
378
+ width : 10 ,
379
+ height : 10 ,
380
+ marginRight : 6
381
+ } ;
339
382
340
383
const styles = StyleSheet . create ( {
341
384
withUnderline : {
@@ -353,23 +396,35 @@ const styles = StyleSheet.create({
353
396
} ,
354
397
tag : {
355
398
backgroundColor : Colors . blue30 ,
356
- borderRadius : BorderRadiuses . br100 ,
357
- paddingVertical : 4.5 ,
358
- paddingHorizontal : 12 ,
359
- marginRight : GUTTER_SPACING ,
360
- marginVertical : GUTTER_SPACING / 2
399
+ ...basicTagStyle
400
+ } ,
401
+ inValidTag : {
402
+ borderWidth : 1 ,
403
+ borderColor : Colors . red30 ,
404
+ ...basicTagStyle
405
+ } ,
406
+ inValidMarkedTag : {
407
+ borderColor : Colors . red10
361
408
} ,
362
409
tagMarked : {
363
410
backgroundColor : Colors . dark10
364
411
} ,
365
412
removeIcon : {
366
413
tintColor : Colors . white ,
367
- width : 10 ,
368
- height : 10 ,
369
- marginRight : 6
414
+ ...basicIconStyle
415
+ } ,
416
+ inValidTagRemoveIcon : {
417
+ tintColor : Colors . red10
370
418
} ,
371
419
tagLabel : {
372
420
...Typography . text80 ,
373
421
color : Colors . white
422
+ } ,
423
+ errorMessage : {
424
+ ...Typography . text80 ,
425
+ color : Colors . red30
426
+ } ,
427
+ errorMessageWhileMarked : {
428
+ color : Colors . red10
374
429
}
375
430
} ) ;
0 commit comments