Skip to content

Commit 5c89321

Browse files
authored
Merge pull request #410 from CraveFood/fix-amount-selector
Amount selector should truncate values on blur
2 parents 1d68a7b + 5d1d8c4 commit 5c89321

File tree

3 files changed

+58
-35
lines changed

3 files changed

+58
-35
lines changed

packages/amount-selectors/src/components/AmountSelectors.js

+37-26
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,22 @@ const selectorSizeToFontSize = {
2020

2121
class AmountSelectors extends React.Component {
2222
state = {
23-
value: this.props.value,
23+
value: 0,
2424
disableBoth: false,
2525
tooltipText: "",
26-
displayValue: this.props.value
26+
displayValue: ""
2727
};
2828

29+
componentDidMount() {
30+
this.updateStateWithNewValue(this.props.value);
31+
}
32+
33+
componentDidUpdate(prevProps, prevState) {
34+
if (prevProps.value !== this.props.value) {
35+
this.updateStateWithNewValue(this.props.value);
36+
}
37+
}
38+
2939
// Conditions to disable both buttons,
3040
// see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation
3141
disableBoth = validity =>
@@ -49,21 +59,6 @@ class AmountSelectors extends React.Component {
4959
return this.props.onChange(validValue);
5060
};
5161

52-
validValue = value => {
53-
const parsedValue = parseFloat(value) || 0;
54-
return Math.min(this.props.max, Math.max(this.props.min, parsedValue));
55-
};
56-
57-
updateDisplayValue = () => {
58-
const validValue = this.validValue(this.state.value);
59-
this.setState({
60-
value: validValue,
61-
displayValue: validValue.toFixed(2)
62-
});
63-
64-
return this.props.onChange(validValue);
65-
};
66-
6762
decrement = () => {
6863
const value = this.state.value - this.props.step;
6964

@@ -76,15 +71,31 @@ class AmountSelectors extends React.Component {
7671
this.onChange(Math.min(value, this.props.max), this.updateDisplayValue);
7772
};
7873

79-
componentDidUpdate(prevProps, prevState) {
80-
if (prevProps.value !== this.props.value) {
81-
const validValue = this.validValue(this.props.value);
82-
this.setState({
83-
value: validValue,
84-
displayValue: validValue.toFixed(2)
85-
});
86-
}
87-
}
74+
updateDisplayValue = () => {
75+
const validValue = this.updateStateWithNewValue(this.state.value);
76+
77+
return this.props.onChange(validValue);
78+
};
79+
80+
getValidValue = value => {
81+
const parsedValue = parseFloat(value) || 0;
82+
const validValue = Math.min(
83+
this.props.max,
84+
Math.max(this.props.min, parsedValue)
85+
);
86+
87+
return Number(validValue.toFixed(2));
88+
};
89+
90+
updateStateWithNewValue = value => {
91+
const validValue = this.getValidValue(value);
92+
this.setState({
93+
value: validValue,
94+
displayValue: validValue.toFixed(2)
95+
});
96+
97+
return validValue;
98+
};
8899

89100
render() {
90101
return (

packages/amount-selectors/src/components/AmountSelectors.test.js

+12
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,16 @@ describe("Amount selectors", () => {
147147
expect(component.state().displayValue).toBe(expectedDisplayValue);
148148
});
149149
});
150+
151+
test("getValidValue should return a valid value with 2 decimal places", () => {
152+
const component = shallow(<AmountSelectors />);
153+
const { getValidValue } = component.instance();
154+
155+
const value = 3.345678;
156+
const validValue = getValidValue(value);
157+
158+
const expectedValue = Number(value.toFixed(2));
159+
160+
expect(validValue).toBe(expectedValue);
161+
});
150162
});

packages/amount-selectors/src/components/__snapshots__/AmountSelectors.story.storyshot

+9-9
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ exports[`Storyshots Amount selectors Default 1`] = `
357357
size={4}
358358
step={1}
359359
type="number"
360-
value={0}
360+
value="0.00"
361361
/>
362362
</div>
363363
</div>
@@ -757,7 +757,7 @@ exports[`Storyshots Amount selectors Disabled typing 1`] = `
757757
size={4}
758758
step={1}
759759
type="number"
760-
value={0}
760+
value="0.00"
761761
/>
762762
</div>
763763
</div>
@@ -1157,7 +1157,7 @@ exports[`Storyshots Amount selectors Small size 1`] = `
11571157
size={4}
11581158
step={1}
11591159
type="number"
1160-
value={0}
1160+
value="0.00"
11611161
/>
11621162
</div>
11631163
</div>
@@ -1552,7 +1552,7 @@ exports[`Storyshots Amount selectors With 0.5 steps 1`] = `
15521552
size={4}
15531553
step={0.5}
15541554
type="number"
1555-
value={2}
1555+
value="2.00"
15561556
/>
15571557
</div>
15581558
</div>
@@ -1947,7 +1947,7 @@ exports[`Storyshots Amount selectors With 0.5 steps and step mismatch validation
19471947
size={4}
19481948
step={0.5}
19491949
type="number"
1950-
value={2}
1950+
value="2.00"
19511951
/>
19521952
</div>
19531953
</div>
@@ -2342,7 +2342,7 @@ exports[`Storyshots Amount selectors With a max value of 3 1`] = `
23422342
size={4}
23432343
step={0.5}
23442344
type="number"
2345-
value={2}
2345+
value="2.00"
23462346
/>
23472347
</div>
23482348
</div>
@@ -2742,7 +2742,7 @@ exports[`Storyshots Amount selectors With onChange function 1`] = `
27422742
size={4}
27432743
step={1}
27442744
type="number"
2745-
value={0}
2745+
value="0.00"
27462746
/>
27472747
</div>
27482748
</div>
@@ -3137,7 +3137,7 @@ exports[`Storyshots Amount selectors With value set 1`] = `
31373137
size={4}
31383138
step={1}
31393139
type="number"
3140-
value={2}
3140+
value="2.00"
31413141
/>
31423142
</div>
31433143
</div>
@@ -3533,7 +3533,7 @@ exports[`Storyshots Amount selectors With value set after mount 1`] = `
35333533
size={4}
35343534
step={1}
35353535
type="number"
3536-
value={10}
3536+
value="10.00"
35373537
/>
35383538
</div>
35393539
</div>

0 commit comments

Comments
 (0)