@@ -2,103 +2,103 @@ import React from 'react';
22import styled from '@emotion/styled' ;
33
44import space from 'app/styles/space' ;
5+ import { Theme } from 'app/utils/theme' ;
56
6- type PillProps = {
7+ enum PILL_TYPE {
8+ POSITIVE = 'positive' ,
9+ NEGATIVE = 'negative' ,
10+ }
11+
12+ type Props = {
713 name : string ;
814 value : string | boolean | undefined | null ;
15+ children ?: React . ReactNode ;
916} ;
1017
11- class Pill extends React . PureComponent < PillProps > {
12- getRenderTypeAndValue = ( ) => {
13- const { value} = this . props ;
18+ const Pill = React . memo ( ( { name, value, children} : Props ) => {
19+ const getTypeAndValue = ( ) : Partial < { type : PILL_TYPE ; renderValue : string } > => {
1420 if ( value === undefined ) {
1521 return { } ;
1622 }
1723
18- let type : PillValueProps [ 'type' ] ;
19- let renderValue : string | undefined ;
20-
2124 switch ( value ) {
2225 case 'true' :
2326 case true :
24- type = 'positive' ;
25- renderValue = 'true' ;
26- break ;
27+ return {
28+ type : PILL_TYPE . POSITIVE ,
29+ renderValue : 'true' ,
30+ } ;
2731 case 'false' :
2832 case false :
29- type = 'negative' ;
30- renderValue = 'false' ;
31- break ;
33+ return {
34+ type : PILL_TYPE . NEGATIVE ,
35+ renderValue : 'false' ,
36+ } ;
3237 case null :
3338 case undefined :
34- type = 'negative' ;
35- renderValue = 'n/a' ;
36- break ;
39+ return {
40+ type : PILL_TYPE . NEGATIVE ,
41+ renderValue : 'n/a' ,
42+ } ;
3743 default :
38- renderValue = value . toString ( ) ;
44+ return {
45+ type : undefined ,
46+ renderValue : String ( value ) ,
47+ } ;
3948 }
40-
41- return { type, renderValue} ;
4249 } ;
4350
44- render ( ) {
45- const { name, children} = this . props ;
46- const { type, renderValue} = this . getRenderTypeAndValue ( ) ;
51+ const { type, renderValue} = getTypeAndValue ( ) ;
52+
53+ return (
54+ < StyledPill type = { type } >
55+ < PillName > { name } </ PillName >
56+ < PillValue > { children ?? renderValue } </ PillValue >
57+ </ StyledPill >
58+ ) ;
59+ } ) ;
4760
48- return (
49- < StyledPill >
50- < PillName > { name } </ PillName >
51- < PillValue type = { type } > { children || renderValue } </ PillValue >
52- </ StyledPill >
53- ) ;
61+ const getPillBorder = ( { type, theme} : { type ?: PILL_TYPE ; theme : Theme } ) => {
62+ switch ( type ) {
63+ case PILL_TYPE . POSITIVE :
64+ return `
65+ background: ${ theme . green100 } ;
66+ border: 1px solid ${ theme . green400 } ;
67+ ` ;
68+ case PILL_TYPE . NEGATIVE :
69+ return `
70+ background: ${ theme . red100 } ;
71+ border: 1px solid ${ theme . red400 } ;
72+ ` ;
73+ default :
74+ return '' ;
5475 }
55- }
76+ } ;
5677
57- const StyledPill = styled ( 'li' ) `
58- white-space: nowrap;
59- margin: 0 10px 10px 0;
60- display: flex;
61- border: 1px solid ${ p => p . theme . borderDark } ;
62- border-radius: ${ p => p . theme . button . borderRadius } ;
63- box-shadow: ${ p => p . theme . dropShadowLightest } ;
64- line-height: 1.2;
65- max-width: 100%;
66- &:last-child {
67- margin-right: 0;
78+ const getPillValueColor = ( { type, theme} : { type ?: PILL_TYPE ; theme : Theme } ) => {
79+ switch ( type ) {
80+ case PILL_TYPE . POSITIVE :
81+ return `
82+ border-left-color: ${ theme . green400 } ;
83+ ` ;
84+ case PILL_TYPE . NEGATIVE :
85+ return `
86+ border-left-color: ${ theme . red400 } ;
87+ ` ;
88+ default :
89+ return `background: ${ theme . gray100 } ;` ;
6890 }
69- ` ;
91+ } ;
7092
7193const PillName = styled ( 'span' ) `
7294 padding: ${ space ( 0.5 ) } ${ space ( 1 ) } ;
7395 min-width: 0;
7496 white-space: nowrap;
97+ display: flex;
98+ align-items: center;
7599` ;
76100
77- type PillValueProps = {
78- type : 'positive' | 'negative' | undefined ;
79- } ;
80- const PillValue = styled ( PillName ) < PillValueProps > `
81- ${ p => {
82- switch ( p . type ) {
83- case 'positive' :
84- return `
85- background: ${ p . theme . green100 } ;
86- border: 1px solid ${ p . theme . green400 } ;
87- margin: -1px;
88- ` ;
89- case 'negative' :
90- return `
91- background: ${ p . theme . red100 } ;
92- border: 1px solid ${ p . theme . red400 } ;
93- margin: -1px;
94- ` ;
95- default :
96- return `
97- background: ${ p . theme . gray100 } ;
98- ` ;
99- }
100- } }
101-
101+ const PillValue = styled ( PillName ) `
102102 border-left: 1px solid ${ p => p . theme . borderDark } ;
103103 border-radius: ${ p =>
104104 `0 ${ p . theme . button . borderRadius } ${ p . theme . button . borderRadius } 0` } ;
@@ -127,4 +127,24 @@ const PillValue = styled(PillName)<PillValueProps>`
127127 }
128128` ;
129129
130+ const StyledPill = styled ( 'li' ) < { type ?: PILL_TYPE } > `
131+ white-space: nowrap;
132+ margin: 0 10px 10px 0;
133+ display: flex;
134+ border: 1px solid ${ p => p . theme . borderDark } ;
135+ border-radius: ${ p => p . theme . button . borderRadius } ;
136+ box-shadow: ${ p => p . theme . dropShadowLightest } ;
137+ line-height: 1;
138+ max-width: 100%;
139+ :last-child {
140+ margin-right: 0;
141+ }
142+
143+ ${ getPillBorder } ;
144+
145+ ${ PillValue } {
146+ ${ getPillValueColor } ;
147+ }
148+ ` ;
149+
130150export default Pill ;
0 commit comments