Skip to content

Commit

Permalink
Add support for custom components in options list (#98).
Browse files Browse the repository at this point in the history
Supported for both sections and options.
Update Readme and SampleApp.
  • Loading branch information
peacechen committed Jan 15, 2019
1 parent 7663625 commit 9439ce5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,22 @@ class SampleApp extends Component {

## Data Format

The selector accept a specific format of data:
The selector accepts a specific format of data:
```javascript
[{ key: 5, label: 'Red Apples' }]
```

Optionally provide a `component` key which overrides the default label text:
```javascript
[{
key: 5,
label: 'Red Apples',
component: <View style={{backgroundColor: 'red'}}><Text style={{color: 'white'}}>Red Apples custom component ☺</Text></View>
}]
```

<img src="https://user-images.githubusercontent.com/6295083/51210593-d3fbae00-18d8-11e9-8f51-d1ca4f9f8267.png" />

If your data has a specific format, you can define extractors of data, example:
```javascript
this.setState({data: [{ id: 5, name: 'Red Apples' }]});
Expand All @@ -110,14 +121,15 @@ return (
### Props
Prop | Type | Optional | Default | Description
------------------- | -------- | -------- | ------------ | -----------
`data` | array | No | [] | array of objects with a unique key and label to select in the modal.
`data` | array | No | [] | array of objects with a unique `key` and `label` to select in the modal. Optional `component` overrides label text.
`onChange` | function | Yes | () => {} | callback function, when the users has selected an option
`onModalOpen` | function | Yes | () => {} | callback function, when modal is opening
`onModalClose` | function | Yes | () => {} | callback function, when modal is closing
`keyExtractor`      | function | Yes     | (data) => data.key   | extract the key from the data item
`labelExtractor`    | function | Yes     | (data) => data.label | extract the label from the data item
`componentExtractor`| function | Yes     | (data) => data.component | extract the component from the data item
`visible` | bool | Yes | false | control open/close state of modal
`closeOnChange`´ | bool | Yes | true | control if modal closes on select
`closeOnChange` | bool | Yes | true | control if modal closes on select
`initValue` | string | Yes | `Select me!` | text that is initially shown on the button
`cancelText` | string | Yes | `cancel` | text of the cancel button
`animationType` | string | Yes | `slide` | type of animation to be used to show the modal. Must be one of `none`, `slide` or `fade`.
Expand Down
3 changes: 2 additions & 1 deletion SampleApp/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { Component } from 'react';

import {
View,
Text,
TextInput,
Switch
} from 'react-native';
Expand All @@ -24,7 +25,7 @@ class SampleApp extends Component {
let index = 0;
const data = [
{ key: index++, section: true, label: 'Fruits' },
{ key: index++, label: 'Red Apples' },
{ key: index++, label: 'Red Apples', component: <View style={{backgroundColor: 'red', borderRadius: 5, alignItems: 'center'}}><Text style={{color: 'white'}}>Red Apples custom component ☺</Text></View> },
{ key: index++, label: 'Cherries' },
{ key: index++, label: 'Cranberries' },
{ key: index++, label: 'Pink Grapefruit' },
Expand Down
22 changes: 16 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const defaultProps = {
onModalClose: () => {},
keyExtractor: (item) => item.key,
labelExtractor: (item) => item.label,
componentExtractor: (item) => item.component,
visible: false,
closeOnChange: true,
initValue: 'Select me!',
Expand Down Expand Up @@ -170,17 +171,29 @@ export default class ModalSelector extends React.Component {
}

renderSection = (section) => {
const optionComponent = this.props.componentExtractor(section);
let component = optionComponent || (
<Text style={[styles.sectionTextStyle,this.props.sectionTextStyle]}>{this.props.labelExtractor(section)}</Text>
);

return (
<View key={this.props.keyExtractor(section)} style={[styles.sectionStyle,this.props.sectionStyle]}>
<Text style={[styles.sectionTextStyle,this.props.sectionTextStyle]}>{this.props.labelExtractor(section)}</Text>
{component}
</View>
);
}

renderOption = (option, isLastItem, isFirstItem) => {
const optionComponent = this.props.componentExtractor(option);
const optionLabel = this.props.labelExtractor(option);
const isSelectedItem = optionLabel === this.state.selected;

let component = optionComponent || (
<Text style={[styles.optionTextStyle,this.props.optionTextStyle,isSelectedItem && this.props.selectedItemTextStyle]} {...this.props.optionTextPassThruProps}>
{optionLabel}
</Text>
);

return (
<TouchableOpacity
key={this.props.keyExtractor(option)}
Expand All @@ -191,11 +204,8 @@ export default class ModalSelector extends React.Component {
importantForAccessibility={isFirstItem}
{...this.props.passThruProps}
>
<View style={[styles.optionStyle, this.props.optionStyle, isLastItem &&
{borderBottomWidth: 0}]}>
<Text style={[styles.optionTextStyle,this.props.optionTextStyle,isSelectedItem && this.props.selectedItemTextStyle]} {...this.props.optionTextPassThruProps}>
{optionLabel}
</Text>
<View style={[styles.optionStyle, this.props.optionStyle, isLastItem && {borderBottomWidth: 0}]}>
{component}
</View>
</TouchableOpacity>);
}
Expand Down

0 comments on commit 9439ce5

Please sign in to comment.