Repository: buildo/react-components (ts)

Issue:
[Meter] Range background color
## requirements
It should be possible to specify meter bar background color based on different values

## specs
- a `range` should accept a new prop named `backgroundColor`
- meter should set the bar background color based on the value specified in the range within which the value falls
- `meter` should accept a new prop `baseBackgroundColor`, for fallback background color

## misc
{optional: other useful info}


Pull request:
#472: [Meter] Range background color (closes #472)
Issue #472

## Test Plan

### tests performed
- `npm run test` ✅ 

![screen shot 2016-06-29 at 12 51 51 pm](https://cloud.githubusercontent.com/assets/925635/16449801/c07f46f0-3df9-11e6-9062-f3886ab0a847.png)





Patch:
diff --git a/examples/components/meter/Meter.example b/examples/components/meter/Meter.example
index 6989d8cd..72021810 100644
--- a/examples/components/meter/Meter.example
+++ b/examples/components/meter/Meter.example
@@ -1,7 +1,7 @@
 class Example extends React.Component {
   render() {
     const ranges = [
-      {startValue: 0, endValue: 30, fillingColor: 'green'},
+      {startValue: 0, endValue: 30, fillingColor: 'green', backgroundColor: 'rgba(0, 255, 0, 0.1)'},
       {startValue: 30, endValue: 60, fillingColor: 'yellow'},
       {startValue: 60, endValue: 80, fillingColor: 'orange', labelColor:'orange'},
       {startValue: 80, endValue: 100, fillingColor: 'red', labelColor: 'red'}
diff --git a/examples/components/meter/MeterWithHole.example b/examples/components/meter/MeterWithHole.example
index 35611d0a..453e0fed 100644
--- a/examples/components/meter/MeterWithHole.example
+++ b/examples/components/meter/MeterWithHole.example
@@ -24,6 +24,7 @@ class Example extends React.Component {
           <Meter
             value={60}
             baseFillingColor={'#ccc'}
+            baseBackgroundColor={'#eee'}
             ranges={ranges}
           />
         </div>
diff --git a/src/meter/Meter.js b/src/meter/Meter.js
index 688ea981..2c336919 100644
--- a/src/meter/Meter.js
+++ b/src/meter/Meter.js
@@ -12,7 +12,8 @@ const Range = t.refinement(t.struct({
   startValue: t.Number,
   endValue: t.Number,
   fillingColor: t.maybe(t.String),
-  labelColor: t.maybe(t.String)
+  labelColor: t.maybe(t.String),
+  backgroundColor: t.maybe(t.String)
 }), r => r.startValue < r.endValue, 'Range');
 
 const Ranges = t.refinement(t.list(Range), (rangeList) => {
@@ -61,6 +62,10 @@ const Props = t.refinement(t.struct({
    * Fallback fillingColor.
    */
   baseFillingColor: t.maybe(t.String),
+  /**
+   * Fallback backgroundColor.
+   */
+  baseBackgroundColor: t.maybe(t.String),
   id: t.maybe(t.String),
   className: t.maybe(t.String),
   style: t.maybe(t.Object)
@@ -124,7 +129,8 @@ export default class Meter extends React.Component {
       max,
       ranges,
       baseFillingColor,
-      baseLabelColor
+      baseLabelColor,
+      baseBackgroundColor
     } = this.props;
 
     const range = find(ranges, ({ startValue, endValue })  => (
@@ -137,6 +143,9 @@ export default class Meter extends React.Component {
       },
       labelStyle: {
         color: range ? range.labelColor : baseLabelColor
+      },
+      barStyle: {
+        backgroundColor: range ? range.backgroundColor : baseBackgroundColor
       }
     };
   }
@@ -155,15 +164,20 @@ export default class Meter extends React.Component {
       className: cx('meter', className),
       fillingStyle: styles.fillingStyle,
       labelStyle: styles.labelStyle,
+      barStyle: styles.barStyle,
       basisSize: styles.basisSize,
       formattedLabel: labelFormatter(props.value, props.min, props.max)
     };
   }
 
-  template({ id, className, style, fillingStyle, labelStyle, basisSize, formattedLabel }) {
+  template({ id, className, style, fillingStyle, labelStyle, barStyle, basisSize, formattedLabel }) {
     return (
       <FlexView {...{ id, className, style }} grow>
-        <FlexView className='bar' grow>
+        <FlexView
+          className='bar'
+          grow
+          style={barStyle}
+        >
           <FlexView
             className='filling'
             basis={basisSize}


Test patch:
diff --git a/test/tests/components/Meter.js b/test/tests/components/Meter.js
index 022b5f2a..66beafb3 100644
--- a/test/tests/components/Meter.js
+++ b/test/tests/components/Meter.js
@@ -13,7 +13,7 @@ describe('Meter', () => {
       min: 0,
       max: 50,
       ranges: [
-        { startValue: 0, endValue: 50, fillingColor: 'green', labelColor: 'red' },
+        { startValue: 0, endValue: 50, fillingColor: 'green', labelColor: 'red', backgroundColor: 'grey' },
         { startValue: 50, endValue: 80, fillingColor: 'yellow' },
         { startValue: 80, endValue: 100 }
       ],
@@ -47,6 +47,13 @@ describe('Meter', () => {
       expect(formattedLabel).toBe('test');
     });
 
+    it('should compute barStyle correctly', ()  => {
+      const { barStyle, ranges } = componentMeter.getLocals();
+      expect(barStyle).toExist();
+      expect(barStyle).toBeA(Object);
+      expect(barStyle.backgroundColor).toBe(ranges[0].backgroundColor);
+    });
+
     it('should compute fillingStyle correctly', ()  => {
       const { fillingStyle, ranges } = componentMeter.getLocals();
       expect(fillingStyle).toExist();
@@ -119,5 +126,28 @@ describe('Meter', () => {
       const { fillingStyle } = meter.getLocals();
       expect(fillingStyle.backgroundColor).toNotExist();
     });
+
+    it('bar background color should be the base color if there\'s no matching range', ()  => {
+      const meter = newComponent(Meter, {
+        value: 20,
+        baseBackroundColor: '#ccc',
+        ranges: [
+          { startValue: 50, endValue: 80, backgroundColor: 'yellow' }
+        ]
+      });
+      const { barStyle, baseBackgroundColor } = meter.getLocals();
+      expect(barStyle.backgroundColor).toBe(baseBackgroundColor);
+    });
+
+    it('bar background color should be not defined if there\'s no matching range and no default is given', ()  => {
+      const meter = newComponent(Meter, {
+        value: 20,
+        ranges: [
+          { startValue: 50, endValue: 80, backgroundColor: 'yellow' }
+        ]
+      });
+      const { barStyle } = meter.getLocals();
+      expect(barStyle.backgroundColor).toNotExist();
+    });
   });
 });