diff --git a/Example/App.js b/Example/App.js
index 387a63a1..d1436e82 100644
--- a/Example/App.js
+++ b/Example/App.js
@@ -60,7 +60,27 @@ export default class App extends Component {
rightButtonBackgroundColor="#18c2ef"
leftButtonBackgroundColor="#ff8080"
/>
+
+ Numeric Input Examples with four Buttons
+
{ this.setState({ value1 }); console.log(this.state.value1); }}
+ onLimitReached={(isMin, msg) => console.log(isMin, msg)}
+ totalWidth={80}
+ totalHeight={30}
+ iconSize={10}
+ step={1}
+ minValue={0}
+ valueType="real"
+ fourButton
+ rounded
+ textColor="#B0228C"
+ iconStyle={{ color: "white" }}
+ rightButtonBackgroundColor="#18c2ef"
+ leftButtonBackgroundColor="#ff8080"
+ />
+ { this.setState({ v1 }); console.log(v1) }}
diff --git a/NumericInput/NumericInput.js b/NumericInput/NumericInput.js
index 29255483..e4f74823 100644
--- a/NumericInput/NumericInput.js
+++ b/NumericInput/NumericInput.js
@@ -20,9 +20,14 @@ export default class NumericInput extends Component {
}
// this.props refers to the new props
- componentDidUpdate() {
+ componentDidUpdate(prevProps) {
const initSent = !(this.props.initValue !== 0 && !this.props.initValue);
-
+ if (prevProps.value !== this.props.value) {
+ this.setState({
+ value: this.props.value,
+ stringValue: this.props.value.toString(),
+ });
+ }
// compare the new value (props.initValue) with the existing/old one (this.state.value)
if (this.props.initValue !== this.state.value && initSent) {
this.setState({
@@ -36,6 +41,36 @@ export default class NumericInput extends Component {
updateBaseResolution = (width, height) => {
calcSize = create({ width, height })
}
+ startInc = () => {
+ this.inc();
+ this.incInterval = setInterval(this.inc, 200);
+ }
+ stopInc = () => {
+ clearInterval(this.incInterval);
+ }
+
+ startDec = () => {
+ this.dec();
+ this.decInterval = setInterval(this.dec, 200);
+ }
+ stopDec = () => {
+ clearInterval(this.decInterval);
+ }
+ startInc10 = () => {
+ this.inc10();
+ this.inc10Interval = setInterval(this.inc10, 200);
+ }
+ stopInc10 = () => {
+ clearInterval(this.inc10Interval);
+ }
+
+ startDec10 = () => {
+ this.dec10();
+ this.dec10Interval = setInterval(this.dec10, 200);
+ }
+ stopDec10 = () => {
+ clearInterval(this.dec10Interval);
+ }
inc = () => {
let value = this.props.value && (typeof this.props.value === 'number') ? this.props.value : this.state.value
if (this.props.maxValue === null || (value + this.props.step < this.props.maxValue)) {
@@ -51,6 +86,21 @@ export default class NumericInput extends Component {
if (value !== this.props.value)
this.props.onChange && this.props.onChange(Number(value))
}
+ inc10 = () => {
+ let value = this.props.value && (typeof this.props.value === 'number') ? this.props.value : this.state.value
+ if (this.props.maxValue === null || (value + this.props.step * 10 < this.props.maxValue)) {
+ value = (value + this.props.step * 10).toFixed(12)
+ value = this.props.valueType === 'real' ? parseFloat(value) : parseInt(value)
+ this.setState({ value, stringValue: value.toString() })
+ } else if (this.props.maxValue !== null) {
+ this.props.onLimitReached(true, 'Reached Maximum Value!')
+ value = this.props.maxValue
+ this.setState({ value, stringValue: value.toString() })
+
+ }
+ if (value !== this.props.value)
+ this.props.onChange && this.props.onChange(Number(value))
+ }
dec = () => {
let value = this.props.value && (typeof this.props.value === 'number') ? this.props.value : this.state.value
if (this.props.minValue === null || (value - this.props.step > this.props.minValue)) {
@@ -64,6 +114,19 @@ export default class NumericInput extends Component {
this.props.onChange && this.props.onChange(Number(value))
this.setState({ value, stringValue: value.toString() })
}
+ dec10 = () => {
+ let value = this.props.value && (typeof this.props.value === 'number') ? this.props.value : this.state.value
+ if (this.props.minValue === null || (value - this.props.step * 10> this.props.minValue)) {
+ value = (value - this.props.step * 10).toFixed(12)
+ value = this.props.valueType === 'real' ? parseFloat(value) : parseInt(value)
+ } else if (this.props.minValue !== null) {
+ this.props.onLimitReached(false, 'Reached Minimum Value!')
+ value = this.props.minValue
+ }
+ if (value !== this.props.value)
+ this.props.onChange && this.props.onChange(Number(value))
+ this.setState({ value, stringValue: value.toString() })
+ }
isLegalValue = (value, mReal, mInt) => value === '' || (((this.props.valueType === 'real' && mReal(value)) || (this.props.valueType !== 'real' && mInt(value))) && (this.props.maxValue === null || (parseFloat(value) <= this.props.maxValue)) && (this.props.minValue === null || (parseFloat(value) >= this.props.minValue)))
realMatch = (value) => value && value.match(/-?\d+(\.(\d+)?)?/) && value.match(/-?\d+(\.(\d+)?)?/)[0] === value.match(/-?\d+(\.(\d+)?)?/).input
@@ -156,36 +219,77 @@ export default class NumericInput extends Component {
}
render() {
+ const step = this.props.step
const editable = this.props.editable
+ const fourButton = this.props.fourButton
const sepratorWidth = (typeof this.props.separatorWidth === 'undefined') ? this.props.sepratorWidth : this.props.separatorWidth;//supporting old property name sepratorWidth
const borderColor = this.props.borderColor
const iconStyle = [style.icon, this.props.iconStyle]
const totalWidth = this.props.totalWidth
const totalHeight = this.props.totalHeight ? this.props.totalHeight : (totalWidth * 0.4)
- const inputWidth = this.props.type === 'up-down' ? (totalWidth * 0.6) : (totalWidth * 0.4)
- const borderRadiusTotal = totalHeight * 0.18
- const fontSize = totalHeight * 0.38
+ const inputWidth = this.props.type === 'up-down' ? (totalWidth * 0.6) : (fourButton ? totalWidth * 0.3 : totalWidth * 0.4)
+ const borderRadiusTotal = totalHeight * 0.1
+ const fontSize = totalHeight * 0.45
const textColor = this.props.textColor
+ const lableTextColor = this.props.lableTextColor
const maxReached = this.state.value === this.props.maxValue
const minReached = this.state.value === this.props.minValue
const inputContainerStyle = this.props.type === 'up-down' ?
[style.inputContainerUpDown, { width: totalWidth, height: totalHeight, borderColor: borderColor }, this.props.rounded ? { borderRadius: borderRadiusTotal } : {}, this.props.containerStyle] :
- [style.inputContainerPlusMinus, { width: totalWidth, height: totalHeight, borderColor: borderColor }, this.props.rounded ? { borderRadius: borderRadiusTotal } : {}, this.props.containerStyle]
+ [style.inputContainerPlusMinus, { width: totalWidth + 24, height: totalHeight+10, borderColor: 'white' }, this.props.rounded ? { borderRadius: borderRadiusTotal } : {}, this.props.containerStyle]
+ const lableStyle = [style.lableTextStyle, { color: lableTextColor }]
+ const lable2Style = [style.lableTextStyle, { color: lableTextColor, fontSize: fontSize * 0.7}]
const inputStyle = this.props.type === 'up-down' ?
[style.inputUpDown, { width: inputWidth, height: totalHeight, fontSize: fontSize, color: textColor, borderRightWidth: 2, borderRightColor: borderColor }, this.props.inputStyle] :
- [style.inputPlusMinus, { width: inputWidth, height: totalHeight, fontSize: fontSize, color: textColor, borderRightWidth: sepratorWidth, borderLeftWidth: sepratorWidth, borderLeftColor: borderColor, borderRightColor: borderColor }, this.props.inputStyle]
+ [style.inputPlusMinus, { width: inputWidth, height: totalHeight+10, fontSize: fontSize+2, color: textColor, borderRightWidth: sepratorWidth, borderLeftWidth: sepratorWidth, borderLeftColor: borderColor, borderRightColor: borderColor, borderColor:borderColor, borderWidth: 2, borderRadius: borderRadiusTotal }, this.props.inputStyle]
const upDownStyle = [{ alignItems: 'center', width: totalWidth - inputWidth, backgroundColor: this.props.upDownButtonsBackgroundColor, borderRightWidth: 1, borderRightColor: borderColor }, this.props.rounded ? { borderTopRightRadius: borderRadiusTotal, borderBottomRightRadius: borderRadiusTotal } : {}]
const rightButtonStyle = [
{
- position: 'absolute',
+ // position: 'absolute',
zIndex: -1,
right: 0,
- height: totalHeight - 2,
+ height: totalHeight + 1,
+ flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 0,
+ borderBottomWidth: 0.5,
backgroundColor: this.props.rightButtonBackgroundColor,
- width: (totalWidth - inputWidth) / 2
+ width: fourButton ? (totalWidth - inputWidth + 20) / 4 : (totalWidth - inputWidth + 20) / 2,
+ },
+ this.props.rounded ?
+ { borderTopLeftRadius: borderRadiusTotal, borderBottomLeftRadius: borderRadiusTotal }
+ : {}]
+ const rightButton10Style = [
+ {
+ // position: 'absolute',
+ zIndex: -1,
+ right: 0,
+ height: totalHeight - 7,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderWidth: 0,
+ borderBottomWidth: 0.5,
+ backgroundColor: this.props.rightButton10BackgroundColor,
+ width: fourButton ? (totalWidth - inputWidth + 20) / 4 : (totalWidth - inputWidth + 20) / 2,
+ },
+ this.props.rounded ?
+ { borderTopLeftRadius: borderRadiusTotal, borderBottomLeftRadius: borderRadiusTotal }
+ : {}]
+ const leftButtonStyle = [
+ {
+ // position: 'absolute',
+ zIndex: -1,
+ left: 0,
+ height: totalHeight + 1,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: this.props.leftButtonBackgroundColor,
+ width: fourButton ? (totalWidth - inputWidth + 20) / 4 : (totalWidth - inputWidth + 20) / 2,
+ borderBottomWidth: 0.5,
+ borderWidth: 0
},
this.props.rounded ?
{
@@ -193,32 +297,38 @@ export default class NumericInput extends Component {
borderBottomRightRadius: borderRadiusTotal
}
: {}]
- const leftButtonStyle = [
+ const leftButton10Style = [
{
- position: 'absolute',
+ // position: 'absolute',
zIndex: -1,
left: 0,
- height: totalHeight - 2,
+ height: totalHeight - 7,
+ flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
- backgroundColor: this.props.leftButtonBackgroundColor,
- width: (totalWidth - inputWidth) / 2,
+ color: this.props.textColor,
+ backgroundColor: this.props.leftButton10BackgroundColor,
+ borderBottomWidth: 0.5,
+ width: fourButton ? (totalWidth - inputWidth + 20) / 4 : (totalWidth - inputWidth + 20) / 2,
borderWidth: 0
},
this.props.rounded ?
- { borderTopLeftRadius: borderRadiusTotal, borderBottomLeftRadius: borderRadiusTotal }
+ {
+ borderTopRightRadius: borderRadiusTotal,
+ borderBottomRightRadius: borderRadiusTotal
+ }
: {}]
const inputWraperStyle = {
alignSelf: 'center',
- borderLeftColor: borderColor,
- borderLeftWidth: sepratorWidth,
- borderRightWidth: sepratorWidth,
- borderRightColor: borderColor
+ // borderLeftColor: borderColor,
+ // borderLeftWidth: sepratorWidth,
+ // borderRightWidth: sepratorWidth,
+ // borderRightColor: borderColor
}
if (this.props.type === 'up-down')
return (
- this.ref = ref} onBlur={this.onBlur} onFocus={this.onFocus} />
+ this.ref = ref} onBlur={this.onBlur} onFocus={this.onFocus} />
)
else return (
- )
@@ -250,6 +376,9 @@ const style = StyleSheet.create({
backgroundColor: 'grey',
height: calcSize(80),
},
+ lableTextStyle: {
+ fontFamily: 'BYekan',
+ },
inputContainerUpDown: {
flexDirection: 'row',
alignItems: 'center',
@@ -291,8 +420,10 @@ NumericInput.propTypes = {
sepratorWidth: PropTypes.number,
type: PropTypes.oneOf(['up-down', 'plus-minus']),
valueType: PropTypes.oneOf(['real', 'integer']),
+ fourButton: PropTypes.any,
rounded: PropTypes.any,
textColor: PropTypes.string,
+ lableTextColor: PropTypes.string,
containerStyle: PropTypes.any,
inputStyle: PropTypes.any,
initValue: PropTypes.number,
@@ -319,8 +450,10 @@ NumericInput.defaultProps = {
totalWidth: calcSize(220),
sepratorWidth: 1,
type: 'plus-minus',
+ fourButton: false,
rounded: false,
- textColor: 'black',
+ textColor: '#B0228C',
+ lableTextColor: '#400010',
containerStyle: {},
inputStyle: {},
initValue: null,
@@ -330,8 +463,10 @@ NumericInput.defaultProps = {
maxValue: null,
step: 1,
upDownButtonsBackgroundColor: 'white',
- rightButtonBackgroundColor: 'white',
- leftButtonBackgroundColor: 'white',
+ rightButtonBackgroundColor: '#99b3ff',
+ leftButtonBackgroundColor: '#ffb299',
+ rightButton10BackgroundColor: '#bfcfff',
+ leftButton10BackgroundColor: '#ffcfbf',
editable: true,
validateOnBlur: true,
reachMaxIncIconStyle: {},
diff --git a/README.md b/README.md
index 09390e11..bb0309e9 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ import NumericInput from 'react-native-numeric-input'
step={1.5}
valueType='real'
rounded
+ fourButton
textColor='#B0228C'
iconStyle={{ color: 'white' }}
rightButtonBackgroundColor='#EA3788'
@@ -95,21 +96,24 @@ Name | Type | Defa
**minValue** |`number` | none
**maxValue** |`number` | none
**step** |`number` | 1
-**valueType** |`'integer'` or `'real'` | `'integer'`
+**valueType** |`'integer'` or `'real'` | `'integer'`
**initValue** |`number` | null if not used will start at 0
**iconSize** |`number` | calcSize(30)
**borderColor** |`string` | `'#d4d4d4'`
**iconStyle** |`object` | none
**totalWidth** |`number` | calcSize(220)
-**separatorWidth** |`number` | 1
+**separatorWidth** |`number` | 1
**type** |`'plus-minus'` or `'up-down'` | `'plus-minus'`
**rounded** |`boolean` | false
+**fourButton** |`boolean` | false
**textColor** |`string` | `'black'`
**containerStyle** |`object` | none
**inputStyle** |`object` | none
**upDownButtonsBackgroundColor** |`string` | `'white'`
**rightButtonBackgroundColor** |`string` | `'white'`
**leftButtonBackgroundColor** |`string` | `'white'`
+**rightButton10BackgroundColor** |`string` | `'white'`
+**leftButton10BackgroundColor** |`string` | `'white'`
**totalHeight** |`number` | none
**onChange** |`function` | none - required prop
**onLimitReached** |`function` | none (empty function)
@@ -128,6 +132,7 @@ Name | Type | Defa
* **totalWidth prop** - this prop is for the entire component width, and all other sizes are derived from it , unless given other size props
* **initValue prop** - if using value prop, this is not needed and the initial value can be given by the value prop
* **validateOnBlur** - added on version 1.3.2, if set to false the text input will validate while typing, not recommended, so just keep it true unless there is a good reason not to use the default functionallity
+* **fourButton** - used to activate two new buttons to increment and decrement ×10 steps - **optional**
* **reachMaxIncIconStyle** - added on version 1.4.0, used to set style to the increment button icon in case maxValue is reached - **optional**
* **reachMaxDecIconStyle** - added on version 1.4.0, used to set style to the decrement button icon in case maxValue is reached - **optional**
* **reachMinIncIconStyle** - added on version 1.4.0, used to set style to the increment button icon in case minValue is reached - **optional**