diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..eb6d93fa --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +docs +SampleApp diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..dbe4fecd --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,87 @@ +module.exports = { + parser: "@babel/eslint-parser", + env: { + es6: true, + node: true, + }, + extends: ["plugin:react/recommended", "eslint:recommended"], + plugins: ["babel", "import", "react", "react-native"], + parserOptions: { + ecmaVersion: 9, + ecmaFeatures: { + experimentalObjectRestSpread: true, + restParams: true, + spread: true, + jsx: true, + }, + sourceType: "module", + requireConfigFile: false, + babelOptions: { + babelrc: false, + configFile: false, + presets: ["@babel/preset-react"], + }, + }, + rules: { + indent: ["error", 4], + semi: ["error", "always"], + "no-mixed-spaces-and-tabs": 2, + "react/no-unknown-property": 1, + "react/jsx-filename-extension": 0, + "react/prefer-stateless-function": 0, + "react/sort-comp": 0, + "no-use-before-define": 0, + "no-underscore-dangle": 0, + "import/no-extraneous-dependencies": 0, + "import/no-unresolved": [2, { ignore: ["react", "react-native"] }], + "no-spaced-func": 2, + "space-in-parens": ["error", "never"], + "no-var": "error", + "no-constant-condition": 2, + eqeqeq: 2, + "no-else-return": 2, + "no-eval": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-useless-return": 2, + "block-spacing": 2, + "no-lonely-if": 2, + "no-trailing-spaces": 2, + "one-var": ["error", "never"], + "arrow-body-style": ["error", "as-needed"], + "no-console": 1, + "no-unused-vars": 1, + "jsx-quotes": ["error", "prefer-double"], + "no-unused-expressions": 2, + "require-await": 2, + "no-irregular-whitespace": 2, + "arrow-spacing": "error", + "arrow-parens": ["error", "as-needed"], + "brace-style": ["error", "1tbs", { allowSingleLine: false }], + "no-multi-spaces": [ + "error", + { + exceptions: { ImportDeclaration: true }, + }, + ], + "key-spacing": [ + 2, + { + beforeColon: false, + afterColon: true, + align: "value", + }, + ], + "no-empty-function": [2, { allow: ["arrowFunctions"] }], + "comma-dangle": [ + "error", + { + arrays: "always-multiline", + objects: "always-multiline", + imports: "always-multiline", + exports: "never", + functions: "ignore", + }, + ], + }, +}; diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 4a58bdcd..00000000 --- a/.flowconfig +++ /dev/null @@ -1,7 +0,0 @@ -[ignore] - -[include] - -[libs] - -[options] diff --git a/.gitignore b/.gitignore index 85b13164..447b55c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .idea npm-debug.log +node_modules +package-lock.json +yarn.lock # vim *.sw* diff --git a/.npmignore b/.npmignore index 5d9321bb..1ed126b1 100644 --- a/.npmignore +++ b/.npmignore @@ -2,4 +2,5 @@ test .idea SampleApp .gitignore -docs \ No newline at end of file +docs +*~ \ No newline at end of file diff --git a/BaseComponent.js b/BaseComponent.js deleted file mode 100644 index 7aac79d2..00000000 --- a/BaseComponent.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -import React from 'react'; - -export default class BaseComponent extends React.Component { - _bind(...methods) { - methods.forEach( (method) => this[method] = this[method].bind(this) ); - } -} diff --git a/README.md b/README.md index d382a18d..8c9dfaba 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,32 @@ -[![npm version](https://badge.fury.io/js/react-native-modal-picker.svg)](https://badge.fury.io/js/react-native-modal-picker) +# react-native-modal-selector [![npm version](https://badge.fury.io/js/react-native-modal-selector.svg)](https://badge.fury.io/js/react-native-modal-selector) -# react-native-modal-picker A cross-platform (iOS / Android), selector/picker component for React Native that is highly customizable and supports sections. +This project is the official continuation of the abandoned `react-native-modal-picker` repo. Contributors are welcome to [request a promotion to collaborator status](https://github.com/peacechen/react-native-modal-selector/issues/1). + ## Demo - + ## Install ```sh -npm i react-native-modal-picker --save +npm install react-native-modal-selector ``` ## Usage -You can either use this component as an wrapper around your existing component or use it in its default mode. In default mode a customizable button is rendered. +You can either use this component in its default mode, as a wrapper around your existing component or provide a custom component (where you need to control opening of the modal yourself). In default mode a customizable button is rendered. See `SampleApp` for an example how to use this component. ```jsx - -import ModalPicker from 'react-native-modal-picker' - -[..] +import ModalSelector from 'react-native-modal-selector' class SampleApp extends Component { - constructor() { - super(); + constructor(props) { + super(props); this.state = { textInputValue: '' @@ -41,59 +39,150 @@ class SampleApp extends Component { { key: index++, section: true, label: 'Fruits' }, { key: index++, label: 'Red Apples' }, { key: index++, label: 'Cherries' }, - { key: index++, label: 'Cranberries' }, - { key: index++, label: 'Pink Grapefruit' }, - { key: index++, label: 'Raspberries' }, - { key: index++, section: true, label: 'Vegetables' }, - { key: index++, label: 'Beets' }, - { key: index++, label: 'Red Peppers' }, - { key: index++, label: 'Radishes' }, - { key: index++, label: 'Radicchio' }, - { key: index++, label: 'Red Onions' }, - { key: index++, label: 'Red Potatoes' }, - { key: index++, label: 'Rhubarb' }, - { key: index++, label: 'Tomatoes' } + { key: index++, label: 'Cranberries', accessibilityLabel: 'Tap here for cranberries' }, + // etc... + // Can also add additional custom keys which are passed to the onChange callback + { key: index++, label: 'Vegetable', customKey: 'Not a fruit' } ]; return ( - { alert(`${option.label} (${option.key}) nom nom nom`) }} /> - { this.setState({textInputValue:option.label})}}> - + - - + + + + // Custom component + { this.selector = selector; }} + customSelector={ this.selector.open()} />} + /> ); } } ``` -## Props - -* `data - []` required, array of objects with a unique key and label -* `style - object` optional, style definitions for the root element -* `onChange - function` optional, callback function, when the users has selected an option -* `initValue - string` optional, text that is initially shown on the button -* `cancelText - string` optional, text of the cancel button -* `selectStyle - object` optional, style definitions for the select element (available in default mode only!) -* `selectTextStyle - object` optional, style definitions for the select element (available in default mode only!) -* `overlayStyle - object` optional, style definitions for the overly/background element -* `sectionStyle - object` optional, style definitions for the section element -* `sectionTextStyle - object` optional, style definitions for the select text element -* `optionStyle - object` optional, style definitions for the option element -* `optionTextStyle - object` optional, style definitions for the option text element -* `cancelStyle - object` optional, style definitions for the cancel element -* `cancelTextStyle - object` optional, style definitions for the cancel text element +## Data Format + +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. Optionally provide a unique `testID` for each item: +```javascript +[{ + key: 5, + label: 'Red Apples', + // The next keys are optional -- + component: Red Apples custom component ☺, + testID: '5-red-apples' +}] +``` + + + +If your data has a specific format, you can define extractors of data, example: +```javascript +this.setState({data: [{ id: 5, name: 'Red Apples' }]}); + +return ( + item.id} + labelExtractor= {item => item.name} + /> +); +``` + +## API + +### Props + +Prop | Type | Optional | Default | Description +------------------- | -------- | -------- | ------------ | ----------- +`data` | array | No | [] | array of objects with a unique `key` and `label` to select in the modal. Optional `component` overrides label text. Optional unique `testID` for each item. +`onChange` | function | Yes | () => {} | callback function, when the users has selected an option +`onModalOpen` | function | Yes | () => {} | callback function, when modal is opening +`onModalClose` | function | Yes | (item) => {} | callback function, when modal is closing. Returns the selected item. +`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 +`initValue` | string | Yes | `Select me!` | text that is initially shown on the button +`cancelText` | string | Yes | `cancel` | text of the cancel button +`disabled` | bool | Yes | false | `true` disables opening of the modal +`supportedOrientations` | ['portrait', 'landscape'] | Yes | both | orientations the modal supports +`keyboardShouldPersistTaps`| `string` / `bool` | Yes | `always` | passed to underlying ScrollView +`listType` | string | Yes | `SCROLLVIEW` | scroller type: `SCROLLVIEW` or `FLATLIST` +`animationType` | string | Yes | `slide` | type of animation to be used to show the modal. Must be one of `none`, `slide` or `fade`. +`style` | object | Yes | | style definitions for the root element +`childrenContainerStyle`| object | Yes | {} | style definitions for the children container view +`touchableStyle` | object | Yes | {} | style definitions for the touchable element +`touchableActiveOpacity` | number | Yes | 0.2 | opacity for the touchable element on touch +`selectStyle`       | object   | Yes     | {}         | style definitions for the select element (available in default mode only!). NOTE: Due to breaking changes in React Native, RN < 0.39.0 should pass `flex:1` explicitly to `selectStyle` as a prop. +`selectTextStyle` | object | Yes | {} | style definitions for the select element (available in default mode only!) +`overlayStyle` | object | Yes | { flex: 1, padding: '5%', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.7)' } | style definitions for the overlay background element. RN <= 0.41 should override this with pixel value for padding. +`sectionStyle` | object | Yes | {} | style definitions for the section element +`sectionTextStyle` | object | Yes | {} | style definitions for the select text element +`selectedItemTextStyle` | object | Yes | {} | style definitions for the currently selected text element +`optionStyle` | object | Yes | {} | style definitions for the option element +`optionTextStyle` | object | Yes | {} | style definitions for the option text element +`optionContainerStyle`| object | Yes | {} | style definitions for the option container element +`cancelStyle` | object | Yes | {} | style definitions for the cancel element +`cancelTextStyle` | object | Yes | {} | style definitions for the cancel text element +`initValueTextStyle`| object | Yes | {} | style definitions for the initValue text element +`cancelContainerStyle`| object | Yes | {} | style definitions for the cancel container +`backdropPressToClose`| bool | Yes | false | `true` makes the modal close when the overlay is pressed +`passThruProps`| object | Yes | {} | props to pass through to the container View and each option TouchableOpacity (e.g. testID for testing) +`selectTextPassThruProps`| object | Yes | {} | props to pass through to the select text component +`optionTextPassThruProps`| object | Yes | {} | props to pass through to the options text components in the modal +`cancelTextPassThruProps`| object | Yes | {} | props to pass through to the cancel text components in the modal +`scrollViewPassThruProps`| object | Yes | {} | props to pass through to the internal ScrollView +`openButtonContainerAccessible`| bool | Yes | false | `true` enables accessibility for the open button container. Note: if `false` be sure to define accessibility props directly in the wrapped component. +`listItemAccessible`| bool | Yes | false | `true` enables accessibility for data items. Note: data items should have an `accessibilityLabel` property if this is enabled +`cancelButtonAccessible`| bool | Yes | false | `true` enables accessibility for cancel button. +`scrollViewAccessible`| bool | Yes | false | `true` enables accessibility for the scroll view. Only enable this if you don't want to interact with individual data items. +`scrollViewAccessibilityLabel` | string | Yes | undefined | Accessibility label for the modal ScrollView +`cancelButtonAccessibilityLabel` | string | Yes | undefined | Accessibility label for the cancel button +`modalOpenerHitSlop` | object | Yes | {} | How far touch can stray away from touchable that opens modal ([RN docs](https://facebook.github.io/react-native/docs/touchablewithoutfeedback.html#hitslop)) +`customSelector` | node | Yes | undefined | Render a custom node instead of the built-in select box. +`selectedKey` | any | Yes | '' | Key of the item to be initially selected +`enableShortPress` | bool | Yes | true | enables short press. This is regular touch behavior. +`enableLongPress` | bool | Yes | false | enables long press. When true, `onModalOpen` returns `{longPress: true}` +`optionsTestIDPrefix` | string | Yes | `'default'` | This prefixes each selectable option's testID prop if no testID keys are provided in `props.data` array objects. Default for each option's testID: 'default-\' +`header` | node | Yes | undefined | Render a header above the list +`onEndReached` | function | Yes | undefined | Called once when the scroll position gets of the rendered content. + +### Methods + +* `open()`: open the modal. +* `close()`: close the modal. +* `getSelectedItem()`: get current selected item, updated by onChange event. + +## See also + +* A similar project is [hepter/react-native-modal-selector-searchable](https://github.com/hepter/react-native-modal-selector-searchable), which is a fork of this module that adds searching capabilities. diff --git a/SampleApp/.buckconfig b/SampleApp/.buckconfig deleted file mode 100644 index 934256cb..00000000 --- a/SampleApp/.buckconfig +++ /dev/null @@ -1,6 +0,0 @@ - -[android] - target = Google Inc.:Google APIs:23 - -[maven_repositories] - central = https://repo1.maven.org/maven2 diff --git a/SampleApp/.expo-shared/assets.json b/SampleApp/.expo-shared/assets.json new file mode 100644 index 00000000..17ad2288 --- /dev/null +++ b/SampleApp/.expo-shared/assets.json @@ -0,0 +1,4 @@ +{ + "f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true, + "89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true +} \ No newline at end of file diff --git a/SampleApp/.flowconfig b/SampleApp/.flowconfig deleted file mode 100644 index 45fd3ccb..00000000 --- a/SampleApp/.flowconfig +++ /dev/null @@ -1,97 +0,0 @@ -[ignore] - -# We fork some components by platform. -.*/*.web.js -.*/*.android.js - -# Some modules have their own node_modules with overlap -.*/node_modules/node-haste/.* - -# Ugh -.*/node_modules/babel.* -.*/node_modules/babylon.* -.*/node_modules/invariant.* - -# Ignore react and fbjs where there are overlaps, but don't ignore -# anything that react-native relies on -.*/node_modules/fbjs/lib/Map.js -.*/node_modules/fbjs/lib/ErrorUtils.js - -# Flow has a built-in definition for the 'react' module which we prefer to use -# over the currently-untyped source -.*/node_modules/react/react.js -.*/node_modules/react/lib/React.js -.*/node_modules/react/lib/ReactDOM.js - -.*/__mocks__/.* -.*/__tests__/.* - -.*/commoner/test/source/widget/share.js - -# Ignore commoner tests -.*/node_modules/commoner/test/.* - -# See https://github.com/facebook/flow/issues/442 -.*/react-tools/node_modules/commoner/lib/reader.js - -# Ignore jest -.*/node_modules/jest-cli/.* - -# Ignore Website -.*/website/.* - -# Ignore generators -.*/local-cli/generator.* - -# Ignore BUCK generated folders -.*\.buckd/ - -# Ignore RNPM -.*/local-cli/rnpm/.* - -.*/node_modules/is-my-json-valid/test/.*\.json -.*/node_modules/iconv-lite/encodings/tables/.*\.json -.*/node_modules/y18n/test/.*\.json -.*/node_modules/spdx-license-ids/spdx-license-ids.json -.*/node_modules/spdx-exceptions/index.json -.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json -.*/node_modules/resolve/lib/core.json -.*/node_modules/jsonparse/samplejson/.*\.json -.*/node_modules/json5/test/.*\.json -.*/node_modules/ua-parser-js/test/.*\.json -.*/node_modules/builtin-modules/builtin-modules.json -.*/node_modules/binary-extensions/binary-extensions.json -.*/node_modules/url-regex/tlds.json -.*/node_modules/joi/.*\.json -.*/node_modules/isemail/.*\.json -.*/node_modules/tr46/.*\.json - - -[include] - -[libs] -node_modules/react-native/Libraries/react-native/react-native-interface.js -node_modules/react-native/flow -flow/ - -[options] -module.system=haste - -esproposal.class_static_fields=enable -esproposal.class_instance_fields=enable - -munge_underscores=true - -module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' -module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' - -suppress_type=$FlowIssue -suppress_type=$FlowFixMe -suppress_type=$FixMe - -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ -suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy - -[version] -^0.25.0 diff --git a/SampleApp/.gitignore b/SampleApp/.gitignore index 42c9490e..094fd5ff 100644 --- a/SampleApp/.gitignore +++ b/SampleApp/.gitignore @@ -1,40 +1,15 @@ -# OSX -# +node_modules/**/* +.expo/* +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ +web-report/ +package-lock.json + +# macOS .DS_Store - -# Xcode -# -build/ -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata -*.xccheckout -*.moved-aside -DerivedData -*.hmap -*.ipa -*.xcuserstate -project.xcworkspace - -# Android/IJ -# -.idea -.gradle -local.properties - -# node.js -# -node_modules/ -npm-debug.log - -# BUCK -buck-out/ -\.buckd/ -android/app/libs -android/keystores/debug.keystore diff --git a/SampleApp/.watchmanconfig b/SampleApp/.watchmanconfig deleted file mode 100644 index 9e26dfee..00000000 --- a/SampleApp/.watchmanconfig +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/SampleApp/App.tsx b/SampleApp/App.tsx new file mode 100644 index 00000000..d212c3e8 --- /dev/null +++ b/SampleApp/App.tsx @@ -0,0 +1,173 @@ +"use strict"; + +import React, { useRef, useState } from "react"; + +import { View, Text, TextInput, Switch, Image, Alert } from "react-native"; + +import ModalSelector from "react-native-modal-selector"; +import { countryList } from "./assets/CountryList"; + +export const SampleApp = () => { + const [textInputValue, setTextInputValue] = useState(""); + const ref = useRef(); + + let index = 0; + const data = [ + { key: index++, section: true, label: "Fruits" }, + { + key: index++, + label: "Red Apples", + component: ( + + Red Apples custom component ☺ + + ), + }, + { key: index++, label: "Cherries" }, + { key: index++, label: "Cranberries" }, + { key: index++, label: "Pink Grapefruit" }, + { key: index++, label: "Raspberries" }, + { key: index++, section: true, label: "Vegetables" }, + { key: index++, label: "Beets" }, + { key: index++, label: "Red Peppers" }, + { key: index++, label: "Radishes" }, + { key: index++, label: "Radicchio" }, + { key: index++, label: "Red Onions" }, + { key: index++, label: "Red Potatoes" }, + { key: index++, label: "Rhubarb" }, + { key: index++, label: "Tomatoes" }, + ]; + + return ( + + {/* Default mode: a clickable button will re rendered */} + { + Alert.alert(`${option.label} (${option.key}) nom nom nom`); + }} + /> + + {/* + Wrapper mode: just wrap your existing component with ModalSelector. + When the user clicks on your element, the modal selector is shown. + */} + { + setTextInputValue(option.label); + }} + > + + + + {/* + Custom mode: you have to provide a react-native component that have to + control how the selector should open (and for this you need a ref to the modal) + */} + ref.current.open()} + thumbColor={"#88f"} + /> + } + /> + + {/* Default mode: a clickable button will re rendered with FlatList */} + x.name} + labelExtractor={(x) => x.name} + initValue="listType with FlatList" + initValueTextStyle={{ color: "black" }} + selectStyle={{ borderColor: "black" }} + selectTextStyle={{ color: "blue" }} + onChange={(option) => { + setTextInputValue(option.name); + }} + componentExtractor={(option) => } + /> + + {/* Default mode: a clickable button will re rendered without FlatList */} + x.name} + labelExtractor={(x) => x.name} + initValue="listType without FlatList" + initValueTextStyle={{ color: "black" }} + selectStyle={{ borderColor: "black" }} + selectTextStyle={{ color: "blue" }} + onChange={(option) => { + setTextInputValue(option.name); + }} + componentExtractor={(option) => } + /> + + {/* With a fixed header at the top of the list */} + x.name} + labelExtractor={(x) => x.name} + initValue="listType without FlatList but fixed header" + initValueTextStyle={{ color: "black" }} + selectStyle={{ borderColor: "black" }} + selectTextStyle={{ color: "blue" }} + onChange={(option) => { + setTextInputValue(option.name); + }} + componentExtractor={(option) => } + header={ + + What country would you pick? + + Please, select an option + + + } + /> + + ); +}; + +const ListItem = ({ data }) => { + return ( + + + {data.number} + {data.name} + + ); +}; + +export default SampleApp; diff --git a/SampleApp/README.md b/SampleApp/README.md index 20ee526d..28ca8919 100644 --- a/SampleApp/README.md +++ b/SampleApp/README.md @@ -2,8 +2,27 @@ This demo app demonstrates how to use this component. +``` +$ npm install +$ react-native run-[ios|android] +``` + # Development -Because the packager [does not support symlinks at the moment](https://github.com/facebook/react-native/issues/637), we have to use a custom nodemon workaround to use this app for development. After starting React Native use the following command to keep the module in sync. +Use [nodemon](https://github.com/remy/nodemon) to keep the module in sync with `node_modules` of this example app: + +``` +$ npm install +$ npm run nodemon +$ npm run start +``` + +You can now edit the files in `../`, and they will be synced to `node_modules/react-native-modal-selector/` + + +# Modifying react-native-modal-selector (RNMS) code during development -`nodemon nodemon.json` +If the nodemon watcher doesn't work on your system, run `npm run postinstall` to update the library code in this sample app. This must be done manually every time the library's code changes. For Windows, the `postinstall` script must be modified to: +``` + "postinstall": "copy /y ..\\*.js node_modules\\react-native-modal-selector", +``` diff --git a/SampleApp/android/app/BUCK b/SampleApp/android/app/BUCK deleted file mode 100644 index 6b4144bc..00000000 --- a/SampleApp/android/app/BUCK +++ /dev/null @@ -1,66 +0,0 @@ -import re - -# To learn about Buck see [Docs](https://buckbuild.com/). -# To run your application with Buck: -# - install Buck -# - `npm start` - to start the packager -# - `cd android` -# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US` -# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck -# - `buck install -r android/app` - compile, install and run application -# - -lib_deps = [] -for jarfile in glob(['libs/*.jar']): - name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) - lib_deps.append(':' + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) - -for aarfile in glob(['libs/*.aar']): - name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) - lib_deps.append(':' + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) - -android_library( - name = 'all-libs', - exported_deps = lib_deps -) - -android_library( - name = 'app-code', - srcs = glob([ - 'src/main/java/**/*.java', - ]), - deps = [ - ':all-libs', - ':build_config', - ':res', - ], -) - -android_build_config( - name = 'build_config', - package = 'com.sampleapp', -) - -android_resource( - name = 'res', - res = 'src/main/res', - package = 'com.sampleapp', -) - -android_binary( - name = 'app', - package_type = 'debug', - manifest = 'src/main/AndroidManifest.xml', - keystore = '//android/keystores:debug', - deps = [ - ':app-code', - ], -) diff --git a/SampleApp/android/app/build.gradle b/SampleApp/android/app/build.gradle deleted file mode 100644 index 8fb8f353..00000000 --- a/SampleApp/android/app/build.gradle +++ /dev/null @@ -1,133 +0,0 @@ -apply plugin: "com.android.application" - -import com.android.build.OutputFile - -/** - * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets - * and bundleReleaseJsAndAssets). - * These basically call `react-native bundle` with the correct arguments during the Android build - * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the - * bundle directly from the development server. Below you can see all the possible configurations - * and their defaults. If you decide to add a configuration block, make sure to add it before the - * `apply from: "../../node_modules/react-native/react.gradle"` line. - * - * project.ext.react = [ - * // the name of the generated asset file containing your JS bundle - * bundleAssetName: "index.android.bundle", - * - * // the entry file for bundle generation - * entryFile: "index.android.js", - * - * // whether to bundle JS and assets in debug mode - * bundleInDebug: false, - * - * // whether to bundle JS and assets in release mode - * bundleInRelease: true, - * - * // whether to bundle JS and assets in another build variant (if configured). - * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants - * // The configuration property can be in the following formats - * // 'bundleIn${productFlavor}${buildType}' - * // 'bundleIn${buildType}' - * // bundleInFreeDebug: true, - * // bundleInPaidRelease: true, - * // bundleInBeta: true, - * - * // the root of your project, i.e. where "package.json" lives - * root: "../../", - * - * // where to put the JS bundle asset in debug mode - * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", - * - * // where to put the JS bundle asset in release mode - * jsBundleDirRelease: "$buildDir/intermediates/assets/release", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in debug mode - * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in release mode - * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", - * - * // by default the gradle tasks are skipped if none of the JS files or assets change; this means - * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to - * // date; if you have any other folders that you want to ignore for performance reasons (gradle - * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ - * // for example, you might want to remove it from here. - * inputExcludes: ["android/**", "ios/**"] - * ] - */ - -apply from: "../../node_modules/react-native/react.gradle" - -/** - * Set this to true to create two separate APKs instead of one: - * - An APK that only works on ARM devices - * - An APK that only works on x86 devices - * The advantage is the size of the APK is reduced by about 4MB. - * Upload all the APKs to the Play Store and people will download - * the correct one based on the CPU architecture of their device. - */ -def enableSeparateBuildPerCPUArchitecture = false - -/** - * Run Proguard to shrink the Java bytecode in release builds. - */ -def enableProguardInReleaseBuilds = false - -android { - compileSdkVersion 23 - buildToolsVersion "23.0.1" - - defaultConfig { - applicationId "com.sampleapp" - minSdkVersion 16 - targetSdkVersion 22 - versionCode 1 - versionName "1.0" - ndk { - abiFilters "armeabi-v7a", "x86" - } - } - splits { - abi { - reset() - enable enableSeparateBuildPerCPUArchitecture - universalApk false // If true, also generate a universal APK - include "armeabi-v7a", "x86" - } - } - buildTypes { - release { - minifyEnabled enableProguardInReleaseBuilds - proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" - } - } - // applicationVariants are e.g. debug, release - applicationVariants.all { variant -> - variant.outputs.each { output -> - // For each separate APK per architecture, set a unique version code as described here: - // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits - def versionCodes = ["armeabi-v7a":1, "x86":2] - def abi = output.getFilter(OutputFile.ABI) - if (abi != null) { // null for the universal-debug, universal-release variants - output.versionCodeOverride = - versionCodes.get(abi) * 1048576 + defaultConfig.versionCode - } - } - } -} - -dependencies { - compile fileTree(dir: "libs", include: ["*.jar"]) - compile "com.android.support:appcompat-v7:23.0.1" - compile "com.facebook.react:react-native:+" // From node_modules -} - -// Run this once to be able to run the application with BUCK -// puts all compile dependencies into folder libs for BUCK to use -task copyDownloadableDepsToLibs(type: Copy) { - from configurations.compile - into 'libs' -} diff --git a/SampleApp/android/app/proguard-rules.pro b/SampleApp/android/app/proguard-rules.pro deleted file mode 100644 index 9852871b..00000000 --- a/SampleApp/android/app/proguard-rules.pro +++ /dev/null @@ -1,63 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Disabling obfuscation is useful if you collect stack traces from production crashes -# (unless you are using a system that supports de-obfuscate the stack traces). --dontobfuscate - -# React Native - -# Keep our interfaces so they can be used by other ProGuard rules. -# See http://sourceforge.net/p/proguard/bugs/466/ --keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip --keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters - -# Do not strip any method/class that is annotated with @DoNotStrip --keep @com.facebook.proguard.annotations.DoNotStrip class * --keepclassmembers class * { - @com.facebook.proguard.annotations.DoNotStrip *; -} - --keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { - void set*(***); - *** get*(); -} - --keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } --keep class * extends com.facebook.react.bridge.NativeModule { *; } --keepclassmembers,includedescriptorclasses class * { native ; } --keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } - --dontwarn com.facebook.react.** - -# okhttp - --keepattributes Signature --keepattributes *Annotation* --keep class okhttp3.** { *; } --keep interface okhttp3.** { *; } --dontwarn okhttp3.** - -# okio - --keep class sun.misc.Unsafe { *; } --dontwarn java.nio.file.* --dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement --dontwarn okio.** diff --git a/SampleApp/android/app/react.gradle b/SampleApp/android/app/react.gradle deleted file mode 100644 index 4b43bf91..00000000 --- a/SampleApp/android/app/react.gradle +++ /dev/null @@ -1,96 +0,0 @@ -import org.apache.tools.ant.taskdefs.condition.Os - -def config = project.hasProperty("react") ? project.react : []; - -def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" -def entryFile = config.entryFile ?: "index.android.js" - -// because elvis operator -def elvisFile(thing) { - return thing ? file(thing) : null; -} - -def reactRoot = elvisFile(config.root) ?: file("../../") -def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] - -void runBefore(String dependentTaskName, Task task) { - Task dependentTask = tasks.findByPath(dependentTaskName); - if (dependentTask != null) { - dependentTask.dependsOn task - } -} - -gradle.projectsEvaluated { - // Grab all build types and product flavors - def buildTypes = android.buildTypes.collect { type -> type.name } - def productFlavors = android.productFlavors.collect { flavor -> flavor.name } - - // When no product flavors defined, use empty - if (!productFlavors) productFlavors.add('') - - productFlavors.each { productFlavorName -> - buildTypes.each { buildTypeName -> - // Create variant and source names - def sourceName = "${buildTypeName}" - def targetName = "${sourceName.capitalize()}" - if (productFlavorName) { - sourceName = "${productFlavorName}${targetName}" - } - - // React js bundle directories - def jsBundleDirConfigName = "jsBundleDir${targetName}" - def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?: - file("$buildDir/intermediates/assets/${sourceName}") - - def resourcesDirConfigName = "jsBundleDir${targetName}" - def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?: - file("$buildDir/intermediates/res/merged/${sourceName}") - def jsBundleFile = file("$jsBundleDir/$bundleAssetName") - - // Bundle task name for variant - def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets" - - def currentBundleTask = tasks.create( - name: bundleJsAndAssetsTaskName, - type: Exec) { - group = "react" - description = "bundle JS and assets for ${targetName}." - - // Create dirs if they are not there (e.g. the "clean" task just ran) - doFirst { - jsBundleDir.mkdirs() - resourcesDir.mkdirs() - } - - // Set up inputs and outputs so gradle can cache the result - inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) - outputs.dir jsBundleDir - outputs.dir resourcesDir - - // Set up the call to the react-native cli - workingDir reactRoot - - // Set up dev mode - def devEnabled = !targetName.toLowerCase().contains("release") - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}", - "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir - } else { - commandLine "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}", - "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir - } - - enabled config."bundleIn${targetName}" ?: targetName.toLowerCase().contains("release") - } - - // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process - currentBundleTask.dependsOn("merge${targetName}Resources") - currentBundleTask.dependsOn("merge${targetName}Assets") - - runBefore("processArmeabi-v7a${targetName}Resources", currentBundleTask) - runBefore("processX86${targetName}Resources", currentBundleTask) - runBefore("processUniversal${targetName}Resources", currentBundleTask) - runBefore("process${targetName}Resources", currentBundleTask) - } - } -} diff --git a/SampleApp/android/app/src/main/AndroidManifest.xml b/SampleApp/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 2eab0042..00000000 --- a/SampleApp/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/SampleApp/android/app/src/main/java/com/sampleapp/MainActivity.java b/SampleApp/android/app/src/main/java/com/sampleapp/MainActivity.java deleted file mode 100644 index 29c99265..00000000 --- a/SampleApp/android/app/src/main/java/com/sampleapp/MainActivity.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sampleapp; - -import com.facebook.react.ReactActivity; -import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; - -import java.util.Arrays; -import java.util.List; - -public class MainActivity extends ReactActivity { - - /** - * Returns the name of the main component registered from JavaScript. - * This is used to schedule rendering of the component. - */ - @Override - protected String getMainComponentName() { - return "SampleApp"; - } - - /** - * Returns whether dev mode should be enabled. - * This enables e.g. the dev menu. - */ - @Override - protected boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - - /** - * A list of packages used by the app. If the app uses additional views - * or modules besides the default ones, add more packages here. - */ - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage() - ); - } -} diff --git a/SampleApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/SampleApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bcc..00000000 Binary files a/SampleApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/SampleApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/SampleApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cb..00000000 Binary files a/SampleApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/SampleApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/SampleApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e..00000000 Binary files a/SampleApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/SampleApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/SampleApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cd..00000000 Binary files a/SampleApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/SampleApp/android/app/src/main/res/values/strings.xml b/SampleApp/android/app/src/main/res/values/strings.xml deleted file mode 100644 index 18f47088..00000000 --- a/SampleApp/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - SampleApp - diff --git a/SampleApp/android/app/src/main/res/values/styles.xml b/SampleApp/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 319eb0ca..00000000 --- a/SampleApp/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/SampleApp/android/build.gradle b/SampleApp/android/build.gradle deleted file mode 100644 index 403a0075..00000000 --- a/SampleApp/android/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.3.1' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - mavenLocal() - jcenter() - maven { - // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url "$projectDir/../../node_modules/react-native/android" - } - } -} diff --git a/SampleApp/android/gradle.properties b/SampleApp/android/gradle.properties deleted file mode 100644 index 1fd964e9..00000000 --- a/SampleApp/android/gradle.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -android.useDeprecatedNdk=true diff --git a/SampleApp/android/gradle/wrapper/gradle-wrapper.jar b/SampleApp/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index b5166dad..00000000 Binary files a/SampleApp/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/SampleApp/android/gradle/wrapper/gradle-wrapper.properties b/SampleApp/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index b9fbfaba..00000000 --- a/SampleApp/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip diff --git a/SampleApp/android/gradlew b/SampleApp/android/gradlew deleted file mode 100755 index 91a7e269..00000000 --- a/SampleApp/android/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/SampleApp/android/gradlew.bat b/SampleApp/android/gradlew.bat deleted file mode 100644 index aec99730..00000000 --- a/SampleApp/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/SampleApp/android/settings.gradle b/SampleApp/android/settings.gradle deleted file mode 100644 index b828a3b9..00000000 --- a/SampleApp/android/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'SampleApp' - -include ':app' diff --git a/SampleApp/app.js b/SampleApp/app.js deleted file mode 100644 index d74b50d4..00000000 --- a/SampleApp/app.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -import React, { Component } from 'react'; - -import { - View, - TextInput -} from 'react-native'; - -import ModalPicker from 'react-native-modal-picker' - -class SampleApp extends Component { - - constructor() { - super(); - - this.state = { - textInputValue: '' - } - } - - render() { - let index = 0; - const data = [ - { key: index++, section: true, label: 'Fruits' }, - { key: index++, label: 'Red Apples' }, - { key: index++, label: 'Cherries' }, - { key: index++, label: 'Cranberries' }, - { key: index++, label: 'Pink Grapefruit' }, - { key: index++, label: 'Raspberries' }, - { key: index++, section: true, label: 'Vegetables' }, - { key: index++, label: 'Beets' }, - { key: index++, label: 'Red Peppers' }, - { key: index++, label: 'Radishes' }, - { key: index++, label: 'Radicchio' }, - { key: index++, label: 'Red Onions' }, - { key: index++, label: 'Red Potatoes' }, - { key: index++, label: 'Rhubarb' }, - { key: index++, label: 'Tomatoes' } - ]; - - return ( - - - { /* Default mode: a clickable button will re rendered */ } - { alert(`${option.label} (${option.key}) nom nom nom`) }}/> - - { /* - Wrapper mode: just wrap your existing component with ModalPicker. - When the user clicks on your element, the modal selector is shown. - */ } - { this.setState({textInputValue:option.label})}}> - - - - - - ); - } -} - -export default SampleApp; \ No newline at end of file diff --git a/SampleApp/app.json b/SampleApp/app.json new file mode 100644 index 00000000..fb0d17e4 --- /dev/null +++ b/SampleApp/app.json @@ -0,0 +1,29 @@ +{ + "expo": { + "name": "React Native Modal Selector Sample", + "slug": "SampleApp", + "privacy": "public", + "platforms": [ + "ios", + "android", + "web" + ], + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "splash": { + "image": "./assets/icon.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "updates": { + "fallbackToCacheTimeout": 0 + }, + "assetBundlePatterns": [ + "**/*" + ], + "ios": { + "supportsTablet": true + } + } +} diff --git a/SampleApp/assets/CountryList.ts b/SampleApp/assets/CountryList.ts new file mode 100644 index 00000000..1e882cc6 --- /dev/null +++ b/SampleApp/assets/CountryList.ts @@ -0,0 +1,1109 @@ + +export const countryList = +[ + { + "name": "Afghanistan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Flag_of_Afghanistan.svg/320px-Flag_of_Afghanistan.svg.png", + "number": "+93" + }, + { + "name": "Albania", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Flag_of_Albania.svg/320px-Flag_of_Albania.svg.png", + "number": "+355" + }, + { + "name": "Algeria", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Flag_of_Algeria.svg/320px-Flag_of_Algeria.svg.png", + "number": "+213" + }, + { + "name": "Andorra", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Andorra.svg/320px-Flag_of_Andorra.svg.png", + "number": "+376" + }, + { + "name": "Angola", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9d/Flag_of_Angola.svg/320px-Flag_of_Angola.svg.png", + "number": "+244" + }, + { + "name": "Anguilla", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Flag_of_Anguilla.svg/320px-Flag_of_Anguilla.svg.png", + "number": "+1 264" + }, + { + "name": "Antigua and Barbuda", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Flag_of_Antigua_and_Barbuda.svg/320px-Flag_of_Antigua_and_Barbuda.svg.png", + "number": "+1268" + }, + { + "name": "Argentina", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Flag_of_Argentina.svg/320px-Flag_of_Argentina.svg.png", + "number": "+54" + }, + { + "name": "Armenia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Flag_of_Armenia.svg/320px-Flag_of_Armenia.svg.png", + "number": "+374" + }, + { + "name": "Aruba", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Flag_of_Aruba.svg/320px-Flag_of_Aruba.svg.png", + "number": "+297" + }, + { + "name": "Australia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Flag_of_Australia_%28converted%29.svg/320px-Flag_of_Australia_%28converted%29.svg.png", + "number": "+61" + }, + { + "name": "Austria", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Flag_of_Austria.svg/320px-Flag_of_Austria.svg.png", + "number": "+43" + }, + { + "name": "Azerbaijan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Flag_of_Azerbaijan.svg/320px-Flag_of_Azerbaijan.svg.png", + "number": "+994" + }, + { + "name": "Bahamas", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Flag_of_the_Bahamas.svg/320px-Flag_of_the_Bahamas.svg.png", + "number": "+1 242" + }, + { + "name": "Bahrain", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Flag_of_Bahrain.svg/320px-Flag_of_Bahrain.svg.png", + "number": "+973" + }, + { + "name": "Bangladesh", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Flag_of_Bangladesh.svg/320px-Flag_of_Bangladesh.svg.png", + "number": "+880" + }, + { + "name": "Barbados", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Flag_of_Barbados.svg/320px-Flag_of_Barbados.svg.png", + "number": "+1 246" + }, + { + "name": "Belarus", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Flag_of_Belarus.svg/320px-Flag_of_Belarus.svg.png", + "number": "+375" + }, + { + "name": "Belgium", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Flag_of_Belgium.svg/320px-Flag_of_Belgium.svg.png", + "number": "+32" + }, + { + "name": "Belize", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Flag_of_Belize.svg/320px-Flag_of_Belize.svg.png", + "number": "+501" + }, + { + "name": "Benin", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/Flag_of_Benin.svg/320px-Flag_of_Benin.svg.png", + "number": "+229" + }, + { + "name": "Bermuda", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Flag_of_Bermuda.svg/320px-Flag_of_Bermuda.svg.png", + "number": "+1 441" + }, + { + "name": "Bhutan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Flag_of_Bhutan.svg/320px-Flag_of_Bhutan.svg.png", + "number": "+975" + }, + { + "name": "Bosnia and Herzegovina", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Flag_of_Bosnia_and_Herzegovina.svg/320px-Flag_of_Bosnia_and_Herzegovina.svg.png", + "number": "+387" + }, + { + "name": "Botswana", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_Botswana.svg/320px-Flag_of_Botswana.svg.png", + "number": "+267" + }, + { + "name": "Bouvet Island", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Flag_of_Norway.svg/320px-Flag_of_Norway.svg.png", + "number": "+55" + }, + { + "name": "Brazil", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Flag_of_Brazil.svg/320px-Flag_of_Brazil.svg.png", + "number": "+55" + }, + { + "name": "British Indian Ocean Territory", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Flag_of_the_Commissioner_of_the_British_Indian_Ocean_Territory.svg/320px-Flag_of_the_Commissioner_of_the_British_Indian_Ocean_Territory.svg.png", + "number": "+246" + }, + { + "name": "Brunei Darussalam", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Flag_of_Brunei.svg/320px-Flag_of_Brunei.svg.png", + "number": "+673" + }, + { + "name": "Bulgaria", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Flag_of_Bulgaria.svg/320px-Flag_of_Bulgaria.svg.png", + "number": "+359" + }, + { + "name": "Burkina Faso", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Flag_of_Burkina_Faso.svg/320px-Flag_of_Burkina_Faso.svg.png", + "number": "+226" + }, + { + "name": "Burundi", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Flag_of_Burundi.svg/320px-Flag_of_Burundi.svg.png", + "number": "+257" + }, + { + "name": "Cambodia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Flag_of_Cambodia.svg/320px-Flag_of_Cambodia.svg.png", + "number": "+855" + }, + { + "name": "Cameroon", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Flag_of_Cameroon.svg/320px-Flag_of_Cameroon.svg.png", + "number": "+237" + }, + { + "name": "Canada", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Flag_of_Canada.svg/320px-Flag_of_Canada.svg.png", + "number": "+1" + }, + { + "name": "Cape Verde", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Flag_of_Cape_Verde.svg/320px-Flag_of_Cape_Verde.svg.png", + "number": "+238" + }, + { + "name": "Cayman Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0f/Flag_of_the_Cayman_Islands.svg/320px-Flag_of_the_Cayman_Islands.svg.png", + "number": "+1345" + }, + { + "name": "Central African Republic", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Flag_of_the_Central_African_Republic.svg/320px-Flag_of_the_Central_African_Republic.svg.png", + "number": "+236" + }, + { + "name": "Chad", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Flag_of_Chad.svg/320px-Flag_of_Chad.svg.png", + "number": "+235" + }, + { + "name": "Chile", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Flag_of_Chile.svg/320px-Flag_of_Chile.svg.png", + "number": "+56" + }, + { + "name": "China", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_the_People%27s_Republic_of_China.svg/320px-Flag_of_the_People%27s_Republic_of_China.svg.png", + "number": "+86" + }, + { + "name": "Christmas Island", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Flag_of_Christmas_Island.svg/320px-Flag_of_Christmas_Island.svg.png", + "number": "+61" + }, + { + "name": "Cocos (Keeling) Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Flag_of_the_Cocos_%28Keeling/320px-Flag_of_the_Cocos_%28Keeling.png%29_Islands.svg", + "number": "+61" + }, + { + "name": "Colombia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/21/Flag_of_Colombia.svg/320px-Flag_of_Colombia.svg.png", + "number": "+57" + }, + { + "name": "Comoros", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Flag_of_the_Comoros.svg/320px-Flag_of_the_Comoros.svg.png", + "number": "+269" + }, + { + "name": "Congo", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Flag_of_the_Republic_of_the_Congo.svg/320px-Flag_of_the_Republic_of_the_Congo.svg.png", + "number": "+242" + }, + { + "name": "Cook Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Flag_of_the_Cook_Islands.svg/320px-Flag_of_the_Cook_Islands.svg.png", + "number": "+682" + }, + { + "name": "Costa Rica", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_Costa_Rica_%28state%29.svg/320px-Flag_of_Costa_Rica_%28state%29.svg.png", + "number": "+506" + }, + { + "name": "Croatia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Flag_of_Croatia.svg/320px-Flag_of_Croatia.svg.png", + "number": "+385" + }, + { + "name": "Cuba", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Flag_of_Cuba.svg/320px-Flag_of_Cuba.svg.png", + "number": "+53" + }, + { + "name": "Cyprus", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_Cyprus.svg/320px-Flag_of_Cyprus.svg.png", + "number": "+357" + }, + { + "name": "Czech Republic", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_Czech_Republic.svg/320px-Flag_of_the_Czech_Republic.svg.png", + "number": "+420" + }, + { + "name": "Denmark", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Flag_of_Denmark.svg/320px-Flag_of_Denmark.svg.png", + "number": "+45" + }, + { + "name": "Djibouti", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Flag_of_Djibouti.svg/320px-Flag_of_Djibouti.svg.png", + "number": "+253" + }, + { + "name": "Dominica", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Flag_of_Dominica.svg/320px-Flag_of_Dominica.svg.png", + "number": "+1 767" + }, + { + "name": "Dominican Republic", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Flag_of_the_Dominican_Republic.svg/320px-Flag_of_the_Dominican_Republic.svg.png", + "number": "+1 849" + }, + { + "name": "Ecuador", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Flag_of_Ecuador.svg/320px-Flag_of_Ecuador.svg.png", + "number": "+593" + }, + { + "name": "Egypt", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Flag_of_Egypt.svg/320px-Flag_of_Egypt.svg.png", + "number": "+20" + }, + { + "name": "El Salvador", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Flag_of_El_Salvador.svg/320px-Flag_of_El_Salvador.svg.png", + "number": "+503" + }, + { + "name": "Equatorial Guinea", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Flag_of_Equatorial_Guinea.svg/320px-Flag_of_Equatorial_Guinea.svg.png", + "number": "+240" + }, + { + "name": "Eritrea", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Flag_of_Eritrea.svg/320px-Flag_of_Eritrea.svg.png", + "number": "+291" + }, + { + "name": "Estonia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Flag_of_Estonia.svg/320px-Flag_of_Estonia.svg.png", + "number": "+372" + }, + { + "name": "Ethiopia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Flag_of_Ethiopia.svg/320px-Flag_of_Ethiopia.svg.png", + "number": "+251" + }, + { + "name": "Falkland Islands (Malvinas)", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Flag_of_the_Falkland_Islands.svg/320px-Flag_of_the_Falkland_Islands.svg.png", + "number": "+500" + }, + { + "name": "Faroe Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Flag_of_the_Faroe_Islands.svg/320px-Flag_of_the_Faroe_Islands.svg.png", + "number": "+298" + }, + { + "name": "Fiji", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_Fiji.svg/320px-Flag_of_Fiji.svg.png", + "number": "+679" + }, + { + "name": "Finland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_Finland.svg/320px-Flag_of_Finland.svg.png", + "number": "+358" + }, + { + "name": "France", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Flag_of_France.svg/320px-Flag_of_France.svg.png", + "number": "+33" + }, + { + "name": "French Guiana", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Flag_of_French_Guiana.svg/320px-Flag_of_French_Guiana.svg.png", + "number": "+594" + }, + { + "name": "French Polynesia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Flag_of_French_Polynesia.svg/320px-Flag_of_French_Polynesia.svg.png", + "number": "+689" + }, + { + "name": "Gabon", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/Flag_of_Gabon.svg/320px-Flag_of_Gabon.svg.png", + "number": "+241" + }, + { + "name": "Gambia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Flag_of_The_Gambia.svg/320px-Flag_of_The_Gambia.svg.png", + "number": "+220" + }, + { + "name": "Georgia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0f/Flag_of_Georgia.svg/320px-Flag_of_Georgia.svg.png", + "number": "+995" + }, + { + "name": "Germany", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_Germany.svg/320px-Flag_of_Germany.svg.png", + "number": "+49" + }, + { + "name": "Ghana", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Ghana.svg/320px-Flag_of_Ghana.svg.png", + "number": "+233" + }, + { + "name": "Gibraltar", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Flag_of_Gibraltar.svg/320px-Flag_of_Gibraltar.svg.png", + "number": "+350" + }, + { + "name": "Greece", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Greece.svg/320px-Flag_of_Greece.svg.png", + "number": "+30" + }, + { + "name": "Greenland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Flag_of_Greenland.svg/320px-Flag_of_Greenland.svg.png", + "number": "+299" + }, + { + "name": "Grenada", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_Grenada.svg/320px-Flag_of_Grenada.svg.png", + "number": "+1 473" + }, + { + "name": "Guadeloupe", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/Flag_of_Guadeloupe_%28local/320px-Flag_of_Guadeloupe_%28local.png%29.svg", + "number": "+590" + }, + { + "name": "Guam", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Flag_of_Guam.svg/320px-Flag_of_Guam.svg.png", + "number": "+1 671" + }, + { + "name": "Guatemala", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Flag_of_Guatemala.svg/320px-Flag_of_Guatemala.svg.png", + "number": "+502" + }, + { + "name": "Guernsey", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_Guernsey.svg/320px-Flag_of_Guernsey.svg.png", + "number": "+44" + }, + { + "name": "Guinea", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Flag_of_Guinea.svg/320px-Flag_of_Guinea.svg.png", + "number": "+224" + }, + { + "name": "Guinea-Bissau", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_Guinea-Bissau/320px-Flag_of_Guinea-Bissau.png.svg", + "number": "+245" + }, + { + "name": "Guyana", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Flag_of_Guyana.svg/320px-Flag_of_Guyana.svg.png", + "number": "+592" + }, + { + "name": "Haiti", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Flag_of_Haiti.svg/320px-Flag_of_Haiti.svg.png", + "number": "+509" + }, + { + "name": "Heard Island and McDonald Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_Antarctica.svg/320px-Flag_of_Antarctica.svg.png", + "number": "+672" + }, + { + "name": "Holy See (Vatican City State)", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Flag_of_the_Vatican_City.svg/320px-Flag_of_the_Vatican_City.svg.png", + "number": "+379" + }, + { + "name": "Honduras", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Flag_of_Honduras.svg/320px-Flag_of_Honduras.svg.png", + "number": "+504" + }, + { + "name": "Hong Kong", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Flag_of_Hong_Kong.svg/320px-Flag_of_Hong_Kong.svg.png", + "number": "+852" + }, + { + "name": "Hungary", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Flag_of_Hungary.svg/320px-Flag_of_Hungary.svg.png", + "number": "+36" + }, + { + "name": "Iceland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Flag_of_Iceland.svg/320px-Flag_of_Iceland.svg.png", + "number": "+354" + }, + { + "name": "India", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Flag_of_India.svg/320px-Flag_of_India.svg.png", + "number": "+91" + }, + { + "name": "Indonesia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Flag_of_Indonesia.svg/320px-Flag_of_Indonesia.svg.png", + "number": "+62" + }, + { + "name": "Iran", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Flag_of_Iran.svg/320px-Flag_of_Iran.svg.png", + "number": "+98" + }, + { + "name": "Iraq", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Flag_of_Iraq.svg/320px-Flag_of_Iraq.svg.png", + "number": "+964" + }, + { + "name": "Ireland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Flag_of_Ireland.svg/320px-Flag_of_Ireland.svg.png", + "number": "+353" + }, + { + "name": "Isle of Man", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_the_Isle_of_Man.svg/320px-Flag_of_the_Isle_of_Man.svg.png", + "number": "+44" + }, + { + "name": "Israel", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_Israel.svg/320px-Flag_of_Israel.svg.png", + "number": "+972" + }, + { + "name": "Italy", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Flag_of_Italy.svg/320px-Flag_of_Italy.svg.png", + "number": "+39" + }, + { + "name": "Jamaica", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/Flag_of_Jamaica.svg/320px-Flag_of_Jamaica.svg.png", + "number": "+1 876" + }, + { + "name": "Japan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Flag_of_Japan.svg/320px-Flag_of_Japan.svg.png", + "number": "+81" + }, + { + "name": "Jersey", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Flag_of_Jersey.svg/320px-Flag_of_Jersey.svg.png", + "number": "+44" + }, + { + "name": "Jordan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Flag_of_Jordan.svg/320px-Flag_of_Jordan.svg.png", + "number": "+962" + }, + { + "name": "Kazakhstan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Flag_of_Kazakhstan.svg/320px-Flag_of_Kazakhstan.svg.png", + "number": "+7" + }, + { + "name": "Kenya", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Flag_of_Kenya.svg/320px-Flag_of_Kenya.svg.png", + "number": "+254" + }, + { + "name": "Kiribati", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Flag_of_Kiribati.svg/320px-Flag_of_Kiribati.svg.png", + "number": "+686" + }, + { + "name": "Kuwait", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Flag_of_Kuwait.svg/320px-Flag_of_Kuwait.svg.png", + "number": "+965" + }, + { + "name": "Kyrgyzstan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Flag_of_Kyrgyzstan.svg/320px-Flag_of_Kyrgyzstan.svg.png", + "number": "+996" + }, + { + "name": "Lao People's Democratic Republic", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Flag_of_Laos.svg/320px-Flag_of_Laos.svg.png", + "number": "+856" + }, + { + "name": "Latvia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Flag_of_Latvia.svg/320px-Flag_of_Latvia.svg.png", + "number": "+371" + }, + { + "name": "Lebanon", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Flag_of_Lebanon.svg/320px-Flag_of_Lebanon.svg.png", + "number": "+961" + }, + { + "name": "Lesotho", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Flag_of_Lesotho.svg/320px-Flag_of_Lesotho.svg.png", + "number": "+266" + }, + { + "name": "Liberia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/Flag_of_Liberia.svg/320px-Flag_of_Liberia.svg.png", + "number": "+231" + }, + { + "name": "Liechtenstein", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Flag_of_Liechtenstein.svg/320px-Flag_of_Liechtenstein.svg.png", + "number": "+423" + }, + { + "name": "Lithuania", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Flag_of_Lithuania.svg/320px-Flag_of_Lithuania.svg.png", + "number": "+370" + }, + { + "name": "Luxembourg", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Flag_of_Luxembourg.svg/320px-Flag_of_Luxembourg.svg.png", + "number": "+352" + }, + { + "name": "Macao", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Flag_of_Macau.svg/320px-Flag_of_Macau.svg.png", + "number": "+853" + }, + { + "name": "Madagascar", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_Madagascar.svg/320px-Flag_of_Madagascar.svg.png", + "number": "+261" + }, + { + "name": "Malawi", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Flag_of_Malawi.svg/320px-Flag_of_Malawi.svg.png", + "number": "+265" + }, + { + "name": "Malaysia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Flag_of_Malaysia.svg/320px-Flag_of_Malaysia.svg.png", + "number": "+60" + }, + { + "name": "Maldives", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0f/Flag_of_Maldives.svg/320px-Flag_of_Maldives.svg.png", + "number": "+960" + }, + { + "name": "Mali", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Flag_of_Mali.svg/320px-Flag_of_Mali.svg.png", + "number": "+223" + }, + { + "name": "Malta", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Flag_of_Malta.svg/320px-Flag_of_Malta.svg.png", + "number": "+356" + }, + { + "name": "Marshall Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Flag_of_the_Marshall_Islands.svg/320px-Flag_of_the_Marshall_Islands.svg.png", + "number": "+692" + }, + { + "name": "Martinique", + "flag": "https://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/320px-Flag_of_France.svg.png", + "number": "+596" + }, + { + "name": "Mauritania", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Flag_of_Mauritania.svg/320px-Flag_of_Mauritania.svg.png", + "number": "+222" + }, + { + "name": "Mauritius", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Flag_of_Mauritius.svg/320px-Flag_of_Mauritius.svg.png", + "number": "+230" + }, + { + "name": "Mayotte", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Flag_of_France.svg/320px-Flag_of_France.svg.png", + "number": "+262" + }, + { + "name": "Mexico", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Flag_of_Mexico.svg/320px-Flag_of_Mexico.svg.png", + "number": "+52" + }, + { + "name": "Monaco", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Flag_of_Monaco.svg/320px-Flag_of_Monaco.svg.png", + "number": "+377" + }, + { + "name": "Mongolia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Flag_of_Mongolia.svg/320px-Flag_of_Mongolia.svg.png", + "number": "+976" + }, + { + "name": "Montenegro", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Flag_of_Montenegro.svg/320px-Flag_of_Montenegro.svg.png", + "number": "+382" + }, + { + "name": "Montserrat", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Flag_of_Montserrat.svg/320px-Flag_of_Montserrat.svg.png", + "number": "+1664" + }, + { + "name": "Morocco", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Flag_of_Morocco.svg/320px-Flag_of_Morocco.svg.png", + "number": "+212" + }, + { + "name": "Mozambique", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Flag_of_Mozambique.svg/320px-Flag_of_Mozambique.svg.png", + "number": "+258" + }, + { + "name": "Myanmar", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/Flag_of_Myanmar.svg/320px-Flag_of_Myanmar.svg.png", + "number": "+95" + }, + { + "name": "Namibia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Flag_of_Namibia.svg/320px-Flag_of_Namibia.svg.png", + "number": "+264" + }, + { + "name": "Nauru", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Flag_of_Nauru.svg/320px-Flag_of_Nauru.svg.png", + "number": "+674" + }, + { + "name": "Nepal", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Flag_of_Nepal.svg/320px-Flag_of_Nepal.svg.png", + "number": "+977" + }, + { + "name": "Netherlands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Flag_of_the_Netherlands.svg/320px-Flag_of_the_Netherlands.svg.png", + "number": "+31" + }, + { + "name": "New Caledonia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Flag_of_FLNKS.svg/320px-Flag_of_FLNKS.svg.png", + "number": "+687" + }, + { + "name": "New Zealand", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Flag_of_New_Zealand.svg/320px-Flag_of_New_Zealand.svg.png", + "number": "+64" + }, + { + "name": "Nicaragua", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Nicaragua.svg/320px-Flag_of_Nicaragua.svg.png", + "number": "+505" + }, + { + "name": "Niger", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/Flag_of_Niger.svg/320px-Flag_of_Niger.svg.png", + "number": "+227" + }, + { + "name": "Nigeria", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Flag_of_Nigeria.svg/320px-Flag_of_Nigeria.svg.png", + "number": "+234" + }, + { + "name": "Niue", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_Niue.svg/320px-Flag_of_Niue.svg.png", + "number": "+683" + }, + { + "name": "Norfolk Island", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Flag_of_Norfolk_Island.svg/320px-Flag_of_Norfolk_Island.svg.png", + "number": "+672" + }, + { + "name": "Northern Mariana Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Flag_of_the_Northern_Mariana_Islands.svg/320px-Flag_of_the_Northern_Mariana_Islands.svg.png", + "number": "+1 670" + }, + { + "name": "Norway", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Flag_of_Norway.svg/320px-Flag_of_Norway.svg.png", + "number": "+47" + }, + { + "name": "Oman", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Flag_of_Oman.svg/320px-Flag_of_Oman.svg.png", + "number": "+968" + }, + { + "name": "Pakistan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Flag_of_Pakistan.svg/320px-Flag_of_Pakistan.svg.png", + "number": "+92" + }, + { + "name": "Palau", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Flag_of_Palau.svg/320px-Flag_of_Palau.svg.png", + "number": "+680" + }, + { + "name": "Panama", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Flag_of_Panama.svg/320px-Flag_of_Panama.svg.png", + "number": "+507" + }, + { + "name": "Papua New Guinea", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Flag_of_Papua_New_Guinea.svg/320px-Flag_of_Papua_New_Guinea.svg.png", + "number": "+675" + }, + { + "name": "Paraguay", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/Flag_of_Paraguay.svg/320px-Flag_of_Paraguay.svg.png", + "number": "+595" + }, + { + "name": "Peru", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Flag_of_Peru.svg/320px-Flag_of_Peru.svg.png", + "number": "+51" + }, + { + "name": "Philippines", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Flag_of_the_Philippines.svg/320px-Flag_of_the_Philippines.svg.png", + "number": "+63" + }, + { + "name": "Pitcairn", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Flag_of_the_Pitcairn_Islands.svg/320px-Flag_of_the_Pitcairn_Islands.svg.png", + "number": "+870" + }, + { + "name": "Poland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Flag_of_Poland.svg/320px-Flag_of_Poland.svg.png", + "number": "+48" + }, + { + "name": "Portugal", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Portugal.svg/320px-Flag_of_Portugal.svg.png", + "number": "+351" + }, + { + "name": "Puerto Rico", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Flag_of_Puerto_Rico.svg/320px-Flag_of_Puerto_Rico.svg.png", + "number": "+1 939" + }, + { + "name": "Qatar", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Flag_of_Qatar.svg/320px-Flag_of_Qatar.svg.png", + "number": "+974" + }, + { + "name": "Réunion", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Flag_of_France.svg/320px-Flag_of_France.svg.png", + "number": "+262" + }, + { + "name": "Romania", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Flag_of_Romania.svg/320px-Flag_of_Romania.svg.png", + "number": "+40" + }, + { + "name": "Rwanda", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Flag_of_Rwanda.svg/320px-Flag_of_Rwanda.svg.png", + "number": "+250" + }, + { + "name": "Saint Kitts and Nevis", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Flag_of_Saint_Kitts_and_Nevis.svg/320px-Flag_of_Saint_Kitts_and_Nevis.svg.png", + "number": "+1 869" + }, + { + "name": "Saint Lucia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Flag_of_Saint_Lucia.svg/320px-Flag_of_Saint_Lucia.svg.png", + "number": "+1 758" + }, + { + "name": "Saint Pierre and Miquelon", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Flag_of_Saint-Pierre_and_Miquelon.svg/320px-Flag_of_Saint-Pierre_and_Miquelon.svg.png", + "number": "+508" + }, + { + "name": "Saint Vincent and the Grenadines", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Flag_of_Saint_Vincent_and_the_Grenadines.svg/320px-Flag_of_Saint_Vincent_and_the_Grenadines.svg.png", + "number": "+1 784" + }, + { + "name": "Samoa", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Flag_of_Samoa.svg/320px-Flag_of_Samoa.svg.png", + "number": "+685" + }, + { + "name": "San Marino", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Flag_of_San_Marino.svg/320px-Flag_of_San_Marino.svg.png", + "number": "+378" + }, + { + "name": "Sao Tome and Principe", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Flag_of_Sao_Tome_and_Principe.svg/320px-Flag_of_Sao_Tome_and_Principe.svg.png", + "number": "+239" + }, + { + "name": "Saudi Arabia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Flag_of_Saudi_Arabia.svg/320px-Flag_of_Saudi_Arabia.svg.png", + "number": "+966" + }, + { + "name": "Senegal", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Flag_of_Senegal.svg/320px-Flag_of_Senegal.svg.png", + "number": "+221" + }, + { + "name": "Serbia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Flag_of_Serbia.svg/320px-Flag_of_Serbia.svg.png", + "number": "+381" + }, + { + "name": "Seychelles", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Flag_of_Seychelles.svg/320px-Flag_of_Seychelles.svg.png", + "number": "+248" + }, + { + "name": "Sierra Leone", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Flag_of_Sierra_Leone.svg/320px-Flag_of_Sierra_Leone.svg.png", + "number": "+232" + }, + { + "name": "Singapore", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Flag_of_Singapore.svg/320px-Flag_of_Singapore.svg.png", + "number": "+65" + }, + { + "name": "Slovakia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Flag_of_Slovakia.svg/320px-Flag_of_Slovakia.svg.png", + "number": "+421" + }, + { + "name": "Slovenia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/Flag_of_Slovenia.svg/320px-Flag_of_Slovenia.svg.png", + "number": "+386" + }, + { + "name": "Solomon Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Flag_of_the_Solomon_Islands.svg/320px-Flag_of_the_Solomon_Islands.svg.png", + "number": "+677" + }, + { + "name": "Somalia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Flag_of_Somalia.svg/320px-Flag_of_Somalia.svg.png", + "number": "+252" + }, + { + "name": "South Africa", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Flag_of_South_Africa.svg/320px-Flag_of_South_Africa.svg.png", + "number": "+27" + }, + { + "name": "South Georgia and the South Sandwich Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Flag_of_South_Georgia_and_the_South_Sandwich_Islands.svg/320px-Flag_of_South_Georgia_and_the_South_Sandwich_Islands.svg.png", + "number": "+500" + }, + { + "name": "Spain", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Flag_of_Spain.svg/320px-Flag_of_Spain.svg.png", + "number": "+34" + }, + { + "name": "Sri Lanka", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Flag_of_Sri_Lanka.svg/320px-Flag_of_Sri_Lanka.svg.png", + "number": "+94" + }, + { + "name": "Sudan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_Sudan.svg/320px-Flag_of_Sudan.svg.png", + "number": "+249" + }, + { + "name": "Suriname", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Flag_of_Suriname.svg/320px-Flag_of_Suriname.svg.png", + "number": "+597" + }, + { + "name": "Swaziland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Flag_of_Eswatini.svg/320px-Flag_of_Eswatini.svg.png", + "number": "+268" + }, + { + "name": "Sweden", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Flag_of_Sweden.svg/320px-Flag_of_Sweden.svg.png", + "number": "+46" + }, + { + "name": "Switzerland", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Flag_of_Switzerland.svg/240px-Flag_of_Switzerland.svg.png", + "number": "+41" + }, + { + "name": "Syrian Arab Republic", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Flag_of_Syria.svg/320px-Flag_of_Syria.svg.png", + "number": "+963" + }, + { + "name": "Taiwan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Flag_of_the_Republic_of_China.svg/320px-Flag_of_the_Republic_of_China.svg.png", + "number": "+886" + }, + { + "name": "Tajikistan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Flag_of_Tajikistan.svg/320px-Flag_of_Tajikistan.svg.png", + "number": "+992" + }, + { + "name": "Thailand", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Flag_of_Thailand.svg/320px-Flag_of_Thailand.svg.png", + "number": "+66" + }, + { + "name": "Timor-Leste", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Flag_of_East_Timor.svg/320px-Flag_of_East_Timor.svg.png", + "number": "+670" + }, + { + "name": "Togo", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Flag_of_Togo.svg/320px-Flag_of_Togo.svg.png", + "number": "+228" + }, + { + "name": "Tokelau", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Flag_of_Tokelau.svg/320px-Flag_of_Tokelau.svg.png", + "number": "+690" + }, + { + "name": "Tonga", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Flag_of_Tonga.svg/320px-Flag_of_Tonga.svg.png", + "number": "+676" + }, + { + "name": "Trinidad and Tobago", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Flag_of_Trinidad_and_Tobago.svg/320px-Flag_of_Trinidad_and_Tobago.svg.png", + "number": "+1 868" + }, + { + "name": "Tunisia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Flag_of_Tunisia.svg/320px-Flag_of_Tunisia.svg.png", + "number": "+216" + }, + { + "name": "Turkey", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Flag_of_Turkey.svg/320px-Flag_of_Turkey.svg.png", + "number": "+90" + }, + { + "name": "Turkmenistan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Flag_of_Turkmenistan.svg/320px-Flag_of_Turkmenistan.svg.png", + "number": "+993" + }, + { + "name": "Turks and Caicos Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Flag_of_the_Turks_and_Caicos_Islands.svg/320px-Flag_of_the_Turks_and_Caicos_Islands.svg.png", + "number": "+1 649" + }, + { + "name": "Tuvalu", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Flag_of_Tuvalu.svg/320px-Flag_of_Tuvalu.svg.png", + "number": "+688" + }, + { + "name": "Uganda", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Flag_of_Uganda.svg/320px-Flag_of_Uganda.svg.png", + "number": "+256" + }, + { + "name": "Ukraine", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Flag_of_Ukraine.svg/320px-Flag_of_Ukraine.svg.png", + "number": "+380" + }, + { + "name": "United Arab Emirates", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_United_Arab_Emirates.svg/320px-Flag_of_the_United_Arab_Emirates.svg.png", + "number": "+971" + }, + { + "name": "United Kingdom", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Flag_of_the_United_Kingdom.svg/320px-Flag_of_the_United_Kingdom.svg.png", + "number": "+44" + }, + { + "name": "United States", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Flag_of_the_United_States.svg/320px-Flag_of_the_United_States.svg.png", + "number": "+1" + }, + { + "name": "United States Minor Outlying Islands", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Flag_of_the_United_States.svg/320px-Flag_of_the_United_States.svg.png", + "number": "+1581" + }, + { + "name": "Uruguay", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Flag_of_Uruguay.svg/320px-Flag_of_Uruguay.svg.png", + "number": "+598" + }, + { + "name": "Uzbekistan", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Flag_of_Uzbekistan.svg/320px-Flag_of_Uzbekistan.svg.png", + "number": "+998" + }, + { + "name": "Vanuatu", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Flag_of_Vanuatu.svg/320px-Flag_of_Vanuatu.svg.png", + "number": "+678" + }, + { + "name": "Viet Nam", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/21/Flag_of_Vietnam.svg/320px-Flag_of_Vietnam.svg.png", + "number": "+84" + }, + { + "name": "Wallis and Futuna", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Flag_of_Wallis_and_Futuna.svg/320px-Flag_of_Wallis_and_Futuna.svg.png", + "number": "+681" + }, + { + "name": "Yemen", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Flag_of_Yemen.svg/320px-Flag_of_Yemen.svg.png", + "number": "+967" + }, + { + "name": "Zambia", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Flag_of_Zambia.svg/320px-Flag_of_Zambia.svg.png", + "number": "+260" + }, + { + "name": "Zimbabwe", + "flag": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Flag_of_Zimbabwe.svg/320px-Flag_of_Zimbabwe.svg.png", + "number": "+263" + } + ] diff --git a/SampleApp/assets/icon.png b/SampleApp/assets/icon.png new file mode 100644 index 00000000..7f5e01c5 Binary files /dev/null and b/SampleApp/assets/icon.png differ diff --git a/SampleApp/babel.config.js b/SampleApp/babel.config.js new file mode 100644 index 00000000..2900afe9 --- /dev/null +++ b/SampleApp/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/SampleApp/index.android.js b/SampleApp/index.android.js deleted file mode 100644 index 8676c06f..00000000 --- a/SampleApp/index.android.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -import { AppRegistry } from 'react-native'; -import SampleApp from './app' - -AppRegistry.registerComponent('SampleApp', () => SampleApp); \ No newline at end of file diff --git a/SampleApp/index.ios.js b/SampleApp/index.ios.js deleted file mode 100644 index 8676c06f..00000000 --- a/SampleApp/index.ios.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -import { AppRegistry } from 'react-native'; -import SampleApp from './app' - -AppRegistry.registerComponent('SampleApp', () => SampleApp); \ No newline at end of file diff --git a/SampleApp/ios/SampleApp.xcodeproj/project.pbxproj b/SampleApp/ios/SampleApp.xcodeproj/project.pbxproj deleted file mode 100644 index ef7251b1..00000000 --- a/SampleApp/ios/SampleApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,761 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; - 00E356F31AD99517003FC87E /* SampleAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* SampleAppTests.m */; }; - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTActionSheet; - }; - 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTGeolocation; - }; - 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5115D1A9E6B3D00147676; - remoteInfo = RCTImage; - }; - 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B511DB1A9E6C8500147676; - remoteInfo = RCTNetwork; - }; - 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; - remoteInfo = RCTVibration; - }; - 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13B07F861A680F5B00A75B9A; - remoteInfo = SampleApp; - }; - 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTSettings; - }; - 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3C86DF461ADF2C930047B81A; - remoteInfo = RCTWebSocket; - }; - 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; - remoteInfo = React; - }; - 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTLinking; - }; - 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5119B1A9E6C1200147676; - remoteInfo = RCTText; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = main.jsbundle; sourceTree = ""; }; - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; - 00E356EE1AD99517003FC87E /* SampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 00E356F21AD99517003FC87E /* SampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppTests.m; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = ""; }; - 13B07F961A680F5B00A75B9A /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = SampleApp/AppDelegate.h; sourceTree = ""; }; - 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = SampleApp/AppDelegate.m; sourceTree = ""; }; - 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = SampleApp/Images.xcassets; sourceTree = ""; }; - 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = SampleApp/Info.plist; sourceTree = ""; }; - 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = SampleApp/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../node_modules/react-native/React/React.xcodeproj; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../node_modules/react-native/Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 00E356EB1AD99517003FC87E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 00C302A81ABCB8CE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302B61ABCB90400DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302BC1ABCB91800DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302D41ABCB9D200DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302E01ABCB9EE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, - ); - name = Products; - sourceTree = ""; - }; - 00E356EF1AD99517003FC87E /* SampleAppTests */ = { - isa = PBXGroup; - children = ( - 00E356F21AD99517003FC87E /* SampleAppTests.m */, - 00E356F01AD99517003FC87E /* Supporting Files */, - ); - path = SampleAppTests; - sourceTree = ""; - }; - 00E356F01AD99517003FC87E /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 00E356F11AD99517003FC87E /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 139105B71AF99BAD00B5F7CC /* Products */ = { - isa = PBXGroup; - children = ( - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, - ); - name = Products; - sourceTree = ""; - }; - 139FDEE71B06529A00C62182 /* Products */ = { - isa = PBXGroup; - children = ( - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, - ); - name = Products; - sourceTree = ""; - }; - 13B07FAE1A68108700A75B9A /* SampleApp */ = { - isa = PBXGroup; - children = ( - 008F07F21AC5B25A0029DE68 /* main.jsbundle */, - 13B07FAF1A68108700A75B9A /* AppDelegate.h */, - 13B07FB01A68108700A75B9A /* AppDelegate.m */, - 13B07FB51A68108700A75B9A /* Images.xcassets */, - 13B07FB61A68108700A75B9A /* Info.plist */, - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, - 13B07FB71A68108700A75B9A /* main.m */, - ); - name = SampleApp; - sourceTree = ""; - }; - 146834001AC3E56700842450 /* Products */ = { - isa = PBXGroup; - children = ( - 146834041AC3E56700842450 /* libReact.a */, - ); - name = Products; - sourceTree = ""; - }; - 78C398B11ACF4ADC00677621 /* Products */ = { - isa = PBXGroup; - children = ( - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, - ); - name = Products; - sourceTree = ""; - }; - 832341AE1AAA6A7D00B99B32 /* Libraries */ = { - isa = PBXGroup; - children = ( - 146833FF1AC3E56700842450 /* React.xcodeproj */, - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, - ); - name = Libraries; - sourceTree = ""; - }; - 832341B11AAA6A8300B99B32 /* Products */ = { - isa = PBXGroup; - children = ( - 832341B51AAA6A8300B99B32 /* libRCTText.a */, - ); - name = Products; - sourceTree = ""; - }; - 83CBB9F61A601CBA00E9B192 = { - isa = PBXGroup; - children = ( - 13B07FAE1A68108700A75B9A /* SampleApp */, - 832341AE1AAA6A7D00B99B32 /* Libraries */, - 00E356EF1AD99517003FC87E /* SampleAppTests */, - 83CBBA001A601CBA00E9B192 /* Products */, - ); - indentWidth = 2; - sourceTree = ""; - tabWidth = 2; - }; - 83CBBA001A601CBA00E9B192 /* Products */ = { - isa = PBXGroup; - children = ( - 13B07F961A680F5B00A75B9A /* SampleApp.app */, - 00E356EE1AD99517003FC87E /* SampleAppTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* SampleAppTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "SampleAppTests" */; - buildPhases = ( - 00E356EA1AD99517003FC87E /* Sources */, - 00E356EB1AD99517003FC87E /* Frameworks */, - 00E356EC1AD99517003FC87E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00E356F51AD99517003FC87E /* PBXTargetDependency */, - ); - name = SampleAppTests; - productName = SampleAppTests; - productReference = 00E356EE1AD99517003FC87E /* SampleAppTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13B07F861A680F5B00A75B9A /* SampleApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "SampleApp" */; - buildPhases = ( - 13B07F871A680F5B00A75B9A /* Sources */, - 13B07F8C1A680F5B00A75B9A /* Frameworks */, - 13B07F8E1A680F5B00A75B9A /* Resources */, - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SampleApp; - productName = "Hello World"; - productReference = 13B07F961A680F5B00A75B9A /* SampleApp.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 83CBB9F71A601CBA00E9B192 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0610; - ORGANIZATIONNAME = Facebook; - TargetAttributes = { - 00E356ED1AD99517003FC87E = { - CreatedOnToolsVersion = 6.2; - TestTargetID = 13B07F861A680F5B00A75B9A; - }; - }; - }; - buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "SampleApp" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 83CBB9F61A601CBA00E9B192; - productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; - ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - }, - { - ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; - ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - }, - { - ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; - ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - }, - { - ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; - ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - }, - { - ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; - ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - }, - { - ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; - ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - }, - { - ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; - ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - }, - { - ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; - ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - }, - { - ProductGroup = 139FDEE71B06529A00C62182 /* Products */; - ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - }, - { - ProductGroup = 146834001AC3E56700842450 /* Products */; - ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 13B07F861A680F5B00A75B9A /* SampleApp */, - 00E356ED1AD99517003FC87E /* SampleAppTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTActionSheet.a; - remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTGeolocation.a; - remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTImage.a; - remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTNetwork.a; - remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTVibration.a; - remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTSettings.a; - remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTWebSocket.a; - remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 146834041AC3E56700842450 /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTLinking.a; - remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTText.a; - remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 00E356EC1AD99517003FC87E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8E1A680F5B00A75B9A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Bundle React Native code and images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; - showEnvVarsInLog = 1; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 00E356EA1AD99517003FC87E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00E356F31AD99517003FC87E /* SampleAppTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F871A680F5B00A75B9A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, - 13B07FC11A68108700A75B9A /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13B07F861A680F5B00A75B9A /* SampleApp */; - targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 13B07FB21A68108700A75B9A /* Base */, - ); - name = LaunchScreen.xib; - path = SampleApp; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = SampleAppTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleApp.app/SampleApp"; - }; - name = Debug; - }; - 00E356F71AD99517003FC87E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = SampleAppTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleApp.app/SampleApp"; - }; - name = Release; - }; - 13B07F941A680F5B00A75B9A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEAD_CODE_STRIPPING = NO; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", - ); - INFOPLIST_FILE = "SampleApp/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = SampleApp; - }; - name = Debug; - }; - 13B07F951A680F5B00A75B9A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", - ); - INFOPLIST_FILE = "SampleApp/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_NAME = SampleApp; - }; - name = Release; - }; - 83CBBA201A601CBA00E9B192 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 83CBBA211A601CBA00E9B192 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", - ); - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "SampleAppTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug */, - 00E356F71AD99517003FC87E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "SampleApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13B07F941A680F5B00A75B9A /* Debug */, - 13B07F951A680F5B00A75B9A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "SampleApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83CBBA201A601CBA00E9B192 /* Debug */, - 83CBBA211A601CBA00E9B192 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; -} diff --git a/SampleApp/ios/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme b/SampleApp/ios/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme deleted file mode 100644 index 7dcff488..00000000 --- a/SampleApp/ios/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SampleApp/ios/SampleApp/AppDelegate.h b/SampleApp/ios/SampleApp/AppDelegate.h deleted file mode 100644 index a9654d5e..00000000 --- a/SampleApp/ios/SampleApp/AppDelegate.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -@interface AppDelegate : UIResponder - -@property (nonatomic, strong) UIWindow *window; - -@end diff --git a/SampleApp/ios/SampleApp/AppDelegate.m b/SampleApp/ios/SampleApp/AppDelegate.m deleted file mode 100644 index 77c16a21..00000000 --- a/SampleApp/ios/SampleApp/AppDelegate.m +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "AppDelegate.h" - -#import "RCTRootView.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - NSURL *jsCodeLocation; - - /** - * Loading JavaScript code - uncomment the one you want. - * - * OPTION 1 - * Load from development server. Start the server from the repository root: - * - * $ npm start - * - * To run on device, change `localhost` to the IP address of your computer - * (you can get this by typing `ifconfig` into the terminal and selecting the - * `inet` value under `en0:`) and make sure your computer and iOS device are - * on the same Wi-Fi network. - */ - - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; - - /** - * OPTION 2 - * Load from pre-bundled file on disk. The static bundle is automatically - * generated by the "Bundle React Native code and images" build step when - * running the project on an actual device or running the project on the - * simulator in the "Release" build configuration. - */ - -// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; - - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation - moduleName:@"SampleApp" - initialProperties:nil - launchOptions:launchOptions]; - rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; -} - -@end diff --git a/SampleApp/ios/SampleApp/Base.lproj/LaunchScreen.xib b/SampleApp/ios/SampleApp/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 3b8cd49b..00000000 --- a/SampleApp/ios/SampleApp/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SampleApp/ios/SampleApp/Images.xcassets/AppIcon.appiconset/Contents.json b/SampleApp/ios/SampleApp/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 118c98f7..00000000 --- a/SampleApp/ios/SampleApp/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/SampleApp/ios/SampleApp/Info.plist b/SampleApp/ios/SampleApp/Info.plist deleted file mode 100644 index 91963b26..00000000 --- a/SampleApp/ios/SampleApp/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - NSLocationWhenInUseUsageDescription - - NSAppTransportSecurity - - - NSAllowsArbitraryLoads - - - - diff --git a/SampleApp/ios/SampleApp/main.m b/SampleApp/ios/SampleApp/main.m deleted file mode 100644 index 3d767fcb..00000000 --- a/SampleApp/ios/SampleApp/main.m +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/SampleApp/ios/SampleAppTests/Info.plist b/SampleApp/ios/SampleAppTests/Info.plist deleted file mode 100644 index 886825cc..00000000 --- a/SampleApp/ios/SampleAppTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/SampleApp/ios/SampleAppTests/SampleAppTests.m b/SampleApp/ios/SampleAppTests/SampleAppTests.m deleted file mode 100644 index 5d2dfcb6..00000000 --- a/SampleApp/ios/SampleAppTests/SampleAppTests.m +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import -#import - -#import "RCTLog.h" -#import "RCTRootView.h" - -#define TIMEOUT_SECONDS 600 -#define TEXT_TO_LOOK_FOR @"Welcome to React Native!" - -@interface SampleAppTests : XCTestCase - -@end - -@implementation SampleAppTests - -- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test -{ - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; - } - } - return NO; -} - -- (void)testRendersWelcomeScreen -{ - UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; - - __block NSString *redboxError = nil; - RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { - if (level >= RCTLogLevelError) { - redboxError = message; - } - }); - - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - - foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } - - RCTSetLogFunction(RCTDefaultLogFunction); - - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); -} - - -@end diff --git a/SampleApp/nodemon.json b/SampleApp/nodemon.json index 37860d64..09e30327 100644 --- a/SampleApp/nodemon.json +++ b/SampleApp/nodemon.json @@ -9,8 +9,8 @@ "watch": [ ".." ], - "ext": "js json png jpeg jpg", + "ext": "js,ts,json,png,jpeg,jpg", "events": { - "restart": "cp -rf ../*.{js,json} node_modules/react-native-modal-picker/" + "restart": "cp -f ../*.js ../*.json ../*.ts node_modules/react-native-modal-selector/" } -} \ No newline at end of file +} diff --git a/SampleApp/package.json b/SampleApp/package.json index c99a7e0d..4d2c2eac 100644 --- a/SampleApp/package.json +++ b/SampleApp/package.json @@ -1,13 +1,35 @@ { - "name": "SampleApp", - "version": "0.0.2", - "private": true, + "main": "node_modules/expo/AppEntry.js", "scripts": { - "start": "react-native run-ios" + "start": "expo start", + "postinstall": "npm run cp", + "cp": "cpx \"../*.{js,ts}\" node_modules/react-native-modal-selector/ -u", + "nodemon": "nodemon nodemon.json", + "android": "expo start --android", + "ios": "expo start --ios", + "web": "expo start --web", + "eject": "expo eject" }, "dependencies": { - "react": "^15.1.0", - "react-native": "^0.27.2", - "react-native-modal-picker": "file:../" - } + "expo": "~45.0.0", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-native": "0.68.2", + "react-native-modal-selector": "https://github.com/peacechen/react-native-modal-selector.git", + "react-native-web": "0.17.7" + }, + "devDependencies": { + "@babel/core": "^7.12.9", + "@deboxsoft/cpx": "^1.5.0", + "@types/react": "17", + "@types/react-native": "0.67.9", + "babel-preset-expo": "9.1.0", + "nodemon": "2.0.16", + "typescript": "4.7.4" + }, + "resolutions": { + "@types/react": "17.0.2", + "@types/react-dom": "17.0.2" + }, + "private": true } diff --git a/SampleApp/tsconfig.json b/SampleApp/tsconfig.json new file mode 100644 index 00000000..c007e280 --- /dev/null +++ b/SampleApp/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "jsx": "react-native", + "target": "esnext", + "lib": [ + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "moduleResolution": "node" + }, + "extends": "expo/tsconfig.base" +} diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 00000000..f58c75e3 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,384 @@ +import React from 'react'; +import { ViewStyle, TextStyle, FlatListProps } from 'react-native'; + +export interface IOption { + key: React.Key; + label?: string; + section?: boolean; + testID?: string; + accessibilityLabel?: string; + component?: React.ReactNode; + [key:string]: any; +} + +type AnimationType = 'none' | 'slide' | 'fade'; +type OrientationType = 'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right'; +type ListType = 'SCROLLVIEW' | 'FLATLIST'; + +export type ModalSelectorProps = IModalSelectorProps; + +interface IModalSelectorProps { + /** + * Array of objects with a unique key and label to select in the modal + * Optional component overrides label text + * + * Default is `[]` + */ + data: TOption[], + + /** + * List to be render inside modal can be Scrollview or Flatlist + * + * Default is `'SCROLLVIEW'` + */ + listType?: ListType; + + /** + * Callback function, when the users has selected an option + * + * Default is `() => {}` + */ + onChange?: (option: TOption) => void; + + /** + * Callback function, when modal is opening + * + * Default is `() => {}` + */ + onModalOpen?: () => void; + + /** + * Callback function, when modal is closing + * + * Default is `() => {}` + */ + onModalClose?: (option: TOption) => void; + + /** + * Extract the key from the data item + * + * Default is `(data) => data.key` + */ + keyExtractor?: (option: TOption) => React.Key; + + /** + * Extract the label from the data item + * + * Default is `(data) => data.label` + */ + labelExtractor?: (option: TOption) => string; + + /** + * Extract the component from the data item + * + * Default is `(data) => data.component` + */ + componentExtractor?: (option: TOption) => React.ReactNode; + + /** + * Control open/close state of modal + * + * Default is `false` + */ + visible?: boolean; + + /** + * Control if modal closes on select + * + * Default is `true` + */ + closeOnChange?: boolean; + + /** + * Text that is initially shown on the button + * + * Default is `'Select me!'` + */ + initValue?: string; + + /** + * Text of the cancel button + * + * Default is `'cancel'` + */ + cancelText?: string; + + /** + * Type of animation to be used to show the modal. + * + * Default is `'slide'` + */ + animationType?: AnimationType; + + /** + * Style definitions for the root element + */ + style?: ViewStyle; + + /** + * Style definitions for the select element (available in default mode only!) + * NOTE: Due to breaking changes in React Native, RN < 0.39.0 should pass flex:1 explicitly to selectStyle as a prop + * + * Default is `{}` + */ + selectStyle?: ViewStyle; + + /** + * Style definitions for the select element (available in default mode only!) + * + * Default is `{}` + */ + selectTextStyle?: TextStyle; + + /** + * Style definitions for the option element + * + * Default is `{}` + */ + optionStyle?: ViewStyle; + + /** + * Style definitions for the option text element + * + * Default is `{}` + */ + optionTextStyle?: TextStyle; + + /** + * Style definitions for the option container element + * + * Default is `{}` + */ + optionContainerStyle?: ViewStyle; + + /** + * Style definitions for the section element + * + * Default is `{}` + */ + sectionStyle?: ViewStyle; + + /** + * Style definitions for the children container view + * + * Default is `{}` + */ + childrenContainerStyle?: ViewStyle; + + /** + * Style definitions for the touchable element + * + * Default is `{}` + */ + touchableStyle?: ViewStyle; + + /** + * Opacity for the touchable element on touch + * + * Default is `0.2` + */ + touchableActiveOpacity?: number; + + /** + * Style definitions for the select text element + * + * Default is `{}` + */ + sectionTextStyle?: TextStyle; + + /** + * Style definitions for the currently selected text element + * + * Default is `{}` + */ + selectedItemTextStyle?: TextStyle; + + /** + * Style definitions for the cancel container + * + * Default is `{}` + */ + cancelContainerStyle?: ViewStyle; + + /** + * Style definitions for the cancel element + * + * Default is `{}` + */ + cancelStyle?: ViewStyle; + + /** + * Style definitions for the cancel text element + * + * Default is `{}` + */ + cancelTextStyle?: TextStyle; + + /** + * Style definitions for the overlay background element + * RN <= 0.41 should override this with pixel value for padding + * + * Default is `{ flex: 1, padding: '5%', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.7)' }` + */ + overlayStyle?: ViewStyle; + + /** + * Style definitions for the initValue text element + * + * Default is `{}` + */ + initValueTextStyle?: TextStyle; + + /** + * Disables opening of the modal + * + * Default is `false` + */ + disabled?: boolean; + + /** + * Orientations the modal supports + * + * Default is `['portrait', 'landscape']` + */ + supportedOrientations?: OrientationType[]; + + /** + * Passed to underlying ScrollView + * + * Default is `'always'` + */ + keyboardShouldPersistTaps?: string | boolean; + + /** + * true makes the modal close when the overlay is pressed + * + * Default is `false` + */ + backdropPressToClose?: boolean; + + /** + * true enables accessibility for the open button container + * Note: if false be sure to define accessibility props directly in the wrapped component + * + * Default is `false` + */ + openButtonContainerAccessible?: boolean; + + /** + * true enables accessibility for data items. + * Note: data items should have an accessibilityLabel property if this is enabled + * + * Default is `false` + */ + listItemAccessible?: boolean; + + /** + * true enables accessibility for cancel button. + * + * Default is `false` + */ + cancelButtonAccessible?: boolean; + + /** + * true enables accessibility for the scroll view. + * Only enable this if you don't want to interact with individual data items. + * + * Default is `false` + */ + scrollViewAccessible?: boolean; + + /** + * Accessibility label for the modal ScrollView + */ + scrollViewAccessibilityLabel?: string; + + /** + * Accessibility label for the cancel button + */ + cancelButtonAccessibilityLabel?: string; + + /** + * props to pass through to the container View and each option TouchableOpacity (e.g. testID for testing) + * + * Default is `{}` + */ + passThruProps?: object; + + /** + * props to pass through to the select text component + * + * Default is `{}` + */ + selectTextPassThruProps?: object; + + /** + * props to pass through to the options text components in the modal + * + * Default is `{}` + */ + optionTextPassThruProps?: object; + + /** + * props to pass through to the cancel text components in the modal + * + * Default is `{}` + */ + cancelTextPassThruProps?: object; + + /** + * props to pass through to the internal ScrollView + * + * Default is `{}` + */ + scrollViewPassThruProps?: object; + + /** + * How far touch can stray away from touchable that opens modal + * + * Default is `{}` + */ + modalOpenerHitSlop?: object; + + /** + * Render a custom node instead of the built-in select box + */ + customSelector?: React.ReactNode; + + /** + * Key of the item to be initially selected + * + * Default is `''` + */ + selectedKey?: React.Key; + + /** + * enables short press. This is regular touch behavior. + */ + enableShortPress?: boolean; + + /** + * enables long press. When true + */ + enableLongPress?: boolean; + + /** + * This prefixes each selectable option's testID prop if no testID keys are provided in data array objects. + * Default for each option's testID: 'default-' + */ + optionsTestIDPrefix?: string; + + /** + * Render a header above the list + */ + header?: React.ReactNode; + +} + +type FlatListCustom = Omit, "renderItem"> + +export default class ModalSelector extends React.Component & FlatListCustom, any> { + open: (args0?: {longPress?: boolean, [args1:string]: any})=> void; + close: (item: TOption) => void; + getSelectedItem: () => TOption; +} diff --git a/index.js b/index.js index d65bf4c0..9b8adf61 100644 --- a/index.js +++ b/index.js @@ -1,161 +1,366 @@ 'use strict'; -import React,{ - PropTypes -} from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { View, - StyleSheet, - Dimensions, Modal, Text, + FlatList, ScrollView, TouchableOpacity, - Platform + TouchableWithoutFeedback, } from 'react-native'; import styles from './style'; -import BaseComponent from './BaseComponent'; let componentIndex = 0; const propTypes = { - data: PropTypes.array, - onChange: PropTypes.func, - initValue: PropTypes.string, - style: View.propTypes.style, - selectStyle: View.propTypes.style, - optionStyle: View.propTypes.style, - optionTextStyle: Text.propTypes.style, - sectionStyle: View.propTypes.style, - sectionTextStyle: Text.propTypes.style, - cancelStyle: View.propTypes.style, - cancelTextStyle: Text.propTypes.style, - overlayStyle: View.propTypes.style, - cancelText: PropTypes.string + data: PropTypes.array, + onChange: PropTypes.func, + onModalOpen: PropTypes.func, + onModalClose: PropTypes.func, + keyExtractor: PropTypes.func, + labelExtractor: PropTypes.func, + visible: PropTypes.bool, + closeOnChange: PropTypes.bool, + initValue: PropTypes.string, + listType: PropTypes.oneOf(['SCROLLVIEW', 'FLATLIST']), + animationType: PropTypes.oneOf(['none', 'slide', 'fade']), + style: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + selectStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + selectTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + optionStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + optionTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + optionContainerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + sectionStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + childrenContainerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + touchableStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + touchableActiveOpacity: PropTypes.number, + sectionTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + selectedItemTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + cancelContainerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + cancelStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + cancelTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + overlayStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + initValueTextStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + cancelText: PropTypes.string, + disabled: PropTypes.bool, + supportedOrientations: PropTypes.arrayOf( + PropTypes.oneOf([ + 'portrait', + 'portrait-upside-down', + 'landscape', + 'landscape-left', + 'landscape-right', + ]), + ), + keyboardShouldPersistTaps: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + backdropPressToClose: PropTypes.bool, + openButtonContainerAccessible: PropTypes.bool, + listItemAccessible: PropTypes.bool, + cancelButtonAccessible: PropTypes.bool, + scrollViewAccessible: PropTypes.bool, + scrollViewAccessibilityLabel: PropTypes.string, + cancelButtonAccessibilityLabel: PropTypes.string, + passThruProps: PropTypes.object, + selectTextPassThruProps: PropTypes.object, + optionTextPassThruProps: PropTypes.object, + cancelTextPassThruProps: PropTypes.object, + scrollViewPassThruProps: PropTypes.object, + modalOpenerHitSlop: PropTypes.object, + customSelector: PropTypes.node, + selectedKey: PropTypes.any, + enableShortPress: PropTypes.bool, + enableLongPress: PropTypes.bool, + optionsTestIDPrefix: PropTypes.string, + header: PropTypes.node, + onEndReached: PropTypes.func, }; const defaultProps = { - data: [], - onChange: ()=> {}, - initValue: 'Select me!', - style: {}, - selectStyle: {}, - optionStyle: {}, - optionTextStyle: {}, - sectionStyle: {}, - sectionTextStyle: {}, - cancelStyle: {}, - cancelTextStyle: {}, - overlayStyle: {}, - cancelText: 'cancel' + data: [], + onChange: () => {}, + onModalOpen: () => {}, + onModalClose: () => {}, + keyExtractor: (item) => item && item.key, + labelExtractor: (item) => item && item.label, + componentExtractor: (item) => item && item.component, + listType: 'SCROLLVIEW', + visible: false, + closeOnChange: true, + initValue: 'Select me!', + animationType: 'slide', + style: {}, + selectStyle: {}, + selectTextStyle: {}, + optionStyle: {}, + optionTextStyle: {}, + optionContainerStyle: {}, + sectionStyle: {}, + childrenContainerStyle: {}, + touchableStyle: {}, + touchableActiveOpacity: 0.2, + sectionTextStyle: {}, + selectedItemTextStyle: {}, + cancelContainerStyle: {}, + cancelStyle: {}, + cancelTextStyle: {}, + overlayStyle: {}, + initValueTextStyle: {}, + cancelText: 'cancel', + disabled: false, + supportedOrientations: ['portrait', 'landscape'], + keyboardShouldPersistTaps: 'always', + backdropPressToClose: false, + openButtonContainerAccessible: false, + listItemAccessible: false, + cancelButtonAccessible: false, + scrollViewAccessible: false, + scrollViewAccessibilityLabel: "", + cancelButtonAccessibilityLabel: "", + passThruProps: {}, + selectTextPassThruProps: {}, + optionTextPassThruProps: {}, + cancelTextPassThruProps: {}, + scrollViewPassThruProps: {}, + modalOpenerHitSlop: {top: 0, bottom: 0, left: 0, right: 0}, + customSelector: undefined, + selectedKey: '', + enableShortPress: true, + enableLongPress: false, + optionsTestIDPrefix: 'default', + header: undefined, + onEndReached: undefined, }; -export default class ModalPicker extends BaseComponent { - - constructor() { - - super(); - - this._bind( - 'onChange', - 'open', - 'close', - 'renderChildren' - ); +export default class ModalSelector extends React.Component { + constructor(props) { + super(props); + let selectedItem = this.validateSelectedKey(props.selectedKey); this.state = { - animationType: 'slide', - modalVisible: false, - transparent: false, - selected: 'please select' + modalVisible: props.visible, + selected: selectedItem.label, + cancelText: props.cancelText, + changedItem: selectedItem.key, }; } - componentDidMount() { - this.setState({selected: this.props.initValue}); - this.setState({cancelText: this.props.cancelText}); + componentDidUpdate(prevProps, prevState) { + let newState = {}; + let doUpdate = false; + if (prevProps.initValue !== this.props.initValue) { + newState.selected = this.props.initValue; + doUpdate = true; + } + if (prevProps.visible !== this.props.visible) { + newState.modalVisible = this.props.visible; + doUpdate = true; + } + if (prevProps.selectedKey !== this.props.selectedKey || prevProps.data !== this.props.data) { + let selectedItem = this.validateSelectedKey(this.props.selectedKey); + newState.selected = selectedItem.label; + newState.changedItem = selectedItem.key; + doUpdate = true; + } + if (doUpdate) { + this.setState(newState); + } } - componentWillReceiveProps(nextProps) { - if (nextProps.initValue != this.props.initValue) { - this.setState({selected: nextProps.initValue}); - } + validateSelectedKey = (key) => { + let selectedItem = this.props.data.filter((item) => this.props.keyExtractor(item) === key); + let selectedLabel = selectedItem.length > 0 ? this.props.labelExtractor(selectedItem[0]) : this.props.initValue; + let selectedKey = selectedItem.length > 0 ? key : undefined; + return {label: selectedLabel, key: selectedKey} } - onChange(item) { + onChange = (item) => { + const key = this.props.keyExtractor(item); + if (!item || key == null) { // == coercion + return; + } this.props.onChange(item); - this.setState({selected: item.label}); - this.close(); + this.setState({ selected: this.props.labelExtractor(item), changedItem: item }, () => { + if (this.props.closeOnChange) + this.close(item); + }); + } + + getSelectedItem() { + return this.state.changedItem; } - close() { - this.setState({ - modalVisible: false - }); + close = (item) => { + this.props.onModalClose(item); + this.setState({ + modalVisible: false, + }); } - open() { - this.setState({ - modalVisible: true - }); + open = (params = {}) => { + if (!params.longPress && !this.props.enableShortPress) { + return; + } + if (params.longPress && !this.props.enableLongPress) { + return; + } + this.props.onModalOpen(params); + this.setState({ + modalVisible: true, + changedItem: undefined, + }); } - renderSection(section) { + renderSection = (section) => { + const optionComponent = this.props.componentExtractor(section); + let component = optionComponent || ( + {this.props.labelExtractor(section)} + ); + return ( - - {section.label} + + {component} ); } - renderOption(option) { + 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 || ( + + {optionLabel} + + ); + return ( - this.onChange(option)}> - - {option.label} + this.onChange(option)} + activeOpacity={this.props.touchableActiveOpacity} + accessible={this.props.listItemAccessible} + accessibilityLabel={option.accessibilityLabel || undefined} + importantForAccessibility={isFirstItem ? 'yes' : 'no'} + {...this.props.passThruProps} + > + + {component} - ) + ); + } + + renderFlatlistOption = ({ item, index, separators }) => { + if (item.section) { + return this.renderSection(item); + } + const numItems = this.props.data.length; + return this.renderOption(item, index === (numItems - 1), index === 0); } - renderOptionList() { - var options = this.props.data.map((item) => { + renderOptionList = () => { + const { + data, + listType, + backdropPressToClose, + scrollViewPassThruProps, + overlayStyle, + optionContainerStyle, + keyboardShouldPersistTaps, + scrollViewAccessible, + scrollViewAccessibilityLabel, + cancelContainerStyle, + touchableActiveOpacity, + cancelButtonAccessible, + cancelButtonAccessibilityLabel, + cancelStyle, + cancelTextStyle, + cancelText, + header, + } = this.props; + + let options = data.map((item, index) => { if (item.section) { return this.renderSection(item); - } else { - return this.renderOption(item); } + return this.renderOption(item, index === data.length - 1, index === 0); }); + let Overlay = View; + let overlayProps = { + style: {flex: 1}, + }; + // Some RN versions have a bug here, so making the property opt-in works around this problem + if (backdropPressToClose) { + Overlay = TouchableWithoutFeedback; + overlayProps = { + key: `modalSelector${componentIndex++}`, + accessible: false, + onPress: this.close, + }; + } + + const optionsContainerStyle = {paddingHorizontal: 10}; + if (scrollViewPassThruProps && scrollViewPassThruProps.horizontal) { + optionsContainerStyle.flexDirection = 'row'; + } + return ( - - - - - {options} - - - - - - - {this.props.cancelText} - - + + + + {header} + {listType === 'FLATLIST'? + + : + + + {options} + + + } + + + + + {cancelText} + + + - - ); + + ); } - renderChildren() { + renderChildren = () => { if(this.props.children) { return this.props.children; } + let initSelectStyle = this.props.initValue === this.state.selected ? + [styles.initValueTextStyle, this.props.initValueTextStyle] : [styles.selectTextStyle, this.props.selectTextStyle]; return ( - {this.state.selected} + {this.state.selected} ); } @@ -163,21 +368,43 @@ export default class ModalPicker extends BaseComponent { render() { const dp = ( - - {this.renderOptionList()} - + this.model = element} + supportedOrientations={this.props.supportedOrientations} + visible={this.state.modalVisible} + onRequestClose={this.close} + animationType={this.props.animationType} + onDismiss={() => this.state.changedItem && this.props.onChange(this.state.changedItem)} + > + {this.renderOptionList()} + ); return ( - + {dp} - - {this.renderChildren()} - + {this.props.customSelector ? + this.props.customSelector + : + this.open({longPress: true})} + disabled={this.props.disabled} + accessible={this.props.openButtonContainerAccessible} + > + + {this.renderChildren()} + + + } ); } } -ModalPicker.propTypes = propTypes; -ModalPicker.defaultProps = defaultProps; +ModalSelector.propTypes = propTypes; +ModalSelector.defaultProps = defaultProps; diff --git a/package.json b/package.json index 16e1eba7..27b6b319 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,18 @@ { - "name": "react-native-modal-picker", - "version": "0.0.16", - "description": "", + "name": "react-native-modal-selector", + "version": "2.1.2", + "description": "A cross-platform (iOS / Android), selector/picker component for React Native that is highly customizable and supports sections.", "main": "index.js", + "typings": "index.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "postversion": "git push && git push --tags" + "postversion": "git push && git push --tags", + "lint": "./node_modules/.bin/eslint ./", + "lint-fix": "./node_modules/.bin/eslint --fix ./" }, "repository": { "type": "git", - "url": "https://github.com/d-a-n/react-native-modal-picker.git" + "url": "git+https://github.com/peacechen/react-native-modal-selector.git" }, "keywords": [ "react-native", @@ -22,16 +25,32 @@ "android", "react-component" ], + "dependencies": { + "prop-types": "^15.5.10" + }, "author": "Daniel Korger ", "contributors": [ - { - "name": "Alex Spring", - "email": "notlose@hotmail.com" - } + "Alex Spring ", + "Peace Chen (https://github.com/peacechen)", + "mikaello" ], "license": "MIT", "bugs": { - "url": "https://github.com/d-a-n/react-native-modal-picker/issues" + "url": "https://github.com/peacechen/react-native-modal-selector/issues" + }, + "homepage": "https://github.com/peacechen/react-native-modal-selector", + "directories": { + "doc": "docs" }, - "homepage": "https://github.com/d-a-n/react-native-modal-picker" + "devDependencies": { + "@babel/core": "^7.18.5", + "@babel/eslint-parser": "^7.18.2", + "@babel/preset-react": "^7.17.12", + "eslint": "^8.18.0", + "eslint-plugin-babel": "^5.3.1", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react-native": "^4.0.0" + } } diff --git a/style.js b/style.js index 3a6f5eca..6146e00f 100644 --- a/style.js +++ b/style.js @@ -1,84 +1,84 @@ 'use strict'; -import { StyleSheet, Dimensions } from 'react-native'; - -const {height, width} = Dimensions.get('window'); +import { StyleSheet } from 'react-native'; const PADDING = 8; const BORDER_RADIUS = 5; const FONT_SIZE = 16; const HIGHLIGHT_COLOR = 'rgba(0,118,255,0.9)'; -const OPTION_CONTAINER_HEIGHT = 400; export default StyleSheet.create({ overlayStyle: { - width: width, - height: height, - backgroundColor: 'rgba(0,0,0,0.7)' + flex: 1, + padding: '5%', + justifyContent: 'center', + backgroundColor: 'rgba(0,0,0,0.7)', }, optionContainer: { - borderRadius:BORDER_RADIUS, - width:width*0.8, - height:OPTION_CONTAINER_HEIGHT, - backgroundColor:'rgba(255,255,255,0.8)', - left:width*0.1, - top:(height-OPTION_CONTAINER_HEIGHT)/2 + borderRadius: BORDER_RADIUS, + flexShrink: 1, + marginBottom: 8, + padding: PADDING, + backgroundColor: 'rgba(255,255,255,0.8)', }, cancelContainer: { - left:width*0.1, - top:(height-OPTION_CONTAINER_HEIGHT)/2 + 10 + alignSelf: 'stretch', }, selectStyle: { - flex: 1, - borderColor: '#ccc', - borderWidth: 1, - padding: 8, - borderRadius: BORDER_RADIUS + borderColor: '#ccc', + borderWidth: 1, + padding: PADDING, + borderRadius: BORDER_RADIUS, }, selectTextStyle: { textAlign: 'center', - color: '#333', - fontSize: FONT_SIZE + color: '#333', + fontSize: FONT_SIZE, }, cancelStyle: { - borderRadius: BORDER_RADIUS, - width: width * 0.8, + borderRadius: BORDER_RADIUS, backgroundColor: 'rgba(255,255,255,0.8)', - padding: PADDING + padding: PADDING, }, cancelTextStyle: { textAlign: 'center', - color: '#333', - fontSize: FONT_SIZE + color: '#333', + fontSize: FONT_SIZE, }, optionStyle: { - padding: PADDING, + padding: PADDING, borderBottomWidth: 1, - borderBottomColor: '#ccc' + borderBottomColor: '#ccc', }, optionTextStyle: { textAlign: 'center', - fontSize: FONT_SIZE, - color: HIGHLIGHT_COLOR + fontSize: FONT_SIZE, + color: HIGHLIGHT_COLOR, }, sectionStyle: { - padding: PADDING * 2, + padding: PADDING * 2, borderBottomWidth: 1, - borderBottomColor: '#ccc' + borderBottomColor: '#ccc', }, sectionTextStyle: { textAlign: 'center', - fontSize: FONT_SIZE - } -}); \ No newline at end of file + fontSize: FONT_SIZE, + }, + + initValueTextStyle: { + textAlign: 'center', + fontSize: FONT_SIZE, + color: '#d3d3d3', + }, +});