react-native-1app
Version:
466 lines (445 loc) • 13.8 kB
JavaScript
import React from "react";
import {
StyleSheet,
Text,
Animated,
View,
TouchableOpacity,
Image,
NativeModules,
LayoutAnimation,
} from "react-native";
import TextInput from "./TextInput";
import { openDialog, closeDialog } from "./DialogAlert";
import { Menu, MenuItem } from "./Menu";
const { UIManager } = NativeModules;
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
export default class Select extends React.Component {
constructor(props) {
super(props);
this.state = {
fontSize:
this.props.placeholder || this.verifyValue(this.props.value) ? 12 : 15,
marginTop:
this.props.placeholder || this.verifyValue(this.props.value) ? 0 : 14,
};
}
verifyValue(value) {
if (value === undefined) return false;
if (value === "") return false;
if (value === null) return false;
return true;
}
openSelect() {
let { title, onChange, clearDisabled } = this.props;
let actions = !clearDisabled
? [{ title: "LIMPAR", onPress: () => onChange(undefined, {}) }]
: [];
openDialog({
body: <SelectOpen {...this.props} key={"select"+new Date().getTime()}/>,
title,
align: "top",
actions: [{ title: "OK" }, ...actions],
styleDescricao: { margin: 0 },
});
}
componentWillReceiveProps(props) {
if (props.placeholder) return;
if (
this.validarValue(props.value) &&
!this.validarValue(this.props.value)
) {
LayoutAnimation.spring();
this.setState({ fontSize: 12, marginTop: 0 });
}
if (
!this.validarValue(props.value) &&
this.validarValue(this.props.value)
) {
LayoutAnimation.spring();
this.setState({ fontSize: 15, marginTop: 14 });
}
}
validarValue(v) {
return v == 0 || v;
}
render() {
let {
list,
label,
value,
key_value,
key_label,
style,
disabled,
type,
placeholder,
inputNative,
notIcon,
renderSelect,
} = this.props;
let { fontSize, marginTop } = this.state;
let item = list.find((i) => i[key_value] == value);
style = StyleSheet.flatten(style);
let textAlign = style.textAlign || "left";
return (
<TouchableOpacity
style={[
styles.button,
{ borderColor: style.color || styles.value.color },
style,
]}
disabled={disabled}
onPress={() => {
if (type == "menu") {
this._menu.showMenu();
} else {
this.openSelect();
}
}}
>
<View style={styles.view}>
{!inputNative ? (
<Animated.Text
style={[
styles.label,
{
textAlign,
marginTop,
fontSize,
color: style.color || styles.label.color,
},
]}
>
{label}
</Animated.Text>
) : null}
{item && item[key_label] ? (
renderSelect ? (
renderSelect(item, item[key_label], key_label)
) : (
<Text
style={[
styles.value,
{
textAlign,
color: style.color || styles.label.color,
fontSize: style.fontSize || styles.label.fontSize,
},
]}
>
{item[key_label]}
</Text>
)
) : null}
{placeholder && (!item || !item[key_label]) ? (
<Text
style={[
styles.value,
{
textAlign,
color: style.color || styles.value.color,
fontSize: style.fontSize || styles.label.fontSize,
},
]}
>
{placeholder}
</Text>
) : null}
{type == "menu" ? (
<SelectMenu
{...this.props}
ref={(ref) => {
this._menu = ref;
}}
/>
) : null}
</View>
{!notIcon && !disabled ? (
<Image
style={{
width: 15,
height: 15,
tintColor: style.color || styles.value.color,
}}
source={{ uri: icon_abrir }}
/>
) : null}
</TouchableOpacity>
);
}
}
class SelectMenu extends React.Component {
setMenuRef = (ref) => {
this._menu = ref;
};
hideMenu = () => {
this._menu.hide();
};
showMenu = () => {
this._menu.show();
};
render() {
let {
key_label,
list,
onChange,
key_value,
value,
renderItem,
} = this.props;
return (
<Menu
ref={this.setMenuRef}
button={<View style={{ alignSelf: "stretch" }} />}
>
{list.map((item, i) => {
if (renderItem)
return (
<TouchableOpacity
onPress={() => {
this.hideMenu();
onChange(item[key_value], item, i);
}}
style={{
flexDirection: "row",
alignItems: "center",
padding: 5,
}}
>
{renderItem(item, i)}
</TouchableOpacity>
);
return (
<MenuItem
onPress={() => {
this.hideMenu();
onChange(item[key_value], item, i);
}}
>
{item[key_label]}
</MenuItem>
);
})}
</Menu>
);
}
}
class SelectOpen extends React.Component {
constructor(props) {
super(props);
this.state = {
texto: "",
};
}
getSuggestions() {
let { key_label, list } = this.props;
let { texto } = this.state;
if (texto === "" || !texto) return list;
return list.filter(
(item) =>
this.limparString(item[key_label]).indexOf(this.limparString(texto)) >=
0
);
}
limparString(s) {
return s
.trim()
.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
.toLowerCase();
}
render() {
let {
key_label,
list,
key_sub_label,
onChange,
key_value,
value,
renderItem,
} = this.props;
return (
<View style={styles.view}>
{list.length > 9 && (
<View style={styles.contenerInput}>
<TextInput
style={styles.textinput}
value={this.state.texto}
placeholder="Filtrar"
onChange={(texto) => {
this.setState({ texto });
}}
inputNative={true}
/>
</View>
)}
{this.getSuggestions().map((item, i) => (
<TouchableOpacity
key={"item_cell_select" + i}
style={styles.buttonItem}
onPress={() => {
onChange(item[key_value], item, i);
closeDialog();
}}
>
{(renderItem && renderItem(item, i)) || [
<View style={styles.viewItem}>
<Text style={styles.valueItem}>{item[key_label]}</Text>
{item[key_sub_label] && (
<Text style={styles.label}>{item[key_sub_label]}</Text>
)}
</View>,
<Image
style={{ width: 20, height: 20 }}
source={{
uri: item[key_value] == value ? icon_check : icon_not_check,
}}
/>,
]}
</TouchableOpacity>
))}
</View>
);
}
}
Select.defaultProps = {
label: "-",
value: undefined,
list: [],
key_value: "value",
key_label: "text",
style: {},
disabled: false,
type: "modal",
onChange: () => console.log("onChange"),
title: "Select",
placeholder: "",
inputNative: false,
notIcon: false,
};
var styles = StyleSheet.create({
button: {
alignSelf: "stretch",
justifyContent: "center",
alignItems: "center",
height: 45,
flexDirection: "row",
borderStyle: "solid",
borderWidth: 0,
borderBottomWidth: 0.8,
borderColor: "rgba(22,22,22,0.7)",
marginTop: 10,
paddingRight: 5,
},
buttonItem: {
alignSelf: "stretch",
justifyContent: "center",
alignItems: "center",
height: 45,
flexDirection: "row",
padding: 2,
borderStyle: "solid",
borderWidth: 0,
borderTopWidth: 1,
borderColor: "rgba(187,177,177,0.53)",
paddingLeft: 10,
paddingRight: 10,
},
view: {
alignSelf: "stretch",
flex: 1,
flexDirection: "column",
padding: 2,
justifyContent: "center",
alignItems: "center",
},
viewItem: {
alignSelf: "stretch",
flex: 1,
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
padding: 2,
},
value: {
color: "rgba(0,0,0,1)",
fontWeight: "normal",
alignSelf: "stretch",
// paddingTop:2
},
valueItem: {
color: "rgba(0,0,0,1)",
alignSelf: "stretch",
fontWeight: "normal",
// paddingTop:2
},
label: {
color: "rgba(22,22,22,1)",
alignSelf: "stretch",
fontWeight: "normal",
fontSize: 12,
marginBottom: 2,
},
textinput: {
color: "rgba(0,0,0,1)",
alignSelf: "stretch",
textAlign: "left",
fontWeight: "normal",
height: 35,
},
contenerInput: {
backgroundColor: "rgba(255,255,255,1)",
padding: 5,
margin: 3,
marginBottom: 10,
borderRadius: 5,
alignSelf: "stretch",
elevation: 3,
shadowColor: "#000000",
shadowOpacity: 0.3,
shadowRadius: 1.5,
shadowOffset: {
height: 1,
width: 0,
},
},
});
const icon_limpar =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIxSURBVGhD7Zg/SxxBHIbPBCSkMGiTJtjERkTszGfQIlaxsQkhjY21ILYKgmlCAlEQktLOwjIfIE1AQROEpElnoeLfFEF9n70b2MW93ZndOW8I88CDN7/dvdt3uX1drhGJRCKRSKQaj2V/AD6QlRmSh/ImAE/linwknXgif0je5EweddFjaQJtyx5pRa/8Kjnwm+Tr1W2G5R/JOU0xsOGz5AAOfMYgEOYl5/UuWZVgdj6RowwCYlZybh+TVQEz8lr+k5MMAsMqyAt5KdmRA0KkNEi6ZlcZBEphEGr2p2SHLflQutInP8mBZFXMtHzTfOlM2yC+anZD8h7fZVEYQnD/cR+OMXCkbZAvkg11a/ap3JNFYUwI9llgUIHcIL5rtiiMjxBwJ0i6ZicYeCIvjK8QkAlCzV61BmzwTTrMgfQVAjJBTM2+Z9EhCPNb8jm4JH2QCULFstiVVG8nSH+dsKzNbMkEoWJ3WgOqlwr2STrEsixrMxcyQYCqNY/Eaww8kXdj21SzLXeCAJV7LtlAFdelqJ0Isy/rhskNAi8lH04Vv2JQEZuK9RGmbRAwGy8k1VyFOcnFKKtYE+aXrPIkURgEPkh2oJqfM6jAeOtvGYQZbL50pjQIT7z3Uct1KQ0Cna5lH1gFgU7Vsi+sg4DvWvaJUxBI1zLVGgrrkiCLycoSk55afiv5P9MtuZj8lsXF5QcSfmNwwtRyKP6Vr6Uz1DJXYjMAOY8RGYlEIpFI5D+j0bgF9AZG0kiHxyMAAAAASUVORK5CYII=";
const icon_abrir =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFBSURBVGhD7dcxKEVRHMfxKzEYeCUmC0oZXjYmZVE22Ty7UdksNoNRGZVN2ZRJWZSJTQalbCZKj8FAwvc/KOkf99137r3n5vetz3KHc/5nOucmSimllFJKKRVRwxiJXD/+bAUfEbvFKFK1Bm+Rst1jHC21AW+xsjQxgUxtwVu0aE+YQuY6sANv8aI8YwZt14k9eJvk7QVzCJYd5gDeZnl5wwKC140jeJuGZodYQm714ATe5qG8Yxm514szeEOEsIrCquEC3iDtWEfhDeAK3kBZbKK0hnADb7BWbKP07LVsDzlvwDR2YRdvFI3hDt6gv9mH3VFRVccDvIE9h+hClE3iEd7g3x3DLtiom4Y99LwDmFPYxVqJZmEPvp+HOEcfKtU8XvF1iEuk+teOsUXYA/Aag/ahyjVgF6dSSiml1P8qST4BgcHE7LLrfy0AAAAASUVORK5CYII=";
const icon_check =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJCSURBVGhD7dm/zwxBHMfxQygoaGj8SAhRoJGgEYlEKf4B/gBEJREVJZ2CBL1fiUKl0CjQqBQSPwoKJIQoECFC8H4nd8nm8r2b3Xt296aYT/Jq5mZ3n+/tMzsze4OSkpIFZRMu4TV+41/PvuMhjmEZZspx/EJ0gXl4hi1oFL+B6GTz9h7rUCsbkdOdGHcXtXIR0Qlysg3JOLCjg3NyGlOzGPN4OjV1FVOzEtGBubmBqSmF9KwU0pev+DHWFsm6kD84iN34MGybJOtCTsCsxjtEfUayLeQyzHI8RtSnKstC7mEJFuHWsC0lu0Kewmuac4j6RLIq5BNcaZvD+IuoXySbQn5iD8xeNN02tFqIz/yoPcVv3jtgNsM7E/WbprVC3mI9LlTa6joL47WeI+qT0loh1+CTxpxB1CdyHT6dluL+sG0Wrf5r3cTozYaTWWqwOj+M+jtvRH3qan2wu392EjNHMGlT9grO2OYkoj5NtF6IHsDjzCH4RKp+/gU7YPzcNVX181l0UoieYA3MfnyD7f7RB2Asxhdu48fOorNC9BIbYHbhM3w/ZtYitRBsotNC9AZbYUZjou5CsInOC9FH7ITxUXsHUb+F6KUQOcD34XylrU29FaIuX7v2WkiXSiG5SRayAtGBuXHRmkxbs2+X3D4k8wjRwTlxgZrMUUQH58Kd6Sok457hBaKT5OAUase9tD88RieaJwe5y55G8ddTN07RCfvmksc70biIarbD3+yu4HaPnCt8Ojmwa42JkpKSSRkM/gM5mlZVH7Nq9gAAAABJRU5ErkJggg==";
const icon_not_check =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFnSURBVGhD7dm/LgRRGIbxjQKJQqhoaDQU7kYkhAsQiZKKO9AJatFwARJKboKCFhHxr6Lg+YqTfJlM5syss2emeJ/kl2jO7Pl2Zleyp6eU+ldzOMADfvCb2RdusIlh9NUWvlH2Am24wzwaZUOUXaxtz5hBrexxKrsT9mi9ZvSO4h7MBWplnwm/8AVLGEXupnEMvx+ziGj38ItsiLa7hN/TNiobgv92sr/buBPFNuAHOUJl4/AL3tCFVuD3dYrKNMiA0yCBBkmcBgk0SOI0SKBBEqdBAg2SOA0SaJDEaZBAgyROgwQaJHEaJNAgiWs8yBj8gg90oVX4fZ0gmh13+UVTaLtd+D3tI9o1/KLoL98Dzt7IJ/g9rSOaHTz6ReYK9tO+nZXksow9PMLvxR73CUQbwS384i7ZQe0WULydXXAOO4xq1Czs4LHsgrl9wo7bGg/hs4NHu8ghzjKy/xX27bSGSSil+q7X+wMfPDQg3iRBBwAAAABJRU5ErkJggg==";
// ==========================EXEMPLO==========================
// <Select list={[{
// nome: "Apple",
// id: 10,
// },{
// nome: "Strawberry",
// id: 17,
// },{
// nome: "Pineapple",
// id: 13,
// },{
// nome: "Banana",
// id: 14,
// },{
// nome: "Watermelon",
// id: 15,
// },{
// nome: "Kiwi fruit",
// id: 16,
// }]}
// key_label='name'
// key_value='id'
// key_sub_label='id'
// label='Frutas'
// value={this.state.value}
// onChange={(value,data)=>{
// // console.log(value,data);
// this.setState({value})
// }}
// />