1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-04-14 11:18:47 +02:00

159 lines
4.2 KiB
JavaScript
Raw Normal View History

2018-03-09 17:49:35 +00:00
const React = require("react");
const { TouchableOpacity, TouchableWithoutFeedback, Dimensions, Text, Modal, View } = require("react-native");
const { ItemList } = require("lib/components/ItemList.js");
class Dropdown extends React.Component {
constructor() {
super();
this.headerRef_ = null;
}
componentWillMount() {
this.setState({
headerSize: { x: 0, y: 0, width: 0, height: 0 },
listVisible: false,
});
}
2017-12-07 23:24:14 +00:00
updateHeaderCoordinates() {
// https://stackoverflow.com/questions/30096038/react-native-getting-the-position-of-an-element
2017-12-07 23:24:14 +00:00
this.headerRef_.measure((fx, fy, width, height, px, py) => {
this.setState({
2018-03-09 17:49:35 +00:00
headerSize: { x: px, y: py, width: width, height: height },
});
2017-12-07 23:24:14 +00:00
});
}
render() {
const items = this.props.items;
const itemHeight = 60;
2018-03-09 17:49:35 +00:00
const windowHeight = Dimensions.get("window").height - 50;
// Dimensions doesn't return quite the right dimensions so leave an extra gap to make
// sure nothing is off screen.
const listMaxHeight = windowHeight;
2018-03-09 17:49:35 +00:00
const listHeight = Math.min(items.length * itemHeight, listMaxHeight); //Dimensions.get('window').height - this.state.headerSize.y - this.state.headerSize.height - 50;
const maxListTop = windowHeight - listHeight;
const listTop = Math.min(maxListTop, this.state.headerSize.y + this.state.headerSize.height);
const wrapperStyle = {
width: this.state.headerSize.width,
height: listHeight + 2, // +2 for the border (otherwise it makes the scrollbar appear)
marginTop: listTop,
marginLeft: this.state.headerSize.x,
};
const itemListStyle = Object.assign({}, this.props.itemListStyle ? this.props.itemListStyle : {}, {
borderWidth: 1,
2018-03-09 17:49:35 +00:00
borderColor: "#ccc",
});
const itemWrapperStyle = Object.assign({}, this.props.itemWrapperStyle ? this.props.itemWrapperStyle : {}, {
2018-03-09 17:49:35 +00:00
flex: 1,
justifyContent: "center",
height: itemHeight,
paddingLeft: 20,
paddingRight: 10,
});
const headerWrapperStyle = Object.assign({}, this.props.headerWrapperStyle ? this.props.headerWrapperStyle : {}, {
height: 35,
// borderWidth: 1,
// borderColor: '#ccc',
2017-11-19 00:23:18 +00:00
//paddingLeft: 20,
//paddingRight: 20,
flex: 1,
2018-03-09 17:49:35 +00:00
flexDirection: "row",
alignItems: "center",
});
const headerStyle = Object.assign({}, this.props.headerStyle ? this.props.headerStyle : {}, {
flex: 1,
});
const headerArrowStyle = Object.assign({}, this.props.headerStyle ? this.props.headerStyle : {}, {
flex: 0,
2017-11-19 00:23:18 +00:00
marginRight: 10,
});
2018-03-09 17:49:35 +00:00
const itemStyle = Object.assign({}, this.props.itemStyle ? this.props.itemStyle : {}, {});
2018-03-09 17:49:35 +00:00
let headerLabel = "...";
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.value === this.props.selectedValue) {
headerLabel = item.label;
break;
}
}
const closeList = () => {
this.setState({ listVisible: false });
2018-03-09 17:49:35 +00:00
};
2018-03-09 17:49:35 +00:00
const itemRenderer = item => {
return (
2018-03-09 17:49:35 +00:00
<TouchableOpacity
style={itemWrapperStyle}
key={item.value}
onPress={() => {
closeList();
if (this.props.onValueChange) this.props.onValueChange(item.value);
}}
>
<Text ellipsizeMode="tail" numberOfLines={1} style={itemStyle} key={item.value}>
{item.label}
</Text>
</TouchableOpacity>
);
2018-03-09 17:49:35 +00:00
};
return (
2018-03-09 17:49:35 +00:00
<View style={{ flex: 1, flexDirection: "column" }}>
<TouchableOpacity
style={headerWrapperStyle}
ref={ref => (this.headerRef_ = ref)}
onPress={() => {
this.updateHeaderCoordinates();
this.setState({ listVisible: true });
}}
>
<Text ellipsizeMode="tail" numberOfLines={1} style={headerStyle}>
{headerLabel}
</Text>
<Text style={headerArrowStyle}>{"▼"}</Text>
</TouchableOpacity>
2018-03-09 17:49:35 +00:00
<Modal
transparent={true}
visible={this.state.listVisible}
onRequestClose={() => {
closeList();
}}
>
<TouchableWithoutFeedback
onPressOut={() => {
closeList();
}}
>
<View style={{ flex: 1 }}>
<View style={wrapperStyle}>
<ItemList
style={itemListStyle}
items={this.props.items}
itemHeight={itemHeight}
2018-03-09 17:49:35 +00:00
itemRenderer={item => {
return itemRenderer(item);
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
</Modal>
</View>
);
}
}
2018-03-09 17:49:35 +00:00
module.exports = { Dropdown };