diff --git a/README.md b/README.md index 7388049..37c2081 100644 --- a/README.md +++ b/README.md @@ -5,31 +5,30 @@ ![Single select](https://raw.githubusercontent.com/xuho/demo-images/master/react-native-select2-single-select.gif) ## Add it to your project - - Using NPM - `npm install react-native-select-two` - - or: - - Using Yarn - `yarn add react-native-select-two` +- Using NPM + `npm install react-native-select-two` +- or: +- Using Yarn + `yarn add react-native-select-two` ## Install dependencies 1. [react-native-modal](https://github.com/react-native-community/react-native-modal) 2. [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons) - ## Usage ```javascript -import React, { Component } from "react" -import { View, Text, StyleSheet } from "react-native" -import Select2 from "react-native-select-two" +import React, { Component } from "react"; +import { View, Text, StyleSheet } from "react-native"; +import Select2 from "react-native-select-two"; const mockData = [ { id: 1, name: "React Native Developer", checked: true }, // set default checked for render option item { id: 2, name: "Android Developer" }, - { id: 3, name: "iOS Developer" } -] + { id: 3, name: "iOS Developer" }, +]; // create a component class CreateNewAppointment extends Component { @@ -43,15 +42,15 @@ class CreateNewAppointment extends Component { popupTitle="Select item" title="Select item" data={mockData} - onSelect={data => { - this.setState({ data }) + onSelect={(data) => { + this.setState({ data }); }} - onRemoveItem={data => { - this.setState({ data }) + onRemoveItem={(data) => { + this.setState({ data }); }} /> - ) + ); } } ``` @@ -65,6 +64,8 @@ class CreateNewAppointment extends Component { | Property name | Type | Default | Description | | ------------------------- | -------------- | ------------------------------- | ------------------------------------------------------------------------------------------- | | **style** | _Object_ | none | Custom style for component | +| **tagStyle** | _Object_ | none | Custom style for tag component | +| **tagTextStyle** | _Object_ | none | Custom style for text component inside tag component | | **modalStyle** | _Object_ | none | Custom style for modal | | **title** | _String_ | none | String display when you don't select any item | | **data** | _Array_ | \*required | Datasource of list options: an array of objects (each object have `name` and `id` property) | diff --git a/index.js b/index.js index 5c94a58..c6ff223 100644 --- a/index.js +++ b/index.js @@ -1,330 +1,449 @@ //import liraries -import React, { Component } from 'react'; -import { Text, StyleSheet, TouchableOpacity, View, FlatList, TextInput, Dimensions, Animated, Platform } from 'react-native'; -import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; -import Modal from 'react-native-modal'; -import Button from './lib/Button'; -import TagItem from './lib/TagItem'; -import utilities from './lib/utilities'; -import PropTypes from 'prop-types'; +import React, { Component } from "react"; +import { + Text, + StyleSheet, + TouchableOpacity, + View, + FlatList, + TextInput, + Dimensions, + Animated, + Platform, +} from "react-native"; +import Icon from "react-native-vector-icons/MaterialCommunityIcons"; +import Modal from "react-native-modal"; +import Button from "./lib/Button"; +import TagItem from "./lib/TagItem"; +import utilities from "./lib/utilities"; +import PropTypes from "prop-types"; -const { height } = Dimensions.get('window'); +const { height } = Dimensions.get("window"); const INIT_HEIGHT = height * 0.6; // create a component class Select2 extends Component { - static defaultProps = { - cancelButtonText: 'Hủy', - selectButtonText: 'Chọn', - searchPlaceHolderText: "Nhập vào từ khóa", - listEmptyTitle: 'Không tìm thấy lựa chọn phù hợp', - colorTheme: '#16a45f', - buttonTextStyle: {}, - buttonStyle: {}, - showSearchBox: true - } - state = { - show: false, - preSelectedItem: [], - selectedItem: [], - data: [], - keyword: '' - } - animatedHeight = new Animated.Value(INIT_HEIGHT); + static defaultProps = { + cancelButtonText: "Hủy", + selectButtonText: "Chọn", + searchPlaceHolderText: "Nhập vào từ khóa", + listEmptyTitle: "Không tìm thấy lựa chọn phù hợp", + colorTheme: "#16a45f", + buttonTextStyle: {}, + buttonStyle: {}, + showSearchBox: true, + }; + state = { + show: false, + preSelectedItem: [], + selectedItem: [], + data: [], + keyword: "", + }; + animatedHeight = new Animated.Value(INIT_HEIGHT); - componentDidMount() { - this.init(); - }; + componentDidMount() { + this.init(); + } - UNSAFE_componentWillReceiveProps(newProps) { - this.init(newProps); - } + UNSAFE_componentWillReceiveProps(newProps) { + this.init(newProps); + } - init(newProps) { - let preSelectedItem = []; - let { data } = newProps || this.props; - data.map(item => { - if (item.checked) { - preSelectedItem.push(item); - } - }) - this.setState({ data, preSelectedItem }); - } + init(newProps) { + let preSelectedItem = []; + let { data } = newProps || this.props; + data.map((item) => { + if (item.checked) { + preSelectedItem.push(item); + } + }); + this.setState({ data, preSelectedItem }); + } - get dataRender() { - let { data, keyword } = this.state; - let listMappingKeyword = []; - data.map(item => { - if (utilities.changeAlias(item.name).includes(utilities.changeAlias(keyword))) { - listMappingKeyword.push(item); - } - }); - return listMappingKeyword; - } + get dataRender() { + let { data, keyword } = this.state; + let listMappingKeyword = []; + data.map((item) => { + if ( + utilities + .changeAlias(item.name) + .includes(utilities.changeAlias(keyword)) + ) { + listMappingKeyword.push(item); + } + }); + return listMappingKeyword; + } - get defaultFont() { - let { defaultFontName } = this.props; - return defaultFontName ? { fontFamily: defaultFontName } : {}; - } + get defaultFont() { + let { defaultFontName } = this.props; + return defaultFontName ? { fontFamily: defaultFontName } : {}; + } - cancelSelection() { - let { data, preSelectedItem } = this.state; - data.map(item => { - item.checked = false; - for (let _selectedItem of preSelectedItem) { - if (item.id === _selectedItem.id) { - item.checked = true; - break; - } - } - }); - this.setState({ data, show: false, keyword: '', selectedItem: preSelectedItem }); - } - - onItemSelected = (item, isSelectSingle) => { - let selectedItem = []; - let { data } = this.state; - item.checked = !item.checked; - for (let index in data) { - if (data[index].id === item.id) { - data[index] = item; - } else if (isSelectSingle) { - data[index].checked = false; - } + cancelSelection() { + let { data, preSelectedItem } = this.state; + data.map((item) => { + item.checked = false; + for (let _selectedItem of preSelectedItem) { + if (item.id === _selectedItem.id) { + item.checked = true; + break; } - data.map(item => { - if (item.checked) selectedItem.push(item); - }) - this.setState({ data, selectedItem }); - } - keyExtractor = (item, idx) => idx.toString(); - renderItem = ({ item, idx }) => { - let { colorTheme, isSelectSingle } = this.props; - return ( - this.onItemSelected(item, isSelectSingle)} - activeOpacity={0.7} - style={styles.itemWrapper}> - - {item.name} - - - - ); - } - renderEmpty = () => { - let { listEmptyTitle } = this.props; - return ( - - {listEmptyTitle} - - ); + } + }); + this.setState({ + data, + show: false, + keyword: "", + selectedItem: preSelectedItem, + }); + } + + onItemSelected = (item, isSelectSingle) => { + let selectedItem = []; + let { data } = this.state; + item.checked = !item.checked; + for (let index in data) { + if (data[index].id === item.id) { + data[index] = item; + } else if (isSelectSingle) { + data[index].checked = false; + } } - closeModal = () => this.setState({ show: false }); - showModal = () => this.setState({ show: true }); + data.map((item) => { + if (item.checked) selectedItem.push(item); + }); + this.setState({ data, selectedItem }); + }; + keyExtractor = (item, idx) => idx.toString(); + renderItem = ({ item, idx }) => { + let { colorTheme, isSelectSingle } = this.props; + return ( + this.onItemSelected(item, isSelectSingle)} + activeOpacity={0.7} + style={styles.itemWrapper} + > + {item.name} + + + ); + }; + renderEmpty = () => { + let { listEmptyTitle } = this.props; + return ( + {listEmptyTitle} + ); + }; + closeModal = () => this.setState({ show: false }); + showModal = () => this.setState({ show: true }); - render() { - let { - style, modalStyle, title, onSelect, onRemoveItem, popupTitle, colorTheme, - isSelectSingle, cancelButtonText, selectButtonText, searchPlaceHolderText, - selectedTitleStyle, buttonTextStyle, buttonStyle, showSearchBox - } = this.props; - let { show, selectedItem, preSelectedItem } = this.state; - return ( - - - - - - {popupTitle || title} - - - - { - showSearchBox - ? this.setState({ keyword })} - onFocus={() => { - Animated.spring(this.animatedHeight, { - toValue: INIT_HEIGHT + (Platform.OS === 'ios' ? height * 0.2 : 0), - friction: 7 - }).start(); - }} - onBlur={() => { - Animated.spring(this.animatedHeight, { - toValue: INIT_HEIGHT, - friction: 7 - }).start(); - }} - /> - : null - } - + render() { + let { + style, + modalStyle, + title, + onSelect, + onRemoveItem, + popupTitle, + colorTheme, + isSelectSingle, + cancelButtonText, + selectButtonText, + searchPlaceHolderText, + selectedTitleStyle, + buttonTextStyle, + buttonStyle, + showSearchBox, + tagStyle, + tagTextStyle, + } = this.props; + let { show, selectedItem, preSelectedItem } = this.state; + return ( + + + + + + {popupTitle || title} + + + + {showSearchBox ? ( + this.setState({ keyword })} + onFocus={() => { + Animated.spring(this.animatedHeight, { + toValue: + INIT_HEIGHT + (Platform.OS === "ios" ? height * 0.2 : 0), + friction: 7, + }).start(); + }} + onBlur={() => { + Animated.spring(this.animatedHeight, { + toValue: INIT_HEIGHT, + friction: 7, + }).start(); + }} + /> + ) : null} + - -