Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include and tested new component SinglePickerMaterialDialogWithSearch #89

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .expo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
> Why do I have a folder named ".expo" in my project?
The ".expo" folder is created when an Expo project is started using "expo start" command.

> What does the "packager-info.json" file contain?
The "packager-info.json" file contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.

> What does the "settings.json" file contain?
The "settings.json" file contains the server configuration that is used to serve the application manifest.

> Should I commit the ".expo" folder?
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.

Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
8 changes: 8 additions & 0 deletions .expo/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"hostType": "lan",
"lanType": "ip",
"dev": true,
"minify": false,
"urlRandomness": null,
"https": false
}
5,349 changes: 0 additions & 5,349 deletions example/yarn.lock

This file was deleted.

31 changes: 28 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,30 @@ interface SinglePickerMaterialDialogStatic extends Dialog {
onCancel?(): void;
}

interface SinglePickerMaterialDialogWithSearchStatic extends Dialog {
/**
* List of items shown to the user to select from
*/
items: PickerItem[];

/**
* Currently selected item chosen from the items array
*/
selectedItem: PickerItem;

/**
* Callback function fired when the confirm(ok) button is pressed
* @param selected
*/
onOk?(selected: SelectedItem): void;

/**
* Callback function fired when the cancel button is pressed
* @param selected
*/
onCancel?(): void;
}

interface MultiPickerMaterialDialogStatic extends Dialog {
/**
* List of items shown to the user to select from
Expand All @@ -168,8 +192,9 @@ interface MultiPickerMaterialDialogStatic extends Dialog {

export class MaterialDialog extends React.Component<MaterialDialogStatic> {}
export class SinglePickerMaterialDialog extends React.Component<
SinglePickerMaterialDialogStatic
SinglePickerMaterialDialogStatic
> {}
export class MultiPickerMaterialDialog extends React.Component<
MultiPickerMaterialDialogStatic
export class SinglePickerMaterialDialogWithSearch extends React.Component<
SinglePickerMaterialDialogWithSearchStatic
> {}
export class MultiPickerMaterialDialog extends React.Component<MultiPickerMaterialDialogStatic> {}
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import MaterialDialog from './src/MaterialDialog';
import MultiPickerMaterialDialog from './src/MultiPickerMaterialDialog';
import SinglePickerMaterialDialog from './src/SinglePickerMaterialDialog';

import SinglePickerMaterialDialogWithSearch from './src/SinglePickerMaterialDialogWithSearch';
const Dialogs = {
MaterialDialog,
MultiPickerMaterialDialog,
SinglePickerMaterialDialog,
SinglePickerMaterialDialogWithSearch,
};

module.exports = Dialogs;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
],
"dependencies": {
"prop-types": "^15.5.10",
"lodash.filter": "^4.6.0",
"react-native-typography": "^1.0.3",
"react-native-vector-icons": "^4.2.0"
},
Expand Down
4 changes: 2 additions & 2 deletions src/MaterialDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import colors from './colors';
import { material } from 'react-native-typography';

const { height } = Dimensions.get('window');
const { height, width } = Dimensions.get('window');

// TODO: Don't rely on Dimensions for the actions footer layout
// TODO: Support custom actions
Expand Down Expand Up @@ -120,7 +120,7 @@ const styles = StyleSheet.create({
modalContainer: {
marginHorizontal: 16,
marginVertical: 106,
minWidth: 280,
minWidth: width - 80,
borderRadius: 2,
elevation: 24,
overflow: 'hidden',
Expand Down
174 changes: 174 additions & 0 deletions src/SinglePickerMaterialDialogWithSearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
StyleSheet,
Text,
TouchableOpacity,
View,
FlatList,
TextInput,
} from "react-native";
import { material } from "react-native-typography";
import Icon from "react-native-vector-icons/MaterialIcons";
import MaterialDialog from "./MaterialDialog";

import colors from "./colors";
import filter from "lodash.filter";

export default class SinglePickerMaterialDialogWithSearch extends Component {
constructor(props) {
super(props);

const { items, selectedItem } = props;

this.state = {
selectedIndex: null,
query: "",
data: items,
selectedItem,
};
}

componentDidMount() {
const { items, selectedItem } = this.props;

let selectedIndex;
if (selectedItem != null) {
selectedIndex = items.findIndex(
(item) => item.value === selectedItem.value
);
}

this.setState({ ...this.state, selectedIndex });
}

contains = (name, query) => {
if (name.includes(query)) {
return true;
}
return false;
};

handleSearch = (text) => {
const formattedQuery = text.toLowerCase();
const data = filter(this.props.items, (item) => {
return this.contains(item.label.toLowerCase(), formattedQuery);
});
this.setState({ ...this.state, data, query: text });
};

onPressItem(item) {
this.setState({
...this.state,
selectedIndex: item.value,
selectedItem: item,
});
}

keyExtractor = (item) => String(item.value);

renderItem = ({ item, index }) => (
<TouchableOpacity onPress={() => this.onPressItem(item)}>
<View style={styles.rowContainer}>
<View style={styles.iconContainer}>
<Icon
name={
item.value === this.state.selectedIndex
? "radio-button-checked"
: "radio-button-unchecked"
}
color={this.props.colorAccent}
size={24}
/>
</View>
<Text style={material.subheading}>{item.label}</Text>
</View>
</TouchableOpacity>
);

render() {
return (
<MaterialDialog
title={this.props.title}
titleColor={this.props.titleColor}
colorAccent={this.props.colorAccent}
visible={this.props.visible}
okLabel={this.props.okLabel}
scrolled={this.props.scrolled}
onOk={() =>
this.props.onOk({
selectedItem: this.state.selectedItem,
query: "",
})
}
cancelLabel={this.props.cancelLabel}
onCancel={() => {
this.props.onCancel();
}}
>
<TextInput
placeholder={this.props.placeholder || "Search:"}
value={this.state.query}
onChangeText={(text) => this.handleSearch(text)}
style={[styles.searchInput, { borderColor: this.props.colorAccent }]}
/>
<FlatList
data={this.state.data}
extraData={this.state}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
</MaterialDialog>
);
}
}

const styles = StyleSheet.create({
rowContainer: {
paddingVertical: 6,
flex: 1,
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
iconContainer: {
marginRight: 16,
},
searchInput: {
backgroundColor: "#fff",
marginBottom: 16,
borderWidth: 2,
borderRadius: 4,
paddingStart: 8,
paddingEnd: 6,
paddingVertical: 8,
fontSize: 14,
}
});

SinglePickerMaterialDialogWithSearch.propTypes = {
visible: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
selectedItem: PropTypes.shape({
value: PropTypes.any.isRequired,
label: PropTypes.string.isRequired,
}),
title: PropTypes.string,
titleColor: PropTypes.string,
colorAccent: PropTypes.string,
onCancel: PropTypes.func.isRequired,
onOk: PropTypes.func.isRequired,
cancelLabel: PropTypes.string,
okLabel: PropTypes.string,
scrolled: PropTypes.bool,
};

SinglePickerMaterialDialogWithSearch.defaultProps = {
selectedItem: undefined,
title: undefined,
titleColor: undefined,
colorAccent: colors.androidColorAccent,
cancelLabel: undefined,
okLabel: undefined,
scrolled: false,
};