diff --git a/components/molecule/dataCounter/src/index.js b/components/molecule/dataCounter/src/index.js index b9140bd16..d36e30b28 100644 --- a/components/molecule/dataCounter/src/index.js +++ b/components/molecule/dataCounter/src/index.js @@ -31,7 +31,8 @@ const MoleculeDataCounter = forwardRef( size = inputSizes.MEDIUM, substractIcon = '-', initialValue, - value + value, + allowCustomValue = false }, ref ) => { @@ -65,14 +66,21 @@ const MoleculeDataCounter = forwardRef( const decrementDisabled = disabled || internalValue <= numMin const incrementDisabled = disabled || internalValue >= numMax + const sanitize = value => { + if (!value) return 0 + if (isNaN(value)) return 0 + return value + } + const assignDiff = (event, {diff, lastAction}) => { setInternalValue(currentValue => { + const finalValue = allowCustomValue && lastAction === 'change' ? sanitize(diff) : currentValue + diff typeof onChange === 'function' && onChange(event, { - value: String(currentValue + diff), + value: String(finalValue), action: lastAction }) - return value === undefined ? currentValue + diff : currentValue + return value === undefined ? finalValue : currentValue }) lastAction && setLastActions(lastAction) } @@ -90,6 +98,17 @@ const MoleculeDataCounter = forwardRef( } const handleChange = (event, {value}) => { + if (allowCustomValue) { + const parsedIntNewValue = parseInt(value, 10) + + assignDiff(event, { + diff: parsedIntNewValue, + lastAction: ACTIONS.CHANGE + }) + + return + } + const parsedIntNewValue = parseInt(value, 10) const diffValue = isNaN(parsedIntNewValue) && 0 @@ -228,7 +247,10 @@ MoleculeDataCounter.propTypes = { addIcon: PropTypes.node, /** Icon to show on substract button */ - substractIcon: PropTypes.node + substractIcon: PropTypes.node, + + /** Flag to allow the input value to be editable */ + allowCustomValue: PropTypes.bool } export default MoleculeDataCounter diff --git a/components/molecule/dataCounter/test/index.test.js b/components/molecule/dataCounter/test/index.test.js index cbd9f7c69..6e4fa1bbf 100644 --- a/components/molecule/dataCounter/test/index.test.js +++ b/components/molecule/dataCounter/test/index.test.js @@ -299,6 +299,83 @@ describe(json.name, () => { expect(input.value).to.equal(`${initialValue}`) }) + it('given allowCustomValue we can directly write the value', () => { + // Given + const spy = sinon.spy() + const props = { + charsSize: 10, + label: 'label', + minValueHelpText: 'minValueHelpText', + minValueErrorText: 'minValueErrorText', + maxValueHelpText: 'maxValueHelpText', + maxValueErrorText: 'maxValueErrorText', + onChange: spy, + min: 0, + max: 2, + initialValue: 2, + allowCustomValue: true + } + const {initialValue} = props + + // When + const {getByRole} = setup(props) + const input = getByRole('textbox') + // Then + expect(input.value).to.equal(`${initialValue}`) + + // And + // When + fireEvent.change(input, {target: {value: '44'}}) + expect(input.value).to.equal('44') + + fireEvent.change(input, {target: {value: '66'}}) + expect(input.value).to.equal('66') + + fireEvent.change(input, {target: {value: '4-'}}) + expect(input.value).to.equal('4') + + fireEvent.change(input, {target: {value: ''}}) + expect(input.value).to.equal('0') + + fireEvent.change(input, {target: {value: '-'}}) + expect(input.value).to.equal('0') + }) + + it('given allowCustomValue false we cannot directly write the value', () => { + // Given + const spy = sinon.spy() + const props = { + charsSize: 10, + label: 'label', + minValueHelpText: 'minValueHelpText', + minValueErrorText: 'minValueErrorText', + maxValueHelpText: 'maxValueHelpText', + maxValueErrorText: 'maxValueErrorText', + onChange: spy, + min: 0, + max: 2, + initialValue: 2 + } + const {initialValue} = props + + // When + const {getByRole} = setup(props) + const input = getByRole('textbox') + // Then + expect(input.value).to.equal(`${initialValue}`) + + // And + // When + fireEvent.change(input, {target: {value: '44'}}) + expect(input.value).to.equal(`${initialValue}`) + + fireEvent.change(input, {target: {value: ''}}) + expect(input.value).to.equal(`${initialValue}`) + + fireEvent.change(input, {target: {value: '-'}}) + expect(input.value).to.equal(`${initialValue}`) + }) + it('should not allow to reach NaN values', () => { // Given const {getByRole, getByDisplayValue} = setup({value: 10})