Skip to content
Merged
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
47 changes: 44 additions & 3 deletions demo/src/screens/componentScreens/PickerScreen.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash';
import React, {Component} from 'react';
import {ScrollView, Image} from 'react-native';
import {View, Colors, Text, Stepper, Typography, Picker, Avatar, Assets, TagsInput} from 'react-native-ui-lib'; //eslint-disable-line
import {View, Colors, Dialog, Text, Stepper, Typography, Picker, Avatar, Assets, TagsInput} from 'react-native-ui-lib'; //eslint-disable-line
import contacts from '../../data/conversations';
import tagIcon from '../../assets/icons/tags.png';
import dropdown from '../../assets/icons/chevronDown.png';
Expand Down Expand Up @@ -29,6 +29,7 @@ export default class PickerScreen extends Component {
// language: {value: 'java', label: 'Java'},
language: undefined,
languages: [],
customModalValues: [],
filter: filters[0],
contact: contacts[0],
tags: [{label: 'Amit'}, {label: 'Ethan'}],
Expand All @@ -37,11 +38,34 @@ export default class PickerScreen extends Component {
};
}

renderDialog = modalProps => {
const {visible, toggleModal, children} = modalProps;

return (
<Dialog
visible={visible}
onDismiss={() => toggleModal(false)}
width="100%"
height="45%"
bottom
useSafeArea
style={{paddingTop: 20, backgroundColor: Colors.white}}
>
<View flex>
<Text marginL-15 text60>
Custom modal
</Text>
<ScrollView>{children}</ScrollView>
</View>
</Dialog>
);
};

render() {
return (
<ScrollView keyboardShouldPersistTaps="always">
<View flex padding-20>
<Text text40 marginB-20>
<Text text40>
Picker
</Text>
<Picker
Expand Down Expand Up @@ -97,7 +121,8 @@ export default class PickerScreen extends Component {
style: {width: 200},
color: Colors.violet30,
labelStyle: {fontSize: 32, fontFamily: 'sans-serif-condensed-light'},
itemHeight: 55}}
itemHeight: 55
}}
selectLabelStyle={{color: Colors.violet30}}
cancelLabelStyle={{color: Colors.violet30}}
>
Expand All @@ -106,6 +131,22 @@ export default class PickerScreen extends Component {
))}
</Picker>

<View marginT-20>
<Picker
title="Custom modal"
placeholder="Pick multiple Languages"
value={this.state.customModalValues}
onChange={items => this.setState({customModalValues: items})}
mode={Picker.modes.MULTI}
rightIconSource={dropdown}
renderCustomModal={this.renderDialog}
>
{_.map(options, option => (
<Picker.Item key={option.value} value={option} label={option.label} disabled={option.disabled} />
))}
</Picker>
</View>

<Text marginT-20 marginB-10 text70 dark60>
Custom Picker:
</Text>
Expand Down
69 changes: 46 additions & 23 deletions src/components/picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ import NativePicker from './NativePicker';
import PickerModal from './PickerModal';
import PickerItem from './PickerItem';


const PICKER_MODES = {
SINGLE: 'SINGLE',
MULTI: 'MULTI',
MULTI: 'MULTI'
};
const ItemType = PropTypes.shape({
value: PropTypes.any,
value: PropTypes.any,
label: PropTypes.string
});

Expand All @@ -36,7 +35,13 @@ class Picker extends BaseComponent {
/**
* Picker current value in the shape of {value: ..., label: ...}, for custom shape use 'getItemValue' prop
*/
value: PropTypes.oneOfType([ItemType, PropTypes.arrayOf(ItemType), PropTypes.object, PropTypes.string, PropTypes.number]),
value: PropTypes.oneOfType([
ItemType,
PropTypes.arrayOf(ItemType),
PropTypes.object,
PropTypes.string,
PropTypes.number
]),
/**
* Callback for when picker value change
*/
Expand All @@ -59,6 +64,10 @@ class Picker extends BaseComponent {
* Render custom picker item
*/
renderItem: PropTypes.func,
/**
* Render custom picker modal (e.g ({visible, children, toggleModal}) => {...})
*/
renderCustomModal: PropTypes.func,
/**
* Custom picker props (when using renderPicker, will apply on the button wrapper)
*/
Expand Down Expand Up @@ -129,7 +138,6 @@ class Picker extends BaseComponent {

this.state = {
value: props.value,
showModal: false,
selectedItemPosition: 0,
};

Expand All @@ -141,7 +149,7 @@ class Picker extends BaseComponent {
}

if (props.useNativePicker && _.isPlainObject(props.value)) {
console.warn('UILib Picker: dont use object as value for native picker, use either string or a number');
console.warn('UILib Picker: don\'t use object as value for native picker, use either string or a number');
}
}

Expand All @@ -153,7 +161,7 @@ class Picker extends BaseComponent {

getLabel() {
const {value} = this.state;

if (_.isArray(value)) {
return _.chain(value)
.map('label')
Expand All @@ -168,34 +176,34 @@ class Picker extends BaseComponent {
handlePickerOnPress = () => {
this.toggleExpandableModal(true);
_.invoke(this.props, 'onPress');
}
};

toggleExpandableModal = (value) => {
toggleExpandableModal = value => {
this.setState({showExpandableModal: value});
}
};

toggleItemSelection = (item) => {
toggleItemSelection = item => {
const {value} = this.state;
const newValue = _.xorBy(value, [item], 'value');
this.setState({
value: newValue,
});
}
};

cancelSelect = () => {
this.setState({
value: this.props.value,
});
this.toggleExpandableModal(false);
}
};

onDoneSelecting = (item) => {
onDoneSelecting = item => {
this.setState({searchValue: '', value: item}); // clean search when done selecting
this.toggleExpandableModal(false);
_.invoke(this.props, 'onChange', item);
}
};

onSearchChange = (searchValue) => {
onSearchChange = searchValue => {
this.setState({
searchValue,
});
Expand All @@ -213,10 +221,10 @@ class Picker extends BaseComponent {
appendPropsToChildren = () => {
const {children, mode, getItemValue, showSearch, renderItem} = this.props;
const {value, searchValue} = this.state;
const childrenWithProps = React.Children.map(children, (child) => {
const childrenWithProps = React.Children.map(children, child => {
const childValue = PickerPresenter.getItemValue({getItemValue, ...child.props});
const childLabel = PickerPresenter.getItemLabel({...child.props, getLabel: child.props.getItemLabel});

if (!showSearch || _.isEmpty(searchValue) || _.includes(_.lowerCase(childLabel), _.lowerCase(searchValue))) {
const selectedValue = PickerPresenter.getItemValue({value, getItemValue});
return React.cloneElement(child, {
Expand All @@ -230,7 +238,7 @@ class Picker extends BaseComponent {
});

return childrenWithProps;
}
};

renderExpandableModal = () => {
const {
Expand All @@ -241,8 +249,21 @@ class Picker extends BaseComponent {
searchStyle,
searchPlaceholder,
renderCustomSearch,
listProps} = this.getThemeProps();
renderCustomModal,
listProps
} = this.getThemeProps();
const {showExpandableModal, selectedItemPosition} = this.state;
const children = this.appendPropsToChildren(this.props.children);

if (renderCustomModal) {
const modalProps = {
visible: showExpandableModal,
toggleModal: this.toggleExpandableModal,
children,
};

return renderCustomModal(modalProps);
}

return (
<PickerModal
Expand All @@ -261,15 +282,17 @@ class Picker extends BaseComponent {
renderCustomSearch={renderCustomSearch}
listProps={listProps}
>
{this.appendPropsToChildren(this.props.children)}
{children}
</PickerModal>
);
}
};

render() {
const {useNativePicker, renderPicker, customPickerProps, testID} = this.props;

if (useNativePicker) return <NativePicker {...this.props}/>;
if (useNativePicker) {
return <NativePicker {...this.props} />;
}

if (_.isFunction(renderPicker)) {
const {value} = this.state;
Expand Down