@99xt/first-born
Advanced tools
Comparing version 1.1.2 to 1.1.3
{ | ||
"name": "@99xt/first-born", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "React Native UI Framework", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
102
README.md
@@ -222,16 +222,24 @@ # first-born | ||
| Prop | Description | Default | | ||
|------------------------|--------------------------------------------------------------|-----------------| | ||
| **`placeholder`** | Display this string if value not selected yet. iOS only. | `'Select Date'` | | ||
| **`formatChosenDate`** | User defined function that returns a formatted date. | _None_ | | ||
| **`onDateChange`** | User defined function to run when selected date changes. | _None_ | | ||
| **`defaultDate`** | Initially picked date. | _None_ | | ||
| **`minimumDate`** | Minimum in date range. | _None_ | | ||
| **`maximumDate`** | Maximum in date range. | _None_ | | ||
| **`modalTransparent`** | If DatePicker modal is transparent. iOS only. | _true_ | | ||
| **`animationType`** | Type of entry/exit animation for DatePicker modal. iOS only. | `'fade'` | | ||
| **`locale`** | Locale of DatePicker. iOS only. | _None_ | | ||
| **`mode`** | Type of picker ('date', 'time'). | `'date'` | | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| **`is24Hour`** | If DatePicker with mode 'time' has 24 hour time format. | _true_ | | ||
| Prop | Description | Default | | ||
|------------------------|---------------------------------------------------------------------|-----------------| | ||
| **`placeholder`** | Display this string if value not selected yet. iOS only. | `'Select Date'` | | ||
| **`formatChosenDate`** | User defined function that returns a formatted date. | _None_ | | ||
| **`onDateChange`** | User defined function to run when selected date changes. | _None_ | | ||
| **`defaultDate`** | Initially picked date. | _None_ | | ||
| **`minimumDate`** | Minimum in date range. | _None_ | | ||
| **`maximumDate`** | Maximum in date range. | _None_ | | ||
| **`modalTransparent`** | If DatePicker modal is transparent. iOS only. | _true_ | | ||
| **`animationType`** | Type of entry/exit animation for DatePicker modal. iOS only. | `'fade'` | | ||
| **`locale`** | Locale of DatePicker. iOS only. | _None_ | | ||
| **`mode`** | Type of picker ('date', 'time'). | `'date'` | | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| **`isValid`** | User defined validation function, that returns true for valid input | _None_ | | ||
| **`errorMessage`** | Error message to display below input, if validation fails | _None_ | | ||
| **`rounded`** | If DatePicker style is rounded edges. | _false_ | | ||
| **`underline`** | If DatePicker style is an underline. | _false_ | | ||
| **`defaultStyle`** | If DatePicker style is default as seen above. | _true_ | | ||
| **`noStyle`** | If DatePicker has no framework defined style. | _false_ | | ||
| **`style`** | Custom DatePicker inactive style. (Style object) | _None_ | | ||
| **`activeStyle`** | Custom DatePicker active style. (Style object) | _None_ | | ||
| **`errorStyle`** | Custom DatePicker error style. (Style object) | _None_ | | ||
@@ -252,6 +260,14 @@ #### Input | ||
| Prop | Description | Default | | ||
|---------------|--------------------------------------------------------------------|-----------| | ||
| **`isValid`** | User defined validation function, that returns true for valid text | _None_ | | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| Prop | Description | Default | | ||
|--------------------|--------------------------------------------------------------------|-----------| | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| **`isValid`** | User defined validation function, that returns true for valid text | _None_ | | ||
| **`errorMessage`** | Error message to display below input, if validation fails | _None_ | | ||
| **`rounded`** | If Input style is rounded edges. | _false_ | | ||
| **`underline`** | If Input style is an underline. | _false_ | | ||
| **`defaultStyle`** | If Input style is default as seen above. | _true_ | | ||
| **`noStyle`** | If Input has no framework defined style. | _false_ | | ||
| **`style`** | Custom Input inactive style. (Style object) | _None_ | | ||
| **`activeStyle`** | Custom Input active style. (Style object) | _None_ | | ||
| **`errorStyle`** | Custom Input error style. (Style object) | _None_ | | ||
@@ -278,9 +294,18 @@ #### Picker | ||
| Prop | Description | Default | | ||
|------------------------|--------------------------------------------------------------|-------------------| | ||
| **`placeholder`** | Display this string if value not selected yet. iOS only. | `'Select Option'` | | ||
| **`modalTransparent`** | If DatePicker modal is transparent. iOS only. | _true_ | | ||
| **`animationType`** | Type of entry/exit animation for DatePicker modal. iOS only. | `'fade'` | | ||
| **`mode`** | Type of picker mode ('dialog', 'dropdown'). Android only. | `'dropdown'` | | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| Prop | Description | Default | | ||
|------------------------|---------------------------------------------------------------------|-------------------| | ||
| **`placeholder`** | Display this string if value not selected yet. iOS only. | `'Select Option'` | | ||
| **`modalTransparent`** | If Picker modal is transparent. iOS only. | _true_ | | ||
| **`animationType`** | Type of entry/exit animation for Picker modal. iOS only. | `'fade'` | | ||
| **`mode`** | Type of picker mode ('dialog', 'dropdown'). Android only. | `'dropdown'` | | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| **`isValid`** | User defined validation function, that returns true for valid input | _None_ | | ||
| **`errorMessage`** | Error message to display below input, if validation fails | _None_ | | ||
| **`rounded`** | If Picker style is rounded edges. | _false_ | | ||
| **`underline`** | If Picker style is an underline. | _false_ | | ||
| **`defaultStyle`** | If Picker style is default as seen above. | _true_ | | ||
| **`noStyle`** | If Picker has no framework defined style. | _false_ | | ||
| **`style`** | Custom Picker inactive style. (Style object) | _None_ | | ||
| **`activeStyle`** | Custom Picker active style. (Style object) | _None_ | | ||
| **`errorStyle`** | Custom Picker error style. (Style object) | _None_ | | ||
@@ -303,5 +328,13 @@ #### TextArea | ||
| Prop | Description | Default | | ||
|-------------|-----------------------------------------|-----------| | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| Prop | Description | Default | | ||
|--------------------|--------------------------------------------------------------------|-----------| | ||
| **`color`** | Color of the `TextInput` when in focus. | _primary_ | | ||
| **`isValid`** | User defined validation function, that returns true for valid text | _None_ | | ||
| **`errorMessage`** | Error message to display below input, if validation fails | _None_ | | ||
| **`underline`** | If DatePicker style is an underline. | _false_ | | ||
| **`defaultStyle`** | If DatePicker style is default as seen above. | _true_ | | ||
| **`noStyle`** | If DatePicker has no framework defined style. | _false_ | | ||
| **`style`** | Custom DatePicker inactive style. (Style object) | _None_ | | ||
| **`activeStyle`** | Custom DatePicker active style. (Style object) | _None_ | | ||
| **`errorStyle`** | Custom DatePicker error style. (Style object) | _None_ | | ||
@@ -672,5 +705,12 @@ ### Molecules | ||
| Prop | Description | Default | | ||
|-------------|-------------------------------------------|-----------| | ||
| **`color`** | Color of all form elements when in focus. | _primary_ | | ||
| Prop | Description | Default | | ||
|--------------------|----------------------------------------------------|-----------| | ||
| **`color`** | Color of all form elements when in focus. | _primary_ | | ||
| **`rounded`** | If form element style is rounded edges. | _false_ | | ||
| **`underline`** | If form element style is an underline. | _false_ | | ||
| **`defaultStyle`** | If form element style is default as seen above. | _true_ | | ||
| **`noStyle`** | If form element has no framework defined style. | _false_ | | ||
| **`style`** | Custom form element inactive style. (Style object) | _None_ | | ||
| **`activeStyle`** | Custom form element active style. (Style object) | _None_ | | ||
| **`errorStyle`** | Custom form element error style. (Style object) | _None_ | | ||
@@ -677,0 +717,0 @@ But each type of input has corresponding proptypes to the molecules named below; |
@@ -22,2 +22,3 @@ import React, { Component } from "react"; | ||
focused: false, | ||
error: false, | ||
defaultDate: props.defaultDate ? props.defaultDate : new Date(), | ||
@@ -41,43 +42,118 @@ chosenDate: | ||
timeZoneOffsetInMinutes, | ||
mode | ||
mode, | ||
noStyle, | ||
rounded, | ||
underline, | ||
defaultStyle, | ||
style, | ||
activeStyle, | ||
errorStyle, | ||
errorMessage, | ||
errorColor | ||
} = this.props; | ||
const { focused, chosenDate, defaultDate } = this.state; | ||
const { focused, chosenDate, defaultDate, error } = this.state; | ||
let inputStyle = [styles.input]; | ||
let inputActiveStyle = [styles.input]; | ||
let inputErrorStyle = [styles.input]; | ||
if (noStyle) { | ||
inputStyle.push(style); | ||
inputActiveStyle.push(activeStyle); | ||
inputErrorStyle.push(errorStyle); | ||
} else if (underline) { | ||
inputStyle.push(styles.underline); | ||
inputActiveStyle.push({ | ||
borderBottomColor: color, | ||
borderBottomWidth: 2 | ||
}); | ||
inputErrorStyle.push({ | ||
borderBottomColor: errorColor, | ||
borderBottomWidth: 2 | ||
}); | ||
} else if (defaultStyle || rounded) { | ||
if (Platform.OS === "android") { | ||
inputStyle.push(styles.default, styles.defaultAndroid); | ||
inputActiveStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} else { | ||
inputStyle.push(styles.default, styles.defaultIos); | ||
inputActiveStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
if (rounded) { | ||
inputStyle.push(styles.rounded); | ||
inputActiveStyle.push(styles.rounded, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.rounded, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
} | ||
if (Platform.OS === "android") { | ||
return ( | ||
<View | ||
style={ | ||
focused | ||
? [ | ||
styles.datePickerAndroid, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.datePickerAndroid | ||
} | ||
> | ||
<Text | ||
ref={c => (this._root = c)} | ||
style={!chosenDate ? styles.input : styles.inputValue} | ||
onPress={() => | ||
mode === "date" | ||
? this.openAndroidDatePicker() | ||
: this.openAndroidTimePicker() | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
> | ||
{chosenDate | ||
? this.formatChosenDate(chosenDate) | ||
: placeholder} | ||
</Text> | ||
<Icon | ||
name="calendar" | ||
onPress={() => | ||
mode === "date" | ||
? this.openAndroidDatePicker() | ||
: this.openAndroidTimePicker() | ||
} | ||
style={styles.icon} | ||
color={focused ? color : commonColors.inputGrey} | ||
size={20} | ||
/> | ||
<Text | ||
ref={c => (this._root = c)} | ||
style={ | ||
!chosenDate | ||
? styles.inputPlaceholder | ||
: styles.inputValue | ||
} | ||
onPress={() => | ||
mode === "date" | ||
? this.openAndroidDatePicker() | ||
: this.openAndroidTimePicker() | ||
} | ||
> | ||
{chosenDate | ||
? this.formatChosenDate(chosenDate) | ||
: placeholder} | ||
</Text> | ||
<View style={styles.iconContainer}> | ||
<Icon | ||
name="calendar" | ||
onPress={() => | ||
mode === "date" | ||
? this.openAndroidDatePicker() | ||
: this.openAndroidTimePicker() | ||
} | ||
style={styles.icon} | ||
color={focused ? color : commonColors.inputGrey} | ||
size={20} | ||
/> | ||
</View> | ||
</View> | ||
{error && errorMessage && ( | ||
<Text size="caption_big" color={errorColor}> | ||
{errorMessage} | ||
</Text> | ||
)} | ||
</View> | ||
@@ -87,11 +163,10 @@ ); | ||
return ( | ||
<View> | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
focused | ||
? [ | ||
styles.datePickerIos, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.datePickerIos | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
@@ -101,3 +176,7 @@ > | ||
ref={c => (this._root = c)} | ||
style={!chosenDate ? styles.input : styles.inputValue} | ||
style={ | ||
!chosenDate | ||
? styles.inputPlaceholder | ||
: styles.inputValue | ||
} | ||
onPress={() => this.openIosDatePicker()} | ||
@@ -109,10 +188,17 @@ > | ||
</Text> | ||
<Icon | ||
onPress={() => this.openIosDatePicker()} | ||
name="calendar" | ||
style={styles.icon} | ||
color={focused ? color : commonColors.inputGrey} | ||
size={20} | ||
/> | ||
<View style={styles.iconContainer}> | ||
<Icon | ||
onPress={() => this.openIosDatePicker()} | ||
name="calendar" | ||
color={focused ? color : commonColors.inputGrey} | ||
size={20} | ||
style={styles.icon} | ||
/> | ||
</View> | ||
</View> | ||
{error && errorMessage && ( | ||
<Text size="caption_big" color={errorColor}> | ||
{errorMessage} | ||
</Text> | ||
)} | ||
<Modal | ||
@@ -149,6 +235,12 @@ supportedOrientations={["portrait", "landscape"]} | ||
setDate(date) { | ||
const { onDateChange, isValid } = this.props; | ||
this.setState({ chosenDate: new Date(date) }); | ||
if (this.props.onDateChange) { | ||
this.props.onDateChange(date); | ||
if (onDateChange) { | ||
onDateChange(date); | ||
} | ||
if (isValid) { | ||
this.setState({ error: !isValid(date) }); | ||
} | ||
} | ||
@@ -231,2 +323,4 @@ | ||
color: PropTypes.string, | ||
isValid: PropTypes.func, | ||
errorMessage: PropTypes.string, | ||
formatChosenDate: PropTypes.func, | ||
@@ -242,2 +336,8 @@ onDateChange: PropTypes.func, | ||
mode: PropTypes.oneOf(["date", "time"]), | ||
activeStyle: PropTypes.object, | ||
errorStyle: PropTypes.object, | ||
rounded: PropTypes.bool, | ||
underline: PropTypes.bool, | ||
defaultStyle: PropTypes.bool, | ||
noStyle: PropTypes.bool, | ||
...TextInput.propTypes | ||
@@ -252,34 +352,20 @@ }; | ||
mode: "date", | ||
is24Hour: true | ||
is24Hour: true, | ||
errorColor: commonColors.error, | ||
defaultStyle: true | ||
}; | ||
const styles = StyleSheet.create({ | ||
datePickerAndroid: { | ||
inputContainer: { | ||
width: "100%", | ||
flexDirection: "row", | ||
marginVertical: 10, | ||
justifyContent: "center", | ||
alignItems: "center", | ||
height: 45, | ||
paddingHorizontal: 10, | ||
borderRadius: 10, | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
marginBottom: 5 | ||
}, | ||
datePickerIos: { | ||
width: "100%", | ||
flexDirection: "row", | ||
borderRadius: 15, | ||
marginVertical: 10, | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9, | ||
justifyContent: "center", | ||
icon: { | ||
marginRight: 5 | ||
}, | ||
iconContainer: { | ||
alignItems: "center", | ||
height: 45, | ||
paddingLeft: 10 | ||
justifyContent: "center" | ||
}, | ||
icon: { | ||
paddingRight: 15 | ||
}, | ||
input: { | ||
inputPlaceholder: { | ||
flex: 1, | ||
@@ -291,3 +377,32 @@ color: commonColors.inputGrey | ||
color: commonColors.black | ||
}, | ||
input: { | ||
marginTop: 10, | ||
marginBottom: 5, | ||
width: "100%", | ||
height: 45, | ||
flexDirection: "row", | ||
justifyContent: "center", | ||
alignItems: "center" | ||
}, | ||
default: { | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
}, | ||
defaultAndroid: { | ||
paddingHorizontal: 5, | ||
borderRadius: 10 | ||
}, | ||
defaultIos: { | ||
paddingHorizontal: 10, | ||
borderRadius: 15 | ||
}, | ||
underline: { | ||
borderBottomColor: commonColors.inputGrey, | ||
borderBottomWidth: 0.9 | ||
}, | ||
rounded: { | ||
borderRadius: 45 / 2, | ||
paddingHorizontal: 10 | ||
} | ||
}); |
@@ -6,2 +6,4 @@ import React, { Component } from "react"; | ||
import { commonColors } from "../utils/color"; | ||
import { Text } from "./Text"; | ||
import { Icon } from "./Icon"; | ||
@@ -32,24 +34,85 @@ export class Input extends Component { | ||
render() { | ||
const { placeholder, color, ...otherProps } = this.props; | ||
const { | ||
errorMessage, | ||
color, | ||
noStyle, | ||
rounded, | ||
underline, | ||
defaultStyle, | ||
style, | ||
activeStyle, | ||
errorStyle, | ||
errorColor, | ||
iconLeft, | ||
iconRight, | ||
...otherProps | ||
} = this.props; | ||
const { error, focused } = this.state; | ||
if (Platform.OS === "android") { | ||
return ( | ||
let inputStyle = [styles.input]; | ||
let inputActiveStyle = [styles.input]; | ||
let inputErrorStyle = [styles.input]; | ||
if (noStyle) { | ||
inputStyle.push(style); | ||
inputActiveStyle.push(activeStyle); | ||
inputErrorStyle.push(errorStyle); | ||
} else if (underline) { | ||
inputStyle.push(styles.underline); | ||
inputActiveStyle.push({ | ||
borderBottomColor: color, | ||
borderBottomWidth: 2 | ||
}); | ||
inputErrorStyle.push({ | ||
borderBottomColor: errorColor, | ||
borderBottomWidth: 2 | ||
}); | ||
} else if (defaultStyle || rounded) { | ||
if (Platform.OS === "android") { | ||
inputStyle.push(styles.default, styles.defaultAndroid); | ||
inputActiveStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} else { | ||
inputStyle.push(styles.default, styles.defaultIos); | ||
inputActiveStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
if (rounded) { | ||
inputStyle.push(styles.rounded); | ||
inputActiveStyle.push(styles.rounded, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.rounded, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
} | ||
return ( | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
this.state.error | ||
? [ | ||
styles.inputAndroid, | ||
{ | ||
borderColor: commonColors.error, | ||
borderWidth: 2 | ||
} | ||
] | ||
: this.state.focused | ||
? [ | ||
styles.inputAndroid, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.inputAndroid | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
> | ||
{iconLeft && this.renderIcon(iconLeft, { marginRight: 5 })} | ||
<TextInput | ||
@@ -59,7 +122,4 @@ ref={c => (this._root = c)} | ||
underlineColorAndroid={"transparent"} | ||
placeholder={placeholder} | ||
placeholderTextColor={ | ||
this.state.error | ||
? commonColors.error | ||
: commonColors.inputGrey | ||
error ? errorColor : commonColors.inputGrey | ||
} | ||
@@ -75,46 +135,23 @@ onFocus={() => this.setState({ focused: true })} | ||
/> | ||
{iconRight && this.renderIcon(iconRight, { marginLeft: 5 })} | ||
</View> | ||
); | ||
} | ||
{error && errorMessage && ( | ||
<Text size="footnote" color={errorColor}> | ||
{errorMessage} | ||
</Text> | ||
)} | ||
</View> | ||
); | ||
} | ||
renderIcon(icon, style) { | ||
const { errorColor } = this.props; | ||
const { error } = this.state; | ||
return ( | ||
<View | ||
style={ | ||
this.state.error | ||
? [ | ||
styles.inputIos, | ||
{ | ||
borderColor: commonColors.error, | ||
borderWidth: 2 | ||
} | ||
] | ||
: this.state.focused | ||
? [ | ||
styles.inputIos, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.inputIos | ||
} | ||
> | ||
<TextInput | ||
ref={c => (this._root = c)} | ||
style={{ | ||
width: "100%", | ||
height: "100%", | ||
textAlignVertical: "bottom" | ||
}} | ||
underlineColorAndroid={"transparent"} | ||
placeholder={placeholder} | ||
placeholderTextColor={ | ||
this.state.error | ||
? commonColors.error | ||
: commonColors.inputGrey | ||
} | ||
onFocus={() => this.setState({ focused: true })} | ||
onBlur={() => this.setState({ focused: false })} | ||
onSubmitEditing={() => { | ||
this.setState({ focused: true }); | ||
Keyboard.dismiss(); | ||
}} | ||
{...otherProps} | ||
onChangeText={this.handleTextChange} | ||
<View style={styles.iconContainer}> | ||
<Icon | ||
{...icon} | ||
size={25} | ||
style={style} | ||
color={error ? errorColor : icon.color} | ||
/> | ||
@@ -129,2 +166,16 @@ </View> | ||
isValid: PropTypes.func, | ||
errorMessage: PropTypes.string, | ||
activeStyle: PropTypes.object, | ||
errorStyle: PropTypes.object, | ||
rounded: PropTypes.bool, | ||
underline: PropTypes.bool, | ||
defaultStyle: PropTypes.bool, | ||
noStyle: PropTypes.bool, | ||
errorColor: PropTypes.string, | ||
iconRight: PropTypes.shape({ | ||
...Icon.propTypes | ||
}), | ||
iconLeft: PropTypes.shape({ | ||
...Icon.propTypes | ||
}), | ||
...TextInput.propTypes | ||
@@ -134,24 +185,43 @@ }; | ||
Input.defaultProps = { | ||
color: commonColors.primary | ||
color: commonColors.primary, | ||
errorColor: commonColors.error, | ||
defaultStyle: true | ||
}; | ||
const styles = StyleSheet.create({ | ||
inputAndroid: { | ||
borderRadius: 10, | ||
paddingHorizontal: 5, | ||
marginVertical: 10, | ||
inputContainer: { | ||
width: "100%", | ||
marginBottom: 5 | ||
}, | ||
input: { | ||
marginTop: 10, | ||
marginBottom: 5, | ||
width: "100%", | ||
height: 45, | ||
flexDirection: "row" | ||
}, | ||
default: { | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9, | ||
height: 45 | ||
borderWidth: 0.9 | ||
}, | ||
inputIos: { | ||
borderRadius: 15, | ||
defaultAndroid: { | ||
paddingHorizontal: 5, | ||
borderRadius: 10 | ||
}, | ||
defaultIos: { | ||
paddingHorizontal: 10, | ||
marginVertical: 10, | ||
width: "100%", | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9, | ||
height: 45 | ||
borderRadius: 15 | ||
}, | ||
underline: { | ||
borderBottomColor: commonColors.inputGrey, | ||
borderBottomWidth: 0.9 | ||
}, | ||
rounded: { | ||
borderRadius: 45 / 2, | ||
paddingHorizontal: 10 | ||
}, | ||
iconContainer: { | ||
alignItems: "center", | ||
justifyContent: "center" | ||
} | ||
}); |
@@ -14,2 +14,3 @@ import React, { Component } from "react"; | ||
focused: false, | ||
error: false, | ||
chosenValue: | ||
@@ -23,6 +24,12 @@ !props.placeholder && props.selectedValue | ||
setValue = value => { | ||
const { onValueChange, isValid } = this.props; | ||
this.setState({ chosenValue: value }); | ||
if (this.props.onValueChange) { | ||
this.props.onValueChange(value); | ||
if (onValueChange) { | ||
onValueChange(value); | ||
} | ||
if (isValid) { | ||
this.setState({ error: !isValid(value) }); | ||
} | ||
}; | ||
@@ -38,27 +45,98 @@ | ||
children, | ||
noStyle, | ||
rounded, | ||
underline, | ||
defaultStyle, | ||
style, | ||
activeStyle, | ||
errorStyle, | ||
errorMessage, | ||
errorColor, | ||
...otherProps | ||
} = this.props; | ||
const { focused, chosenValue } = this.state; | ||
const { focused, error, chosenValue } = this.state; | ||
let inputStyle = [ | ||
Platform.OS === "android" ? styles.inputAndroid : styles.inputIos | ||
]; | ||
let inputActiveStyle = [styles.input]; | ||
let inputErrorStyle = [styles.input]; | ||
if (noStyle) { | ||
inputStyle.push(style); | ||
inputActiveStyle.push(activeStyle); | ||
inputErrorStyle.push(errorStyle); | ||
} else if (underline) { | ||
inputStyle.push(styles.underline); | ||
inputActiveStyle.push({ | ||
borderBottomColor: color, | ||
borderBottomWidth: 2 | ||
}); | ||
inputErrorStyle.push({ | ||
borderBottomColor: errorColor, | ||
borderBottomWidth: 2 | ||
}); | ||
} else if (defaultStyle || rounded) { | ||
if (Platform.OS === "android") { | ||
inputStyle.push(styles.default, styles.defaultAndroid); | ||
inputActiveStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} else { | ||
inputStyle.push(styles.default, styles.defaultIos); | ||
inputActiveStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
if (rounded) { | ||
inputStyle.push(styles.rounded); | ||
inputActiveStyle.push(styles.rounded, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.rounded, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
} | ||
if (Platform.OS === "android") { | ||
return ( | ||
<View | ||
style={ | ||
focused | ||
? [ | ||
styles.pickerAndroid, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.pickerAndroid | ||
} | ||
> | ||
<Picker | ||
style={{ height: 45 }} | ||
ref={c => (this._root = c)} | ||
{...otherProps} | ||
selectedValue={chosenValue} | ||
onValueChange={this.setValue.bind(this)} | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
> | ||
{children} | ||
</Picker> | ||
<Picker | ||
style={{ height: 45 }} | ||
ref={c => (this._root = c)} | ||
{...otherProps} | ||
selectedValue={chosenValue} | ||
onValueChange={this.setValue.bind(this)} | ||
> | ||
{children} | ||
</Picker> | ||
</View> | ||
{error && errorMessage && ( | ||
<Text size="caption_big" color={errorColor}> | ||
{errorMessage} | ||
</Text> | ||
)} | ||
</View> | ||
@@ -68,11 +146,10 @@ ); | ||
return ( | ||
<View> | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
focused | ||
? [ | ||
styles.pickerIos, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.pickerIos | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
@@ -84,4 +161,7 @@ > | ||
!this.state.chosenValue | ||
? styles.input | ||
: [styles.input, { color: commonColors.black }] | ||
? styles.inputPlaceholder | ||
: [ | ||
styles.inputPlaceholder, | ||
{ color: commonColors.black } | ||
] | ||
} | ||
@@ -100,2 +180,7 @@ onPress={() => this.setState({ focused: true })} | ||
</View> | ||
{error && errorMessage && ( | ||
<Text size="caption_big" color={errorColor}> | ||
{errorMessage} | ||
</Text> | ||
)} | ||
<Modal | ||
@@ -140,5 +225,14 @@ supportedOrientations={["portrait", "landscape"]} | ||
color: PropTypes.string, | ||
isValid: PropTypes.func, | ||
errorMessage: PropTypes.string, | ||
animationType: PropTypes.string, | ||
modalTransparent: PropTypes.bool, | ||
mode: PropTypes.string, | ||
activeStyle: PropTypes.object, | ||
errorStyle: PropTypes.object, | ||
rounded: PropTypes.bool, | ||
underline: PropTypes.bool, | ||
defaultStyle: PropTypes.bool, | ||
noStyle: PropTypes.bool, | ||
errorColor: PropTypes.string, | ||
...Picker.propTypes | ||
@@ -152,32 +246,57 @@ }; | ||
mode: "dropdown", | ||
placeholder: "Select Option" | ||
placeholder: "Select Option", | ||
errorColor: commonColors.error, | ||
defaultStyle: true | ||
}; | ||
const styles = StyleSheet.create({ | ||
pickerAndroid: { | ||
inputContainer: { | ||
width: "100%", | ||
marginVertical: 10, | ||
borderRadius: 10, | ||
paddingHorizontal: 5, | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
marginBottom: 5 | ||
}, | ||
pickerIos: { | ||
icon: { | ||
paddingRight: 15 | ||
}, | ||
inputPlaceholder: { | ||
flex: 1, | ||
color: commonColors.inputGrey | ||
}, | ||
inputAndroid: { | ||
marginTop: 10, | ||
marginBottom: 5, | ||
width: "100%", | ||
height: 45 | ||
}, | ||
inputIos: { | ||
marginTop: 10, | ||
marginBottom: 5, | ||
width: "100%", | ||
height: 45, | ||
flexDirection: "row", | ||
borderRadius: 15, | ||
marginVertical: 10, | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9, | ||
justifyContent: "center", | ||
alignItems: "center", | ||
height: 45, | ||
paddingLeft: 10 | ||
alignItems: "center" | ||
}, | ||
icon: { | ||
paddingRight: 15 | ||
default: { | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
}, | ||
input: { | ||
flex: 1, | ||
color: commonColors.inputGrey | ||
defaultAndroid: { | ||
paddingHorizontal: 5, | ||
borderRadius: 10 | ||
}, | ||
defaultIos: { | ||
paddingHorizontal: 10, | ||
borderRadius: 15 | ||
}, | ||
underline: { | ||
borderBottomColor: commonColors.inputGrey, | ||
borderBottomWidth: 0.9 | ||
}, | ||
rounded: { | ||
borderRadius: 45 / 2, | ||
paddingHorizontal: 10 | ||
}, | ||
iconContainer: { | ||
alignItems: "center", | ||
justifyContent: "center" | ||
} | ||
@@ -184,0 +303,0 @@ }); |
@@ -11,19 +11,89 @@ import React, { Component } from "react"; | ||
inputHeight: 100, | ||
focused: false | ||
focused: false, | ||
error: false, | ||
text: "" | ||
}; | ||
} | ||
handleTextChange = text => { | ||
const { isValid, onChangeText } = this.props; | ||
this.setState({ text: text }); | ||
if (onChangeText) { | ||
onChangeText(text); | ||
} | ||
if (isValid) { | ||
this.setState({ error: !isValid(text) }); | ||
} | ||
}; | ||
render() { | ||
const { onChangeText, placeholder, color, ...otherProps } = this.props; | ||
const { | ||
color, | ||
noStyle, | ||
underline, | ||
defaultStyle, | ||
style, | ||
activeStyle, | ||
errorStyle, | ||
errorMessage, | ||
errorColor, | ||
rounded, | ||
...otherProps | ||
} = this.props; | ||
if (Platform.OS === "android") { | ||
return ( | ||
const { focused, error, text, inputHeight } = this.state; | ||
let inputStyle = [styles.input]; | ||
let inputActiveStyle = [styles.input]; | ||
let inputErrorStyle = [styles.input]; | ||
if (noStyle) { | ||
inputStyle.push(style); | ||
inputActiveStyle.push(activeStyle); | ||
inputErrorStyle.push(errorStyle); | ||
} else if (underline) { | ||
inputStyle.push(styles.underline); | ||
inputActiveStyle.push({ | ||
borderBottomColor: color, | ||
borderBottomWidth: 2 | ||
}); | ||
inputErrorStyle.push({ | ||
borderBottomColor: errorColor, | ||
borderBottomWidth: 2 | ||
}); | ||
} else if (defaultStyle || rounded) { | ||
if (Platform.OS === "android") { | ||
inputStyle.push(styles.default, styles.defaultAndroid); | ||
inputActiveStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultAndroid, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} else { | ||
inputStyle.push(styles.default, styles.defaultIos); | ||
inputActiveStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: color, | ||
borderWidth: 2 | ||
}); | ||
inputErrorStyle.push(styles.default, styles.defaultIos, { | ||
borderColor: errorColor, | ||
borderWidth: 2 | ||
}); | ||
} | ||
} | ||
return ( | ||
<View style={styles.inputContainer}> | ||
<View | ||
style={ | ||
this.state.focused | ||
? [ | ||
styles.inputAndroid, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.inputAndroid | ||
error | ||
? inputErrorStyle | ||
: focused | ||
? inputActiveStyle | ||
: inputStyle | ||
} | ||
@@ -34,9 +104,6 @@ > | ||
style={{ | ||
width: "100%", | ||
height: Math.max(90, this.state.inputHeight), | ||
height: Math.max(90, inputHeight), | ||
textAlignVertical: "top" | ||
}} | ||
underlineColorAndroid={"transparent"} | ||
placeholder={placeholder} | ||
onChangeText={onChangeText} | ||
multiline | ||
@@ -52,36 +119,5 @@ onContentSizeChange={event => { | ||
{...otherProps} | ||
onChangeText={this.handleTextChange} | ||
/> | ||
</View> | ||
); | ||
} | ||
return ( | ||
<View | ||
style={ | ||
this.state.focused | ||
? [ | ||
styles.inputIos, | ||
{ borderColor: color, borderWidth: 2 } | ||
] | ||
: styles.inputIos | ||
} | ||
> | ||
<TextInput | ||
ref={c => (this._root = c)} | ||
style={{ | ||
width: "100%", | ||
height: Math.max(90, this.state.inputHeight) | ||
}} | ||
underlineColorAndroid={"transparent"} | ||
placeholder={placeholder} | ||
onChangeText={onChangeText} | ||
multiline | ||
onContentSizeChange={event => { | ||
this.setState({ | ||
inputHeight: event.nativeEvent.contentSize.height | ||
}); | ||
}} | ||
onFocus={() => this.setState({ focused: true })} | ||
onBlur={() => this.setState({ focused: false })} | ||
{...otherProps} | ||
/> | ||
</View> | ||
@@ -94,2 +130,10 @@ ); | ||
color: PropTypes.string, | ||
isValid: PropTypes.func, | ||
errorMessage: PropTypes.string, | ||
activeStyle: PropTypes.object, | ||
errorStyle: PropTypes.object, | ||
underline: PropTypes.bool, | ||
defaultStyle: PropTypes.bool, | ||
noStyle: PropTypes.bool, | ||
errorColor: PropTypes.string, | ||
...TextInput.propTypes | ||
@@ -99,23 +143,33 @@ }; | ||
TextArea.defaultProps = { | ||
color: commonColors.primary | ||
color: commonColors.primary, | ||
errorColor: commonColors.error, | ||
defaultStyle: true | ||
}; | ||
const styles = StyleSheet.create({ | ||
inputAndroid: { | ||
inputContainer: { | ||
width: "100%", | ||
marginVertical: 10, | ||
borderRadius: 10, | ||
paddingHorizontal: 5, | ||
marginBottom: 5 | ||
}, | ||
input: { | ||
marginTop: 10, | ||
marginBottom: 5, | ||
width: "100%" | ||
}, | ||
default: { | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
}, | ||
inputIos: { | ||
borderRadius: 15, | ||
defaultAndroid: { | ||
paddingHorizontal: 5, | ||
borderRadius: 10 | ||
}, | ||
defaultIos: { | ||
paddingHorizontal: 10, | ||
paddingTop: 5, | ||
marginVertical: 10, | ||
width: "100%", | ||
borderColor: commonColors.inputGrey, | ||
borderWidth: 0.9 | ||
borderRadius: 15 | ||
}, | ||
underline: { | ||
borderBottomColor: commonColors.inputGrey, | ||
borderBottomWidth: 0.9 | ||
} | ||
}); |
@@ -23,3 +23,7 @@ import React, { Component } from "react"; | ||
<View style={styles.formElementContainer} key={key}> | ||
{this.renderElements(element, inputColor)} | ||
{this.renderElements( | ||
element, | ||
inputColor, | ||
otherProps | ||
)} | ||
</View> | ||
@@ -32,3 +36,3 @@ ); | ||
renderElements(element, color) { | ||
renderElements(element, color, styleProps) { | ||
element.color = color; | ||
@@ -39,10 +43,10 @@ const { type, pickerData, ...otherProps } = element; | ||
case "text": | ||
return <FormInput {...otherProps} />; | ||
return <FormInput {...styleProps} {...otherProps} />; | ||
case "textarea": | ||
return <FormTextArea {...otherProps} />; | ||
return <FormTextArea {...styleProps} {...otherProps} />; | ||
case "date": | ||
return <FormDatePicker {...otherProps} />; | ||
return <FormDatePicker {...styleProps} {...otherProps} />; | ||
case "picker": | ||
return ( | ||
<FormPicker {...otherProps}> | ||
<FormPicker {...styleProps} {...otherProps}> | ||
{pickerData.map((dataElement, key) => ( | ||
@@ -58,3 +62,10 @@ <Picker.Item {...dataElement} key={key} /> | ||
Form.propTypes = { | ||
color: PropTypes.string | ||
color: PropTypes.string, | ||
activeStyle: PropTypes.object, | ||
errorStyle: PropTypes.object, | ||
rounded: PropTypes.bool, | ||
underline: PropTypes.bool, | ||
defaultStyle: PropTypes.bool, | ||
noStyle: PropTypes.bool, | ||
errorColor: PropTypes.string | ||
}; | ||
@@ -61,0 +72,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
206404
4270
957