├── Example ├── android.js ├── example.js └── images │ ├── about.png │ ├── airplane.png │ ├── apps.png │ ├── battery.png │ ├── blutooth.png │ ├── cellular.png │ ├── control.png │ ├── data.png │ ├── display.png │ ├── display2.png │ ├── dnd.png │ ├── general.png │ ├── hotspot.png │ ├── memory.png │ ├── more.png │ ├── notifications.png │ ├── sound.png │ ├── storage.png │ ├── user.png │ └── wifi.png ├── LICENSE ├── README.md ├── documentation ├── android.png ├── auth.gif ├── editable.png ├── realistic.png └── simple.png ├── img ├── icon-arrow-settings.png ├── icon-arrow-settings@2x.png └── icon-arrow-settings@3x.png ├── index.js └── package.json /Example/android.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import React, { 3 | AppRegistry, 4 | Component, 5 | StyleSheet, 6 | Text, 7 | View, 8 | Image 9 | } from 'react-native'; 10 | 11 | import SettingsList from 'react-native-settings-list'; 12 | 13 | 14 | class SettingsListExample extends Component { 15 | constructor(){ 16 | super(); 17 | } 18 | render() { 19 | return ( 20 | 21 | 22 | Settings 23 | 24 | 25 | 26 | 33 | 36 | 37 | 38 | } 39 | hasNavArrow={false} 40 | itemWidth={70} 41 | titleStyle={{color:'black', fontSize: 16}} 42 | title='Data usage' 43 | /> 44 | 47 | 48 | 49 | } 50 | title='More' 51 | itemWidth={70} 52 | titleStyle={{color:'black', fontSize: 16}} 53 | hasNavArrow={false} 54 | /> 55 | 56 | 63 | 66 | 67 | 68 | } 69 | title='Display' 70 | itemWidth={70} 71 | titleStyle={{color:'black', fontSize: 16}} 72 | hasNavArrow={false} 73 | /> 74 | 77 | 78 | 79 | } 80 | title='Sound & notification' 81 | itemWidth={70} 82 | titleStyle={{color:'black', fontSize: 16}} 83 | hasNavArrow={false} 84 | /> 85 | 88 | 89 | 90 | } 91 | title='Apps' 92 | itemWidth={70} 93 | titleStyle={{color:'black', fontSize: 16}} 94 | hasNavArrow={false} 95 | /> 96 | 99 | 100 | 101 | } 102 | title='Storage & USB' 103 | itemWidth={70} 104 | titleStyle={{color:'black', fontSize: 16}} 105 | hasNavArrow={false} 106 | /> 107 | 110 | 111 | 112 | } 113 | title='Battery' 114 | itemWidth={70} 115 | titleStyle={{color:'black', fontSize: 16}} 116 | hasNavArrow={false} 117 | /> 118 | 121 | 122 | 123 | } 124 | title='Memory' 125 | itemWidth={70} 126 | titleStyle={{color:'black', fontSize: 16}} 127 | hasNavArrow={false} 128 | /> 129 | 130 | 131 | 132 | 133 | ); 134 | } 135 | } 136 | 137 | const styles = StyleSheet.create({ 138 | imageStyle:{ 139 | marginLeft:15, 140 | marginRight:20, 141 | alignSelf:'center', 142 | width:20, 143 | height:24, 144 | justifyContent:'center' 145 | } 146 | }); 147 | 148 | AppRegistry.registerComponent('SettingsListExample', () => SettingsListExample); 149 | -------------------------------------------------------------------------------- /Example/example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import React from 'react'; 3 | 4 | import { 5 | AppRegistry, 6 | Component, 7 | StyleSheet, 8 | Text, 9 | View, 10 | Image, 11 | Alert 12 | } from 'react-native'; 13 | import SettingsList from 'react-native-settings-list'; 14 | 15 | /* 16 | // simple example 17 | class SettingsListExample extends Component { 18 | constructor(){ 19 | super(); 20 | this.onValueChange = this.onValueChange.bind(this); 21 | this.state = {switchValue: false, stages: 20}; 22 | } 23 | 24 | render() { 25 | return ( 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | } 36 | itemWidth={50} 37 | title='Icon Example' 38 | onPress={() => Alert.alert('Icon Example Pressed')} 39 | /> 40 | 46 | Alert.alert('Different Colors Example Pressed')}/> 52 | 53 | 54 | 55 | 56 | this.setState({stages: text})} 62 | /> 63 | 64 | 65 | 66 | ); 67 | } 68 | 69 | onValueChange(value){ 70 | this.setState({switchValue: value}); 71 | } 72 | } 73 | */ 74 | 75 | /** 76 | * realistic iPhone example 77 | */ 78 | class SettingsListExample extends Component { 79 | constructor(){ 80 | super(); 81 | this.onValueChange = this.onValueChange.bind(this); 82 | this.state = {switchValue: false, loggedIn: false}; 83 | } 84 | render() { 85 | var bgColor = '#DCE3F4'; 86 | return ( 87 | 88 | 89 | Settings 90 | 91 | 92 | 93 | 94 | {this.state.toggleAuthView ? 95 | 98 | } 99 | title='Logged In As...' 100 | hasNavArrow={false} 101 | /> 102 | : 103 | 106 | } 107 | isAuth={true} 108 | authPropsUser={{placeholder:'E-mail'}} 109 | authPropsPW={{placeholder:'Password'}} 110 | onPress={() => this.toggleAuthView()} 111 | /> 112 | } 113 | 114 | 117 | } 118 | hasSwitch={true} 119 | switchState={this.state.switchValue} 120 | switchOnValueChange={this.onValueChange} 121 | hasNavArrow={false} 122 | title='Airplane Mode' 123 | /> 124 | } 126 | title='Wi-Fi' 127 | titleInfo='Bill Wi The Science Fi' 128 | titleInfoStyle={styles.titleInfoStyle} 129 | onPress={() => Alert.alert('Route to Wifi Page')} 130 | /> 131 | } 133 | title='Blutooth' 134 | titleInfo='Off' 135 | titleInfoStyle={styles.titleInfoStyle} 136 | onPress={() => Alert.alert('Route to Blutooth Page')} 137 | /> 138 | } 140 | title='Cellular' 141 | onPress={() => Alert.alert('Route To Cellular Page')} 142 | /> 143 | } 145 | title='Personal Hotspot' 146 | titleInfo='Off' 147 | titleInfoStyle={styles.titleInfoStyle} 148 | onPress={() => Alert.alert('Route To Hotspot Page')} 149 | /> 150 | 151 | } 153 | title='Notifications' 154 | onPress={() => Alert.alert('Route To Notifications Page')} 155 | /> 156 | } 158 | title='Control Center' 159 | onPress={() => Alert.alert('Route To Control Center Page')} 160 | /> 161 | } 163 | title='Do Not Disturb' 164 | onPress={() => Alert.alert('Route To Do Not Disturb Page')} 165 | /> 166 | 167 | } 169 | title='General' 170 | onPress={() => Alert.alert('Route To General Page')} 171 | /> 172 | } 174 | title='Display & Brightness' 175 | onPress={() => Alert.alert('Route To Display Page')} 176 | /> 177 | 178 | 179 | 180 | ); 181 | } 182 | toggleAuthView() { 183 | this.setState({toggleAuthView: !this.state.toggleAuthView}); 184 | } 185 | onValueChange(value){ 186 | this.setState({switchValue: value}); 187 | } 188 | } 189 | 190 | const styles = StyleSheet.create({ 191 | imageStyle:{ 192 | marginLeft:15, 193 | alignSelf:'center', 194 | height:30, 195 | width:30 196 | }, 197 | titleInfoStyle:{ 198 | fontSize:16, 199 | color: '#8e8e93' 200 | } 201 | }); 202 | 203 | module.exports = SettingsListExample; 204 | -------------------------------------------------------------------------------- /Example/images/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/about.png -------------------------------------------------------------------------------- /Example/images/airplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/airplane.png -------------------------------------------------------------------------------- /Example/images/apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/apps.png -------------------------------------------------------------------------------- /Example/images/battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/battery.png -------------------------------------------------------------------------------- /Example/images/blutooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/blutooth.png -------------------------------------------------------------------------------- /Example/images/cellular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/cellular.png -------------------------------------------------------------------------------- /Example/images/control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/control.png -------------------------------------------------------------------------------- /Example/images/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/data.png -------------------------------------------------------------------------------- /Example/images/display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/display.png -------------------------------------------------------------------------------- /Example/images/display2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/display2.png -------------------------------------------------------------------------------- /Example/images/dnd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/dnd.png -------------------------------------------------------------------------------- /Example/images/general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/general.png -------------------------------------------------------------------------------- /Example/images/hotspot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/hotspot.png -------------------------------------------------------------------------------- /Example/images/memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/memory.png -------------------------------------------------------------------------------- /Example/images/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/more.png -------------------------------------------------------------------------------- /Example/images/notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/notifications.png -------------------------------------------------------------------------------- /Example/images/sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/sound.png -------------------------------------------------------------------------------- /Example/images/storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/storage.png -------------------------------------------------------------------------------- /Example/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/user.png -------------------------------------------------------------------------------- /Example/images/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/Example/images/wifi.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-settings-list 2 | --- 3 | A clean and highly customizable React Native implementation of a list of settings for a settings page. 4 | 5 | [![NPM Version](https://img.shields.io/npm/v/react-native-settings-list.svg?style=flat)](https://www.npmjs.com/package/react-native-settings-list) 6 | [![NPM Downloads](https://img.shields.io/npm/dm/react-native-settings-list.svg?style=flat)](https://www.npmjs.com/package/react-native-settings-list) 7 | 8 | ## Quick Access 9 | * Installation 10 | * Usage 11 | * New changes/additions 12 | * Contributing 13 | * Prop values 14 | * \ 15 | * \ 16 | * \ 17 | * Simple Example 18 | * Realistic Example 19 | 20 | 21 | ## Installation 22 | --- 23 | Install the module with: 24 | 25 | 26 | ``` 27 | npm install react-native-settings-list --save 28 | ``` 29 | ## Usage 30 | --- 31 | In your code, simply require/import the module: 32 | 33 | 34 | ``` 35 | import SettingsList from 'react-native-settings-list'; 36 | ``` 37 | 38 | ###### Top 39 | 40 | ## New changes/additions 41 | * Ability for an authorization-type component [example updated to show a practical use] 42 | * Allows for complete customization of the TextInput by passing into the two props authPropsUser and authPassPW (overwrites defaults 43 | * Uses existing onPress prop for callback 44 | * Preview: 45 | * 46 | * Ability for custom arrow image/component 47 | * Simply use the new arrowIcon prop to inject any type of object as the new arrow (with proper style formatting) 48 | * Added defaultTitleStyle prop to \ to set the style of the tiles for all children removing the need for duplicate code 49 | 50 | ###### Top 51 | 52 | ## Contributing 53 | Feel free to do pull requests if a certain feature you want is missing. I accept all PR's that are enhancements to the project. 54 | 55 | ###### Top 56 | 57 | ## Prop values 58 | --- 59 | ### \ 60 | The following props are used: 61 | 62 | | Name | Description | Type | 63 | |-------------------|------------------------------------------------|------------------------| 64 | | backgroundColor | Sets default background color for all children | React.PropTypes.string | 65 | | borderColor | Sets default border color for all children | React.PropTypes.string | 66 | | defaultItemSize | Sets default width for all children | React.PropTypes.number | 67 | | underlayColor | Sets default underlayColor for all children | React.PropTypes.string | 68 | | defaultTitleStyle | Sets default style for all children's titles | React.PropTypes.string | 69 | 70 | ### \ 71 | The following props are used: 72 | 73 | | Name | Description | Type | 74 | |-------------|-----------------------------------------|------------------------| 75 | | headerText | Text for the header | React.PropTypes.string | 76 | | headerStyle | Sets border color for the settings list | Text.propTypes.style | 77 | | headerRef | Sets a `ref` on the header component | React.PropTypes.func | 78 | 79 | ### \ 80 | The following props are used: 81 | 82 | | Name | Description | Type | 83 | |---------------------|----------------------------------------------------------------------------------------------------------|------------------------| 84 | | title | Text for the item | React.PropTypes.string | 85 | | titleStyle | Text Style | Text.propTypes.style | 86 | | icon | A component for the icon. Doesn't need to be an image | React.PropTypes.node | 87 | | itemWidth | Changes the individual item's width. Overwrites **\** defaultItemSize | React.PropTypes.number | 88 | | backgroundColor | Changes the individual item's background color. Overwrites default **\** backgroundColor | React.PropTypes.string | 89 | | underlayColor | Changes the individual item's underlayColor color. Overwrites default **\** underlayColor | React.PropTypes.string | 90 | | onPress | On press Callback for item [used for auth callback as well] | React.PropTypes.func | 91 | | hasNavArrow | Displays a navigation arrow | React.PropTypes.bool | 92 | | arrowStyle | Style for the navigation arrow | Image.propTypes.style | 93 | | arrowIcon | Inject custom arrow into the end of the item | React.PropTypes.node | 94 | | hasSwitch | Enable a switch component | React.PropTypes.bool | 95 | | switchProps | RN switch props | React.PropTypes.object | 96 | | switchOnValueChange | On switches value change callback | React.PropTypes.func | 97 | | titleInfo | Right side title information string | React.PropTypes.string | 98 | | titleInfoStyle | Style for title information string | Text.propTypes.style | 99 | | isAuth | Sets item as an authorization item | React.PropTypes.bool | 100 | | authPropsUser | Changes the props for the first TextInput component; overwrites default | React.PropTypes.node | 101 | | authPropsPW | Changes the props for the second TextInput component; overwrites default | React.PropTypes.node | 102 | | itemRef | Sets a `ref` on the TouchableHighlight that SettingsList.Item renders to | React.PropTypes.func | 103 | 104 | ###### Top 105 | 106 | 107 | ## Simple Example 108 | --- 109 | Here is a simple example of the different things you can do with the module: 110 | 111 | 112 | 113 | The code behind it: 114 | 115 | ``` 116 | constructor(){ 117 | super(); 118 | this.onValueChange = this.onValueChange.bind(this); 119 | this.state = {switchValue: false}; 120 | } 121 | 122 | render() { 123 | return ( 124 | 125 | 126 | 127 | 128 | 131 | 132 | 133 | } 134 | itemWidth={50} 135 | title='Icon Example' 136 | onPress={() => Alert.alert('Icon Example Pressed')} 137 | /> 138 | 144 | Alert.alert('Different Colors Example Pressed')}/> 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | ); 158 | } 159 | 160 | onValueChange(value){ 161 | this.setState({switchValue: value}); 162 | } 163 | ``` 164 | 165 | ###### Top 166 | 167 | ## A more realistic example 168 | 169 | --- 170 | Here is an example that looks very very close to the default iPhone settings page. 171 | 172 | 173 | 174 | 175 | The code behind this is: 176 | 177 | 178 | ``` 179 | constructor(){ 180 | super(); 181 | this.onValueChange = this.onValueChange.bind(this); 182 | this.state = {switchValue: false}; 183 | } 184 | render() { 185 | var bgColor = '#DCE3F4'; 186 | return ( 187 | 188 | 189 | Settings 190 | 191 | 192 | 193 | 194 | 197 | } 198 | hasSwitch={true} 199 | switchState={this.state.switchValue} 200 | switchOnValueChange={this.onValueChange} 201 | hasNavArrow={false} 202 | title='Airplane Mode' 203 | /> 204 | } 206 | title='Wi-Fi' 207 | titleInfo='Bill Wi The Science Fi' 208 | titleInfoStyle={styles.titleInfoStyle} 209 | onPress={() => Alert.alert('Route to Wifi Page')} 210 | /> 211 | } 213 | title='Blutooth' 214 | titleInfo='Off' 215 | titleInfoStyle={styles.titleInfoStyle} 216 | onPress={() => Alert.alert('Route to Blutooth Page')} 217 | /> 218 | } 220 | title='Cellular' 221 | onPress={() => Alert.alert('Route To Cellular Page')} 222 | /> 223 | } 225 | title='Personal Hotspot' 226 | titleInfo='Off' 227 | titleInfoStyle={styles.titleInfoStyle} 228 | onPress={() => Alert.alert('Route To Hotspot Page')} 229 | /> 230 | 231 | } 233 | title='Notifications' 234 | onPress={() => Alert.alert('Route To Notifications Page')} 235 | /> 236 | } 238 | title='Control Center' 239 | onPress={() => Alert.alert('Route To Control Center Page')} 240 | /> 241 | } 243 | title='Do Not Disturb' 244 | onPress={() => Alert.alert('Route To Do Not Disturb Page')} 245 | /> 246 | 247 | } 249 | title='General' 250 | onPress={() => Alert.alert('Route To General Page')} 251 | /> 252 | } 254 | title='Display & Brightness' 255 | onPress={() => Alert.alert('Route To Display Page')} 256 | /> 257 | 258 | 259 | 260 | ); 261 | } 262 | onValueChange(value){ 263 | this.setState({switchValue: value}); 264 | } 265 | ``` 266 | Here is an example of the android page: 267 | 268 | 269 | 270 | The code can be found here 271 | ###### Top 272 | -------------------------------------------------------------------------------- /documentation/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/documentation/android.png -------------------------------------------------------------------------------- /documentation/auth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/documentation/auth.gif -------------------------------------------------------------------------------- /documentation/editable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/documentation/editable.png -------------------------------------------------------------------------------- /documentation/realistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/documentation/realistic.png -------------------------------------------------------------------------------- /documentation/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/documentation/simple.png -------------------------------------------------------------------------------- /img/icon-arrow-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/img/icon-arrow-settings.png -------------------------------------------------------------------------------- /img/icon-arrow-settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/img/icon-arrow-settings@2x.png -------------------------------------------------------------------------------- /img/icon-arrow-settings@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evetstech/react-native-settings-list/8592e47cc31ac0c1eb33be54a24032a631786116/img/icon-arrow-settings@3x.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import React from 'react'; 4 | import PropTypes from 'prop-types'; 5 | import createReactClass from 'create-react-class'; 6 | 7 | import { 8 | View, 9 | TouchableHighlight, 10 | Text, 11 | StyleSheet, 12 | ScrollView, 13 | TextInput, 14 | Switch, 15 | Image, 16 | ViewPropTypes 17 | } from 'react-native'; 18 | 19 | const ARROW_ICON = require('./img/icon-arrow-settings.png'); 20 | 21 | class SettingsList extends React.Component { 22 | static propTypes = { 23 | backgroundColor: PropTypes.string, 24 | borderColor: PropTypes.string, 25 | defaultItemSize: PropTypes.number, 26 | underlayColor: PropTypes.string, 27 | defaultTitleStyle: Text.propTypes.style, 28 | defaultTitleInfoPosition: PropTypes.string, 29 | scrollViewProps: PropTypes.object, 30 | }; 31 | 32 | static defaultProps ={ 33 | backgroundColor: 'white', 34 | borderColor: 'black', 35 | defaultItemSize: 50, 36 | underlayColor: 'transparent', 37 | defaultTitleStyle: {fontSize: 16} 38 | }; 39 | 40 | _getGroups(){ 41 | var groupNumber = -1; 42 | let headers = []; 43 | let itemGroup = []; 44 | let result = []; 45 | React.Children.forEach(this.props.children, (child) => { 46 | // Allow for null, optional fields 47 | if(!child) return; 48 | 49 | if(child.type.displayName === 'Header'){ 50 | if(groupNumber != -1){ 51 | result[groupNumber] = {items: itemGroup, header: headers[groupNumber] }; 52 | itemGroup = []; 53 | } 54 | groupNumber++; 55 | headers[groupNumber] = child.props; 56 | } else if(child.type.displayName === 'Item'){ 57 | if(groupNumber == -1){ 58 | groupNumber++; 59 | } 60 | itemGroup.push(child.props); 61 | } else { 62 | if(groupNumber == -1){ 63 | groupNumber++; 64 | } 65 | itemGroup.push(child); 66 | } 67 | }); 68 | result[groupNumber] = {items: itemGroup, header: headers[groupNumber] }; 69 | return result; 70 | } 71 | 72 | render(){ 73 | return ( 74 | 75 | {this._getGroups().map((group, index) => { 76 | return this._groupView(group, index); 77 | })} 78 | 79 | ) 80 | } 81 | 82 | _groupView(group, index){ 83 | if(group.header){ 84 | return ( 85 | 86 | {group.header.headerText} 87 | 88 | {group.items.map((item, index) => { 89 | return this._itemView(item,index, group.items.length); 90 | })} 91 | 92 | 93 | ) 94 | } else { 95 | let items; 96 | if (group.items.length > 0) { 97 | items = ( 98 | 99 | {group.items.map((item, index) => { 100 | return this._itemView(item,index, group.items.length); 101 | })} 102 | 103 | ); 104 | } 105 | 106 | return ( 107 | 108 | {items} 109 | 110 | ) 111 | } 112 | } 113 | 114 | _itemEditableBlock(item, index, position) { 115 | 116 | return ([ 117 | 123 | {item.title} 124 | , 125 | item.isEditable ? 126 | item.onTextChange(text)} 131 | value={item.value} /> 132 | : null 133 | ]) 134 | } 135 | 136 | _itemTitleBlock(item, index, position) { 137 | return ([ 138 | 144 | {item.title} 145 | , 146 | item.titleInfo ? 147 | 156 | {item.titleInfo} 157 | 158 | : null 159 | ]) 160 | } 161 | 162 | _itemView(item, index, max){ 163 | var border; 164 | 165 | if (item.type && item.type.displayName) { 166 | return item; 167 | } 168 | 169 | if(item.borderHide) { 170 | switch(item.borderHide) { 171 | case 'Top' : border = {borderBottomWidth:1, borderColor: this.props.borderColor}; break; 172 | case 'Bottom' : border = {borderTopWidth:1, borderColor: this.props.borderColor}; break; 173 | } 174 | } else { 175 | border = index === max-1 ? {borderWidth:0} : {borderBottomWidth:1, borderColor: this.props.borderColor}; 176 | } 177 | 178 | let titleInfoPosition = item.titleInfoPosition ? item.titleInfoPosition : this.props.defaultTitleInfoPosition; 179 | 180 | return ( 181 | 182 | 183 | {item.icon} 184 | {item.isAuth ? 185 | 186 | 187 | 188 | this.refs.PasswordInputBlock.focus()} 191 | style={{flex:1,height:30, borderBottomWidth:1}} 192 | placeholder = "username" 193 | {...item.authPropsUser} 194 | /> 195 | 196 | 197 | item.onPress()} 205 | /> 206 | 207 | 208 | 209 | : 210 | 211 | {titleInfoPosition === 'Bottom' ? 212 | 213 | {item.isEditable ? this._itemEditableBlock(item, inde, 'Bottom') : this._itemTitleBlock(item, index, 'Bottom')} 214 | 215 | : item.isEditable ? this._itemEditableBlock(item, index) : this._itemTitleBlock(item, index)} 216 | 217 | {item.rightSideContent ? item.rightSideContent : null} 218 | {item.hasSwitch ? 219 | item.switchOnValueChange(value)} 223 | value={item.switchState}/> 224 | : null} 225 | {this.itemArrowIcon(item)} 226 | 227 | } 228 | 229 | 230 | ) 231 | } 232 | 233 | itemArrowIcon(item) { 234 | if(item.arrowIcon) { 235 | return item.arrowIcon; 236 | } 237 | 238 | if(item.hasNavArrow){ 239 | return ; 240 | } 241 | 242 | return null; 243 | } 244 | } 245 | module.exports = SettingsList; 246 | 247 | const styles = StyleSheet.create({ 248 | itemBox: { 249 | flex:1, 250 | justifyContent:'center', 251 | flexDirection:'row' 252 | }, 253 | titleBox: { 254 | flex:1, 255 | marginLeft:15, 256 | flexDirection:'row' 257 | }, 258 | titleText: { 259 | flex:1, 260 | alignSelf:'center' 261 | }, 262 | rightSide: { 263 | marginRight:15, 264 | alignSelf:'center' 265 | }, 266 | editableText: { 267 | flex: 1, 268 | textAlign: 'right', 269 | marginRight: 15 270 | } 271 | }); 272 | 273 | /** 274 | * Optional Header for groups 275 | */ 276 | SettingsList.Header = createReactClass({ 277 | propTypes: { 278 | headerText: PropTypes.string, 279 | headerStyle: Text.propTypes.style, 280 | headerRef: PropTypes.func, 281 | headerNumberOfLines: PropTypes.number, 282 | }, 283 | getDefaultProps() { 284 | return { 285 | headerNumberOfLines: 1, 286 | }; 287 | }, 288 | /** 289 | * not directly rendered 290 | */ 291 | render(){ 292 | return null; 293 | } 294 | }); 295 | 296 | /** 297 | * Individual Items in the Settings List 298 | */ 299 | SettingsList.Item = createReactClass({ 300 | propTypes: { 301 | /** 302 | * Title being displayed 303 | */ 304 | title: PropTypes.string, 305 | titleStyle: Text.propTypes.style, 306 | /** 307 | * Icon displayed on the left of the settings item 308 | */ 309 | icon: PropTypes.node, 310 | 311 | /** 312 | * Item Box Style 313 | */ 314 | itemBoxStyle : ViewPropTypes.style, 315 | /** 316 | * Title Box Style 317 | */ 318 | titleBoxStyle: ViewPropTypes.style, 319 | /** 320 | * Right Side Style 321 | */ 322 | rightSideStyle: ViewPropTypes.style, 323 | /** 324 | * Editable Right Side Style 325 | */ 326 | editableTextStyle: Text.propTypes.style, 327 | 328 | /** 329 | * Individual item width. Can be globally set in the parent. Will become deprecated 330 | */ 331 | itemWidth: PropTypes.number, 332 | /** 333 | * Allows for the item to become an auth item 334 | */ 335 | isAuth: PropTypes.bool, 336 | authPropsUser: PropTypes.object, 337 | authPropsPW: PropTypes.object, 338 | /** 339 | * Individual background color. Can be globally set in the parent. Will become Deprecated 340 | */ 341 | backgroundColor: PropTypes.string, 342 | 343 | /** 344 | * Individual underlay click color. Can be globally set in the parent. 345 | */ 346 | underlayColor: PropTypes.string, 347 | /** 348 | * Item on press callback. 349 | */ 350 | onPress: PropTypes.func, 351 | /** 352 | * Item on long press callback. 353 | */ 354 | onLongPress: PropTypes.func, 355 | /** 356 | * Enable or disable the > arrow at the end of the setting item. 357 | */ 358 | hasNavArrow: PropTypes.bool, 359 | arrowIcon: PropTypes.node, 360 | 361 | arrowStyle: Image.propTypes.style, 362 | /** 363 | * Enable or disable a Switch component 364 | */ 365 | hasSwitch: PropTypes.bool, 366 | /** 367 | * Switch state 368 | */ 369 | switchState: PropTypes.bool, 370 | /** 371 | * Switch props 372 | */ 373 | switchProps: PropTypes.object, 374 | /** 375 | * On value change callback 376 | */ 377 | switchOnValueChange: PropTypes.func, 378 | /** 379 | * Right side information on the setting item 380 | */ 381 | titleInfo: PropTypes.string, 382 | titleInfoStyle: Text.propTypes.style, 383 | /** 384 | * If 'Bottom', info is placed beneath the title 385 | */ 386 | titleInfoPosition: PropTypes.string, 387 | /** 388 | * Right side content 389 | */ 390 | rightSideContent: PropTypes.node, 391 | /* Gives opens to hide specific borders */ 392 | borderHide: PropTypes.oneOf(['Top', 'Bottom', 'Both']), 393 | 394 | itemRef: PropTypes.func, 395 | }, 396 | getDefaultProps(){ 397 | return { 398 | hasNavArrow: true 399 | } 400 | }, 401 | /** 402 | * not directly rendered 403 | */ 404 | render(){ 405 | return null; 406 | }, 407 | }); 408 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-settings-list", 3 | "version": "1.8.0", 4 | "description": "A clean and highly customizable React Native implementation of a list of settings for a settings page.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/evetstech/react-native-settings-list.git" 12 | }, 13 | "keywords": [ 14 | "react-native", 15 | "react-component", 16 | "ios", 17 | "android", 18 | "settings-list", 19 | "settings" 20 | ], 21 | "author": "Steve Singrattana ", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/evetstech/react-native-settings-list/issues" 25 | }, 26 | "homepage": "https://github.com/evetstech/react-native-settings-list#readme", 27 | "devDependencies": { 28 | "react-native": ">=0.18.0", 29 | "react": ">=0.14.0" 30 | }, 31 | "dependencies": { 32 | "create-react-class": "^15.6.2", 33 | "prop-types": "^15.5.10" 34 | } 35 | } 36 | --------------------------------------------------------------------------------