diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..e88ed233c --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,91 @@ +{ + "parserOptions": { + "project": "./tsconfig.json" + }, + "extends": ["skype", "skype/react"], + "rules": { + "no-console": [ + "error", + { + "allow": [ + "error", + "warn", + "log" + ] + } + ], + + "camelcase": "off", + "@typescript-eslint/camelcase": [ + "error", + { + "allow": [ + "^reactxp_", + "^mixin_", + "^UNSAFE_", + "^Radio_button_" /* Android properties only */ + ] + } + ], + "@typescript-eslint/no-parameter-properties": "off" + }, + "overrides": [ + { + "files": [ + "*.tsx" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + + { + "files": [ + "ReactXP.ts", + "ModuleInterface.ts" + ], + "rules": { + "no-self-assign": "off", + "prefer-const": "off", + + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/prefer-namespace-keyword": "off" + } + }, + + { + "files": [ + "Easing.ts" + ], + "rules": { + "@typescript-eslint/member-naming": [ + "error", + { + "public": "^[A-Z]\\w+$" + } + ] + } + }, + + { + "files": [ + "*.d.ts" + ], + "rules": { + "@typescript-eslint/prefer-namespace-keyword": "off", + "@typescript-eslint/no-unused-vars": "off" + } + }, + + { + "files": [ + "*/web/Animated.tsx", + "*/native-desktop/RootView.tsx" + ], + "rules": { + "@typescript-eslint/member-naming": "off" + } + } + ] +} diff --git a/.npmignore b/.npmignore index 77b203cea..174f50aae 100644 --- a/.npmignore +++ b/.npmignore @@ -6,3 +6,4 @@ /extensions /docs *.user +.eslintrc \ No newline at end of file diff --git a/.npmrc b/.npmrc index 43c97e719..e69de29bb 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +0,0 @@ -package-lock=false diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..5814d7de5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: node_js + +node_js: + - "node" + +dist: trusty + +sudo: false + +addons: + chrome: stable + +install: + - node --version + - npm --version + - npm i + +script: + - npm run lint + - npm run build + +cache: + directories: + - node_modules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..3fe9b147a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing to ReactXP + +We welcome contributions to ReactXP! This gude provides some tips for a successful contributions. + +For complex changes, we recommend filing a GitHub issue to start a discussion with project maintainers before implementing the change. + +## Pull Requests + +Please make sure the following is done when submitting a pull request: + +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add test code to the RXPTest sample app. +3. If you've changed APIs, update the documentation files. +4. Ensure the test suite passes. +5. If you haven't already, complete the Contributor License Agreement ("CLA"). + +## Testing Your Change + +To test your change: +1. Rebuild reactxp: `npm i` and `npm run build` +2. Switch to the RXPTest sample directory: `cd ./samples/RXPTest` +3. Update dependencies: `npm i` +4. Copy the locally-built reactxp library: `cp -r ../../dist/* ./node_modules/reactxp/dist` +5. Rebuild the test app: `npm run web-watch` or `npm run rn-watch` +6. If testing the web version: + - for desktop: open the test in the browser: `open ./index.html` and run the test + - for mobile: run `npm run web -- -host YOUR_LOCAL_IP` then on your mobile enter `http://YOUR_LOCAL_IP:8080` +7. If testing one or more RN versions, open the corresponding native project and build and run the test + +## Contributor License Agreement ("CLA") + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +You must sign a Contribution License Agreement (CLA) before your PR will be merged. This is a one-time requirement for Microsoft projects in GitHub. You can read more about [Contribution License Agreements (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia. You can sign the Microsoft Contribution License Agreement by visiting https://cla.microsoft.com/. Use your GitHub account to login. + +## Issues + +We use GitHub issues to track bugs. + +## Coding Style + +ReactXP is written in TypeScript and uses tslint to help enforce an internally-consistent coding style. Contributions should be consistent with this style. + diff --git a/README.md b/README.md index ff57ec1c7..5b6cac800 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,60 @@ # ReactXP + +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/Microsoft/reactxp/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/reactxp.svg?style=flat-square)](https://www.npmjs.com/package/reactxp) [![Build Status](https://dev.azure.com/ms/reactxp/_apis/build/status/Microsoft.reactxp?)](https://dev.azure.com/ms/reactxp/_build/latest?definitionId=16) [![Build Status](https://img.shields.io/travis/Microsoft/reactxp/master.svg?style=flat-square)](https://travis-ci.org/Microsoft/reactxp) [![npm downloads](https://img.shields.io/npm/dm/reactxp.svg?style=flat-square)](https://www.npmjs.com/package/reactxp) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/Microsoft/reactxp#contributing) [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square)](https://gitter.im/msreactxp/Lobby) + + ReactXP is a library for cross-platform app development using React and React Native. +## ReactXP End of Life +The ReactXP library is no longer being maintained and is is considered “end of life”. We recommend alternatives such as [React Native for Web](https://necolas.github.io/react-native-web/docs/). The ReactXP github project will be put into “archive” mode and will remain available in read-only form for the benefit of those who are still using it within older projects, but no new versions will be published. + ## Why ReactXP With React and React Native, your web app can share most of its logic with your iOS and Android apps, but the view layer needs to be implemented separately for each platform. We have taken this a step further and developed a thin cross-platform layer we call ReactXP. If you write your app to this abstraction, you can share your view definitions, styles and animations across multiple target platforms. Of course, you can still provide platform-specific UI variants, but this can be done selectively where desired. ## Getting Started The [samples](/samples) directory contains a minimal “Hello World” app that demonstrates some basic ReactXP functionality. You can use this as a starting point. Just follow the build instructions in the README file. -Nader Dabit has created a helpful [video tutorial](https://medium.com/@dabit3/reactxp-first-look-d3dd1d08febd) that walks you through the steps to build the sample app. +Also included in the samples directory is the [RXPTest app](/samples/RXPTest) which attempts to exercise all of the functionality of ReactXP. It is a good source to consult for sample usage of APIs, components, and props. You can read more about ReactXP and its APIs from the [ReactXP official Documentation](https://microsoft.github.io/reactxp/docs/getting-started.html). +Use the command-line tool called [create-rx-app](https://github.com/a-tarasyuk/create-rx-app) to create a starter project. + +```sh +npm install create-rx-app -g +create-rx-app AppName +``` + +or + +```sh +npx create-rx-app AppName +``` + +By default the project will be created in TypeScript. However if you prefer JavaScript instead, add `--javascript` when creating the project. + +This will create a directory called **AppName** inside the current working directory. Inside **AppName**, this will generate the initial project structure and install all of its dependencies. Once this installation is done, there are some commands you can run in the project directory: + +- `npm run start:web` - runs the Web version of the app in the development mode +- `npm run build:web` - builds the Web version of the app for production to the **dist-web** folder +- `npm run start:ios` - runs the iOS version of the app and attempts to open in the iOS Simulator if you're on a Mac and have it installed +- `npm run start:android` - runs the Android version of the app and attempts to open your app on a connected Android device or emulator +- `npm run start:windows` - runs the Windows version of the app +- `npm start:rn-dev-server` - runs react native (RN) development server + ### Prerequisites -* [Node.Js](https://nodejs.org/) -* [React Native](https://facebook.github.io/react-native/) +* [Node.Js](https://nodejs.org/) ([Setup Instructions](https://nodejs.org/en/download/package-manager/)) +* [React Native](https://facebook.github.io/react-native/) ([Setup Instructions](https://facebook.github.io/react-native/docs/getting-started)) -## Contributing +## ESLint rules -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +> [TSLint will be deprecated some time in 2019](https://github.com/palantir/tslint) + +If you plan to migrate your projects from TSLint to ESlint and want to continue using the [_rules_](https://github.com/microsoft/reactxp/tree/master/src/tslint) to automate search common problems in *ReactXP* usage, you can use [eslint-plugin-reactxp](https://github.com/a-tarasyuk/eslint-plugin-reactxp). + +## Contributing -You must sign a Contribution License Agreement (CLA) before your PR will be merged. This is a one-time requirement for Microsoft projects in GitHub. You can read more about [Contribution License Agreements (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia. You can sign the Microsoft Contribution License Agreement by visiting https://cla.microsoft.com/. Use your GitHub account to login. +We welcome contributions to ReactXP. See the [CONTRIBUTING](./CONTRIBUTING.md) file for how to help out. ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details diff --git a/README_Hindi.md b/README_Hindi.md new file mode 100644 index 000000000..2a0c73a2e --- /dev/null +++ b/README_Hindi.md @@ -0,0 +1,52 @@ +# ReactXP + +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/Microsoft/reactxp/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/reactxp.svg?style=flat-square)](https://www.npmjs.com/package/reactxp) [![Build Status](https://img.shields.io/travis/Microsoft/reactxp/master.svg?style=flat-square)](https://travis-ci.org/Microsoft/reactxp) [![npm downloads](https://img.shields.io/npm/dm/reactxp.svg?style=flat-square)](https://www.npmjs.com/package/reactxp) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/Microsoft/reactxp#contributing) [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square)](https://gitter.im/msreactxp/Lobby) + +ReactXP एक क्रॉस-प्लॅटफॉर्म ऍप डेवलपमेंट लाइब्रेरी है जिसमे React और React Native का उपयोग किया जाता है. + +##ReactXP क्यों ? +React और React Native के साथ आपका वेब ऍप, iOS और Android ऍप के साथ ज्यादातर तार्किक शेयर कर सकता है, लेकिन view layer आपको अलग से इम्प्लीमेंट करना होगा हर एक प्लॅटफॉर्म के लिए. हमने एक कदम आगे लेकर एक हल्का क्रॉस-प्लॅटफॉर्म लेयर विकसित किया है जिसे हम ReactXP बुलाते है. अगर आप आपके ऍप को इस abstraction के हिसाब से लिखते है फिर आप आपके view definitions, styles और animations को शेयर कर सकते है मल्टिपल टारगेट प्लेटफॉर्म्स पर. आप प्लेटफार्म स्पेसिफिक UI variants भी प्रदान कर सकते है जैसे आप चुनेंगे जब आपकी मर्ज़ी हो| + +## शुरुआत +दिए हुए [samples](/samples) directory में आपको एक आसान सा “Hello World” ऍप मिलेगा जिसमे ReactXP के बुनियादी कार्यक्षमता दिखाई गई है. आप उससे स्टार्टिंग पॉइंट की तरह प्रयोग कर सकते है. दिए हुए README के सूचनाओं का पालन कर सकते है. + +samples directory[RXPTest app](/samples/RXPTest) में RXPTest ऍप भी दिया गया है जो ReactXP के सारे कार्यक्षमताओं का उपयोग करने का प्रयास करता है. +ये एक अछि सोर्स है APIs, components और props का उपयोग जान्ने के लिए. + +आप ReactXP और उसके APIs के बारे में और पड़ सकते है इस वेबसाइट पर [ReactXP official Documentation](https://microsoft.github.io/reactxp/docs/getting-started.html). + +[create-rx-app](https://github.com/a-tarasyuk/create-rx-app) नाम के कमांड-लाइन टूल का उपयोग करके स्टार्टर प्रोजेक्ट बनाइये. + +```sh +npm install create-rx-app -g +create-rx-app AppName +``` + +अथवा + +```sh +npx create-rx-app AppName +``` +शुरुवात में प्रोजेक्ट TypeScript में उपलब्ध किया जाता hai. लेकिन अगर आपको JavaScript में करना हो तोह प्रोजेक्ट बनाते समय फिर `--javascript` का उपयोग करें. + +ये **AppName** नाम का डायरेक्टरी बनाएगा वर्किंग डायरेक्टरी में. **AppName** के अंदर शुरुवाती प्रोजेक्ट का आकार बना हुआ रहेगा और सारे dependencies इनस्टॉल किये हुए रहेंगे. इंस्टालेशन ख़तम होने के बाद निचे दिए हुए कुछ commands आप रन कर सकते है प्रोजेक्ट डायरेक्टरी में : + +- `npm run start:web` - ऍप के Web version को development mode में run करने के लिए +- `npm run build:web` - ऍप के Web version को बनता है production के लिए **dist-web** फोल्डर में +- `npm run start:ios` - ऍप के iOS version को run करके iOS Simulator में खोलके की कोशिश करता है अगर आप Mac इस्तेमाल कर रहे हो और उसमे इनस्टॉल किया हुआ हो +- `npm run start:android` - ऍप के Android version को run करके आपके ऍप को connected Android device या फिर emulator पर खोलने के कोशिश करता है +- `npm run start:windows` - ऍप के Windows version को run करता है +- `npm start:rn-dev-server` - React native (RN) development server run करता है + +### Prerequisites +* [Node.Js](https://nodejs.org/) ([Setup Instructions](https://nodejs.org/en/download/package-manager/)) +* [React Native](https://facebook.github.io/react-native/) ([Setup Instructions](https://facebook.github.io/react-native/docs/getting-started)) + +## Contributing + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +You must sign a Contribution License Agreement (CLA) before your PR will be merged. This is a one-time requirement for Microsoft projects in GitHub. You can read more about [Contribution License Agreements (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia. You can sign the Microsoft Contribution License Agreement by visiting https://cla.microsoft.com/. Use your GitHub account to login. + +## License +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..e138ec5d6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..26502cb9c --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,19 @@ +# Node.js +# Build a general Node.js project with npm. +# Add steps that analyze code, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript + +pool: + vmImage: 'Ubuntu 16.04' + +steps: +- task: NodeTool@0 + inputs: + versionSpec: '8.x' + displayName: 'Install Node.js' + +- script: | + npm ci + npm run lint + npm run build + displayName: 'npm install and build' \ No newline at end of file diff --git a/docs/_data/nav_docs.yml b/docs/_data/nav_docs.yml index f9cddcaf7..c04d59b86 100644 --- a/docs/_data/nav_docs.yml +++ b/docs/_data/nav_docs.yml @@ -86,9 +86,13 @@ title: ImageSvg - id: extensions/navigator title: Navigator + - id: extensions/netinfo + title: NetInfo - id: extensions/restclient title: REST Client - id: extensions/video title: Video - id: extensions/virtuallistview title: VirtualListView + - id: extensions/webview + title: WebView diff --git a/docs/docs/animations.md b/docs/docs/animations.md index 37ae5987f..1b042904c 100644 --- a/docs/docs/animations.md +++ b/docs/docs/animations.md @@ -7,11 +7,11 @@ permalink: docs/animations.html next: accessibility --- -ReactXP supports a powerful animation abstraction. Inidividual style elements (e.g. transforms, opacity, or backgroundColor) can be animated. +ReactXP supports a powerful animation abstraction. Individual style elements (e.g. transforms, opacity, or backgroundColor) can be animated. ## Animatable Components -Three base RX classes can have animatable styles: +Four base RX classes can have animatable styles: * Animated.View @@ -83,7 +83,7 @@ let compositeAnimation = RX.Animated.parallel([ { toValue: 0.0, duration: 250, easing: RX.Animated.Easing.InOut() } ), RX.Animated.timing(animatedOpacityValue, - { toValue: 1.1, duration 250, easing: RX.Animated.Easing.Linear() } + { toValue: 1.1, duration: 250, easing: RX.Animated.Easing.Linear() } ) ]); @@ -103,6 +103,7 @@ animatedOpacityValue.setValue(0.0); ReactXP animation APIs on the web are implemented using DOM style transitions, as opposed to using JavaScript code to drive the animation. This results in much better performance and (in most cases) glitch-free animations, but it imposes some limitations on the use of the animation APIs. * All active animated values associated with a particular element must share the same timing parameters (duration, easing function, delay, loop) and must be started at the same time. * Each animated value can be associated with only one animated attribute that is actively running. -* Interpolated values are limited to only two values -- a begin and end value -- and must be specified in increasing order. -* For interpolated values, the starting and ending values of an animation must correspond to the two interpolation keys. +* Interpolated values used with startTransition are limited to only two values -- a begin and end value -- and must be specified in increasing order. +* Interpolated values not used with startTransition must have numeric outputValues, since we're interpolating between them ourselves. +* For interpolated values, the starting and ending values of a transition animation must correspond to the two interpolation keys. * If an animation is stopped, the value will not reflect the intermediate position in the case of transforms and interpolated values. diff --git a/docs/docs/apis/accessibility.md b/docs/docs/apis/accessibility.md index e67b55736..8e207c39c 100644 --- a/docs/docs/apis/accessibility.md +++ b/docs/docs/apis/accessibility.md @@ -28,6 +28,6 @@ announceForAccessibility(announcement: string): void; // Indicates whether a screen reader is currently enabled. isScreenReaderEnabled(): boolean; -// Inidicates whether the OS-level "high-contrast" setting is enabled. +// Indicates whether the OS-level "high-contrast" setting is enabled. isHighContrastEnabled(): boolean; ``` diff --git a/docs/docs/apis/alert.md b/docs/docs/apis/alert.md index 3e3d671ba..3fbd95a3b 100644 --- a/docs/docs/apis/alert.md +++ b/docs/docs/apis/alert.md @@ -59,6 +59,14 @@ interface AlertOptions { // Optional theme (web only) theme?: AlertModalTheme; + + // (Android, iOS, and Windows only) + // Optional: the id of the root view this alert is associated with. + // Defaults to the view set by UserInterface.setMainView(). + rootViewId?: string; + + // Optional: Prevent the dialog from being dismissed when pressing away from the dialog + preventDismissOnPress?: boolean; } ``` diff --git a/docs/docs/apis/app.md b/docs/docs/apis/app.md index a576d027e..cd53c0f51 100644 --- a/docs/docs/apis/app.md +++ b/docs/docs/apis/app.md @@ -13,13 +13,15 @@ This interface provides core methods associated with the application. It also ex ``` javascript // Indicates whether the app is active or inactive enum AppActivationState { - // App is active and in foreground + // App is running and in foreground Active = 1, - // App is active and in background + // App is running and in background Background = 2, - // App is inactive (not actively running) + // App is inactive + // On RN mobile platforms, it is an intermediate state between when app transitions between foreground and background. + // On desktop platforms, this is currently not being used. Inactive = 3, // iOS specific activation state for extensions implemented diff --git a/docs/docs/apis/linking.md b/docs/docs/apis/linking.md index f82948d57..879f48a11 100644 --- a/docs/docs/apis/linking.md +++ b/docs/docs/apis/linking.md @@ -43,7 +43,7 @@ enum LinkingErrorCode { ## Methods ``` javascript -// Returns the URL that was used to launch tha application +// Returns the URL that was used to launch the application getInitialUrl(): SyncTasks.Promise; // Requests the URL to be opened by the default app for that protocol diff --git a/docs/docs/apis/modal.md b/docs/docs/apis/modal.md index ffb6787b1..6ba9cba3f 100644 --- a/docs/docs/apis/modal.md +++ b/docs/docs/apis/modal.md @@ -20,7 +20,7 @@ A modal covers the entire screen but is transparent. Its children define the vis ## Types ``` javascript interface ModalOptions { - // Android & iOS only. + // Android, iOS, and Windows only. // The id of the root view this modal is associated with. // Defaults to the view set by UserInterface.setMainView(); rootViewId?: string; diff --git a/docs/docs/apis/network.md b/docs/docs/apis/network.md index c765cabd1..6d913bf02 100644 --- a/docs/docs/apis/network.md +++ b/docs/docs/apis/network.md @@ -7,32 +7,4 @@ permalink: docs/apis/network.html next: apis/platform --- -This interface provides information about network connectivity. - -## Types -``` javascript -enum DeviceNetworkType { - Unknown, - None, - Wifi, - Mobile2G, - Mobile3G, - Mobile4G -} -``` - -## Methods -``` javascript -// Returns a promise that specifies whether the device currently -// has network connectivity -isConnected(): SyncTasks.Promise; - -// Returns the type of network -getType(): SyncTasks.Promise; -``` - -## Events -``` javascript -// Triggered when the connectivity changes -connectivityChangedEvent: SubscribableEvent<(isConnected: boolean) => void>; -``` +This has been deprecated from ReactXP Core and moved to an extension (reactxp-netinfo) inline with the React Native Lean Core initiative. \ No newline at end of file diff --git a/docs/docs/apis/popup.md b/docs/docs/apis/popup.md index d72301fd5..68f749e39 100644 --- a/docs/docs/apis/popup.md +++ b/docs/docs/apis/popup.md @@ -19,7 +19,10 @@ Popups are identified by a caller-specified ID that should be unique. ## Types ``` javascript -type PopupPosition = 'top' | 'right' | 'bottom' | 'left'; +// 'context' mode makes it attempt to behave like a context menu -- defaulting +// to the lower right of the anchor element and working its way around. It is not supported +// with inner positioning and will throw an exception if used there. +type PopupPosition = 'top' | 'right' | 'bottom' | 'left' | 'context'; interface PopupOptions { // Returns a mounted component instance that serves as the @@ -78,12 +81,13 @@ interface PopupOptions { // default behavior, in which case the popup must be dismissed explicitly. preventDismissOnPress?: boolean; - // The popup may be left in the DOM after it's dismissed. This is a performance optimization to - // make the popup appear faster when it's shown again, intended for popups that tend to be shown - // repeatedly. Note that this is only a hint, popups cannot be force-cached. + // The popup may be left in the DOM after it's dismissed. This is a + // performance optimization to make the popup appear faster when it's shown + // again, intended for popups that tend to be shown repeatedly. Note that + // this is only a hint, so callers shouldn't rely on caching behavior. cacheable?: boolean; - // Android & iOS only. + // Android, iOS, and Windows only. // The id of the root view this popup is associated with. // Defaults to the view set by UserInterface.setMainView(); rootViewId?: string; diff --git a/docs/docs/apis/statusbar.md b/docs/docs/apis/statusbar.md index 01ccc8363..103b89b9e 100644 --- a/docs/docs/apis/statusbar.md +++ b/docs/docs/apis/statusbar.md @@ -27,6 +27,6 @@ setNetworkActivityIndicatorVisible(value: boolean): void; // Specifies the background color of the status bar (applies on Android only) setBackgroundColor(color: string, animated: boolean): void; -// Specifies whether the status bar is transluscent or transparent +// Specifies whether the status bar is translucent or transparent setTranslucent(translucent: boolean): void; ``` diff --git a/docs/docs/apis/storage.md b/docs/docs/apis/storage.md index 717d59678..0e99c9227 100644 --- a/docs/docs/apis/storage.md +++ b/docs/docs/apis/storage.md @@ -7,7 +7,7 @@ permalink: docs/apis/storage.html next: apis/userinterface --- -This interface provides a simple key-based local storage mechanism. +This interface provides a simple key-based local storage mechanism. If you need more powerful options to persist data and work with them, consider using ReactXP's [Database Extension](/reactxp/docs/extensions/database). ## Methods ``` javascript diff --git a/docs/docs/apis/userinterface.md b/docs/docs/apis/userinterface.md index 17436e886..9ff4671d9 100644 --- a/docs/docs/apis/userinterface.md +++ b/docs/docs/apis/userinterface.md @@ -57,12 +57,6 @@ measureWindow(rootViewId?: string): Types.Dimensions; // can be adjusted by users on some platforms; defaults to 1.0 getContentSizeMultiplier(): SyncTasks.Promise; -// Sets the default maximum "size multiplier" for text increase. -// Values must be 0 or >=1. The default is 0 which indicates that -// there is no max. -// Note: Older versions of React Native don’t support this interface. -setMaxContentSizeMultiplier(maxContentSizeMultiplier: number): void; - // Dismisses the on-screen keyboard (on applicable platforms) dismissKeyboard(): void; @@ -73,7 +67,7 @@ enableTouchLatencyEvents(latencyThresholdMs: number): void; // Returns true if the application is in the keyboard navigation state, // when the user is using Tab key to navigate through the focusable -// elements (on applicalbe platforms). +// elements (on applicable platforms). isNavigatingWithKeyboard(): boolean; ``` diff --git a/docs/docs/apis/userpresence.md b/docs/docs/apis/userpresence.md index c7ea25877..b2d5e7b2c 100644 --- a/docs/docs/apis/userpresence.md +++ b/docs/docs/apis/userpresence.md @@ -12,6 +12,7 @@ This interface provides information about whether the user is currently present. # Methods ``` javascript // Indicates whether the user is currently present +// On web platforms, it indicates whether the user has focused on the app and interacted with the app in the last 60 seconds isUserPresent(): boolean; ``` diff --git a/docs/docs/components/activityindicator.md b/docs/docs/components/activityindicator.md index fae7cf383..15314ae7d 100644 --- a/docs/docs/components/activityindicator.md +++ b/docs/docs/components/activityindicator.md @@ -19,6 +19,9 @@ deferTime: number = 0; // Size of indicator (exact sizes are platform-specific) size: 'large' | 'medium' | 'small' | 'tiny'; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; ``` ## Styles diff --git a/docs/docs/components/button.md b/docs/docs/components/button.md index 11df2631e..74e68ef54 100644 --- a/docs/docs/components/button.md +++ b/docs/docs/components/button.md @@ -25,11 +25,15 @@ accessibilityTraits: AccessibilityTrait | AccessibilityTrait[] = undefined; // in View's FocusArbitrator callback. accessibilityId: string = undefined; +// Opacity value the button should animate to on button touch +activeOpacity: number = undefined; // iOS and Android only + // Id of an expandable element revealed by the button. Describes a relation // between button and element to screen reader. ariaControls: string = undefined; // Web only // Specifies a unique id for an HTML element +// NOTE: This property may be going away in future versions. id: string = undefined; // Web only // Expose the element and/or its children as accessible to Screen readers @@ -45,6 +49,9 @@ disabled: boolean = false; // overriden with this property disabledOpacity: number = undefined; +// Disable default opacity animation on touch of buttons +disableTouchOpacityAnimation: boolean = false; // iOS and Android only + // Should be focused when the component is mounted, see also View's arbitrateFocus // property. // WARNING: autoFocus=true means that this Button's requestFocus() method will be @@ -91,16 +98,12 @@ style: ButtonStyleRuleSet | ButtonStyleRuleSet[] = []; // Keyboard tab order tabIndex: number = undefined; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + // Text for a tooltip title: string = undefined; -// Visual touchfeedback properties -// Disable default opacity animation on touch of buttons -disableTouchOpacityAnimation: boolean = false; // iOS and Android only - -// Opacity value the button should animate to on button touch -activeOpacity: number = undefined; // iOS and Android only - // Background color that will be visible on button touch underlayColor: string = undefined; // iOS and Android only ``` diff --git a/docs/docs/components/gestureview.md b/docs/docs/components/gestureview.md index 51a727c5b..c128dd995 100644 --- a/docs/docs/components/gestureview.md +++ b/docs/docs/components/gestureview.md @@ -7,12 +7,22 @@ permalink: docs/components/gestureview.html next: components/image --- -This component provides support for common touch gestures -- tapping, double-tapping, panning, and pinching. It also handles common mouse-based gestures including double clicking and scroll wheel input. +This component provides support for common touch gestures -- tapping, double-tapping, long-pressing, panning, and pinching. It also handles common mouse-based gestures including double clicking and scroll wheel input. Information about pending gestures is returned through event handlers. A caller can specify which gestures they are interested in by specifying those event handlers. For example, if you are interested in double taps and horizontal pans, provide an onDoubleTap and onPanHorizontal handler. ## Props ``` javascript +// Alternate text for screen readers. +accessibilityLabel: string = undefined; + +// Traits used to hint screen readers, etc. +accessibilityTraits: AccessibilityTrait | AccessibilityTrait[] = undefined; + +// Expose the element and/or its children as accessible to Screen readers +importantForAccessibility?: ImportantForAccessibility = + ImportantForAccessibility.Yes; + // Gestures and attributes that apply only to touch inputs onPinchZoom: (gestureState: MultiTouchGestureState) => void = undefined; onRotate: (gestureState: MultiTouchGestureState) => void = undefined; @@ -28,6 +38,14 @@ onPanHorizontal: (gestureState: PanGestureState) => void = undefined; onTap: (gestureState: TapGestureState) => void = undefined; onDoubleTap: (gestureState: TapGestureState) => void = undefined; onContextMenu: (gestureState: TapGestureState) => void = undefined; +onLongPress: (gestureState: TapGestureState) => void = undefined; + +// Focus Events +onFocus: (e: FocusEvent) => void = undefined; +onBlur: (e: FocusEvent) => void = undefined; + +// Keyboard Events +onKeyPress: (e: KeyboardEvent) => void = undefined; // We can set vertical or horizontal as preferred preferredPan: PreferredPanGesture = undefined; // Horizontal or vertical @@ -40,15 +58,8 @@ panPixelThreshold: number = undefined; // release the responder? Setting true allows release. releaseOnRequest: boolean = false; -// Alternate text for screen readers. -accessibilityLabel: string = undefined; - -// Traits used to hint screen readers, etc. -accessibilityTraits: AccessibilityTrait | AccessibilityTrait[] = undefined; - -// Expose the element and/or its children as accessible to Screen readers -importantForAccessibility?: ImportantForAccessibility = - ImportantForAccessibility.Yes; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; ``` ## Styles diff --git a/docs/docs/components/image.md b/docs/docs/components/image.md index 9e71600d4..529fd3ee8 100644 --- a/docs/docs/components/image.md +++ b/docs/docs/components/image.md @@ -11,6 +11,8 @@ This component displays an image, which can come from a local source or from the If child elements are specified, the image acts as a background, and the children are rendered on top of it. +If headers contains 'Cache-Control: max-stale' with no value specified and the image fails to load, the component tries again passing cache: 'only-if-cached' to the underlying native Image (iOS only). This way the app can render otherwise inaccessible stale cached images. + ## Props ``` javascript // Alternate text to display if the image cannot be loaded @@ -31,7 +33,9 @@ resizeMethod: 'auto' | 'resize' | 'scale' = 'auto'; // Android only // Determines how to resize the image if its natural size // does not match the size of the container -resizeMode: 'stretch' | 'contain' | 'cover' | 'auto' | 'repeat' = 'stretch'; +// Note: In Web version, 'auto' doesn't scale down image +// if width/height smaller than the original image size +resizeMode: 'stretch' | 'contain' | 'cover' | 'auto' | 'repeat' = 'contain'; // URL to image source: string = undefined; @@ -39,6 +43,9 @@ source: string = undefined; // See below for supported styles style: ImageStyleRuleSet | ImageStyleRuleSet[] = []; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + // Tooltip for image title: string = undefined; ``` diff --git a/docs/docs/components/link.md b/docs/docs/components/link.md index f7b69cf9a..5976a806c 100644 --- a/docs/docs/components/link.md +++ b/docs/docs/components/link.md @@ -17,20 +17,12 @@ This component displays a hyperlink. On the web, it translates to an <a> t // in View's FocusArbitrator callback. accessibilityId: string = undefined; -// Should be focused when the component is mounted, see also View's arbitrateFocus -// property. -autoFocus: boolean = false; - // Should fonts be scaled according to system setting? allowFontScaling: boolean = true; // Android and iOS only -// Should the scale multiplier be capped when allowFontScaling is set to true? -// Possible values include the following: -// null/undefined (default) - inheret from parent/global default -// 0 - no max -// >= 1 - sets the maxContentSizeMultiplier of this node to this value -// Note: Older versions of React Native don’t support this interface. -maxContentSizeMultiplier: number = null; // Android and iOS only +// Should be focused when the component is mounted, see also View's arbitrateFocus +// property. +autoFocus: boolean = false; // For non-zero values, truncates with ellipsis if necessary numberOfLines: number = 0; @@ -54,14 +46,17 @@ onContextMenu: (e: MouseEvent) => void = undefined; // Can the link be included in a text selection? selectable: boolean = false; +// See below for supported styles +style: LinkStyleRuleSet | LinkStyleRuleSet[] = []; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + // Text for a tooltip title: string = undefined; // URL to follow for hyperlink url: string; - -// See below for supported styles -style: LinkStyleRuleSet | LinkStyleRuleSet[] = []; ``` ## Styles diff --git a/docs/docs/components/picker.md b/docs/docs/components/picker.md index c805b6644..0ac2c696c 100644 --- a/docs/docs/components/picker.md +++ b/docs/docs/components/picker.md @@ -22,19 +22,21 @@ interface PickerPropsItem { // List of items to be displayed in the picker items: PickerPropsItem[] = []; -// Initially-selected item -selectedValue: string; +// 'dialog': Show a modal dialog +// 'dropdown': Shows a dropdown anchored to the picker view +mode: 'dialog' | 'dropdown' = 'dialog'; // Android only // Invoked when the selected value changes onValueChange: (itemValue: string, itemPosition: number) => void; +// Initially-selected item +selectedValue: string; + // See below for supported styles style: PickerStyleRuleSet | PickerStyleRuleSet[] = []; -// Android only. -// 'dialog': Show a modal dialog -// 'dropdown': Shows a dropdown anchored to the picker view -mode: 'dialog' | 'dropdown' = 'dialog'; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; ``` ## Styles diff --git a/docs/docs/components/scrollview.md b/docs/docs/components/scrollview.md index 78b8a2c0e..07c2011d1 100644 --- a/docs/docs/components/scrollview.md +++ b/docs/docs/components/scrollview.md @@ -16,16 +16,15 @@ ScrollViews must have a bounded height (or width, if it scrolls horizontally) si // Should scroll bar bounce when user hits the bounds? bounces: boolean = true; // iOS only -// Does it support scrolling in the horizontal and/or vertical directions? +// Controls the scroll direction. When false or undefined, only vertical scroll is enabled, when true, only horizontal scroll is enabled horizontal: boolean = false; -vertical: boolean = true; // When the user scrolls the view, how should the on-screen keyboard react? keyboardDismissMode: 'none' | 'interactive' | 'on-drag'; // Native only // Should the on-screen keyboard remain visible when the user taps // the scroll view? -keyboardShouldPersistTaps: boolean = false; // Native only +keyboardShouldPersistTaps: boolean | 'always' | 'never' | 'handled' = 'never'; // Native only // Invoked when the contents of the scroll view change onContentSizeChange: (width: number, height: number) => void = undefined; @@ -47,11 +46,19 @@ onScroll: (newScrollTop: number, newScrollLeft: number) => void = undefined; onScrollBeginDrag: () => void = undefined; onScrollEndDrag: () => void = undefined; +// Animation helpers to allow usage of the RN.Animated.Event system through ReactXP. +// AnimatedValue objects hooked up to either (or both) of these properties will be automatically +// hooked into the onScroll handler of the scrollview and .setValue() will be called on them +// with the updated values. On supported platforms, it will use RN.Animated.event() to do +// a native-side/-backed coupled animation. +scrollXAnimatedValue?: RX.Types.AnimatedValue; +scrollYAnimatedValue?: RX.Types.AnimatedValue; + // Android only property to control overScroll mode -overScrollMode?: 'always' | 'always-if-content-scrolls' | 'never'; +overScrollMode?: 'auto' | 'always' | 'never'; // Snap to page boundaries? -pagingEnabled: boolean = false; // iOS only +pagingEnabled: boolean = false; // Android & iOS only snapToInterval: number = undefined; // iOS only // Is scrolling enabled? @@ -77,6 +84,9 @@ style: ViewStyleRuleSet | ViewStyleRuleSet[] = []; // Windows-only property to control tab navigation inside the view tabNavigation?: 'local' | 'cycle' | 'once'; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; ``` ## Styles @@ -96,12 +106,6 @@ focus(): void; // position. setScrollLeft(scrollLeft: number, animate: boolean): void; setScrollTop(scrollTop: number, animate: boolean): void; - -// Adds a value to the current top or left position (measured in pixels) of the -// viewport within the scroll view. Optionally animates from the current -// position. -addToScrollLeft(deltaLeft: number, animate: boolean): void; -addToScrollTop(deltaTop: number, animate: boolean): void; ``` diff --git a/docs/docs/components/text.md b/docs/docs/components/text.md index 83e6705ea..ba68aef90 100644 --- a/docs/docs/components/text.md +++ b/docs/docs/components/text.md @@ -31,7 +31,8 @@ allowFontScaling: boolean = true; // Android and iOS only // glyph. e.g., "abcd..." ellipsizeMode: 'head' | 'middle' | 'tail'; // Android & iOS only -// Specifies a unique id for an HTML element +// Specifies a unique id for an HTML element. +// NOTE: This property may be going away in future versions. id: string = undefined; // Web only // Expose the element and/or its children as accessible to Screen readers @@ -53,26 +54,24 @@ accessibilityId: string = undefined; // callback. autoFocus: boolean = false; -// Should the scale multiplier be capped when allowFontScaling is set to true? -// Possible values include the following: -// null/undefined (default) - inheret from parent/global default -// 0 - no max -// >= 1 - sets the maxContentSizeMultiplier of this node to this value -// Note: Older versions of React Native don’t support this interface. -maxContentSizeMultiplier: number = null; // Android and iOS only - -// For non-zero values, truncates with ellipsis if necessary +// For non-zero values, truncates with ellipsis if necessary. Web platform +// doesn't support values greater than 1. Web platform may also not truncate +// properly if text contains line breaks, so it may be necessary to replace +// line breaks before rendering. numberOfLines: number = 0; -// Is the text selectable (affects mouse pointer and copy command) -selectable: boolean = false; - // Mouse & Touch Events onPress?: (e: SyntheticEvent) => void = undefined; onContextMenu?: (e: SyntheticEvent) => void = undefined; +// Is the text selectable (affects mouse pointer and copy command) +selectable: boolean = false; + // See below for supported styles style: TextStyleRuleSet | TextStyleRuleSet[] = []; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; ``` ## Styles @@ -104,6 +103,9 @@ requestFocus(): void; // Blurs the component. blur(): void; + +// When selection is enabled, retrieves the selected text. +getSelectedText(): string; // Windows only ``` ## Sample Usage diff --git a/docs/docs/components/textinput.md b/docs/docs/components/textinput.md index 46ad5b291..f9be376d9 100644 --- a/docs/docs/components/textinput.md +++ b/docs/docs/components/textinput.md @@ -44,6 +44,12 @@ autoFocus: boolean = false; // Should focus be lost after submitting? blurOnSubmit: boolean = false; +// iOS and Windows only property for controlling when the clear button +// should appear on the right side of the text view. Default behavior +// dependends on platform: equivalent to 'never' on iOS, and 'always' +// on Windows. +clearButtonMode: 'never' | 'while-editing' | 'unless-editing' | 'always'; + // Initial value that will change when the user starts typing defaultValue: string = undefined; @@ -59,14 +65,6 @@ keyboardAppearance: 'default' | 'light' | 'dark'; // On-screen keyboard type to display keyboardType: 'default' | 'numeric' | 'email-address' | 'number-pad'; -// Should the scale multiplier be capped when allowFontScaling is -// set to true? Possible values include the following: -// null/undefined (default) - inheret from parent/global default -// 0 - no max -// >= 1 - sets the maxContentSizeMultiplier of this node to this value -// Note: Older versions of React Native don’t support this interface. -maxContentSizeMultiplier: number = null; // Android and iOS only - // Maximum character count maxLength: number = undefined; @@ -85,7 +83,8 @@ onFocus: () => void = undefined; // Called on a key event onKeyPress: (e: KeyboardEvent) => void = undefined; -// Called when text is pasted into the control +// Called when text is pasted into the control (not currently +// supported on iOS or Android) onPaste: (e: ClipboardEvent) => void = undefined; // Called when the selection scrolls due to overflow @@ -116,6 +115,11 @@ spellCheck: boolean = [value of autoCorrect]; // See below for supported styles style: TextInputStyleRuleSet | TextInputStyleRuleSet[] = []; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + +// Text for a tooltip +title: string = undefined; // If defined, the control value is forced to match this value; // if undefined, control value can be modified by the user diff --git a/docs/docs/components/view.md b/docs/docs/components/view.md index efa41ef02..8fe7d2f22 100644 --- a/docs/docs/components/view.md +++ b/docs/docs/components/view.md @@ -30,8 +30,9 @@ accessibilityLiveRegion: AccessibilityLiveRegion = // in View's FocusArbitrator callback. accessibilityId: string = undefined; -// Expose the element and/or its children as accessible to Screen readers -importantForAccessibility?: ImportantForAccessibility = Auto; +// Opacity value the button should animate to, on touch on views that +// have onPress handlers +activeOpacity: number = undefined; // iOS and Android only // Animation of children // - Every child must have a `key`. @@ -47,14 +48,22 @@ ariaLabelledBy?: string = undefined; // Web only ariaRoleDescription?: string = undefined; // Web only // Block touches for this component and all of its children -blockPointerEvents: boolean = false; // iOS and Android only +blockPointerEvents: boolean = false; + +// Disable default opacity animation on touch on views that have +// onPress handlers +disableTouchOpacityAnimation: boolean = false; // iOS and Android only // Specifies a unique id for an HTML element +// NOTE: This property may be going away in future versions. id: string = undefined; // Web only // Ignore clicks and other mouse events, allowing children or // components behind to receive them -ignorePointerEvents: boolean = false; // web only +ignorePointerEvents: boolean = false; + +// Expose the element and/or its children as accessible to Screen readers +importantForAccessibility?: ImportantForAccessibility = Auto; // When the keyboard navigation is happening, restrict the focusable // elements within this view. Useful for popups and modals, you @@ -106,6 +115,12 @@ arbitrateFocus: FocusArbitrator = undefined; importantForLayout: boolean = false; // web only // Mouse-specific Events +// For drag specific events, if onDragStart is present, the view is draggable. +// onDragStart/onDrag/onDragEnd are source specific events +// onDragEnter/onDragOver/onDragLeave/onDrop are destination specific events +onDragStart: (e: DragEvent) => void = undefined; +onDrag: (e: DragEvent) => void = undefined; +onDragEnd: (e: DragEvent) => void = undefined; onDragEnter: (e: DragEvent) => void = undefined; onDragOver: (e: DragEvent) => void = undefined; onDragLeave: (e: DragEvent) => void = undefined; @@ -127,6 +142,8 @@ onBlur: (e: FocusEvent) => void = undefined; onKeyPress: (e: KeyboardEvent) => void = undefined; // Touch-specific Events +onTouchStartCapture: (e: React.SyntheticEvent) => void = undefined; +onTouchMoveCapture: (e: React.SyntheticEvent) => void = undefined; onLongPress: (e: SyntheticEvent) => void = undefined; onMoveShouldSetResponder: (e: React.SyntheticEvent) => boolean = undefined; @@ -155,6 +172,9 @@ shouldRasterizeIOS: boolean = false; // iOS only // Keyboard tab order tabIndex: number = undefined; +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + // Text for a tooltip title: string = undefined; @@ -164,15 +184,6 @@ style: ViewStyleRuleSet | ViewStyleRuleSet[] = []; // Should use hardware or software rendering? viewLayerTypeAndroid: 'none' | 'software' | 'hardware'; // Android only property -// Visual touchfeedback properties -// Disable default opacity animation on touch on views that have -// onPress handlers -disableTouchOpacityAnimation: boolean = false; // iOS and Android only - -// Opacity value the button should animate to, on touch on views that -// have onPress handlers -activeOpacity: number = undefined; // iOS and Android only - // Background color that will be visible on touch on views that have onPress // handlers underlayColor: string = undefined; // iOS and Android only @@ -214,7 +225,7 @@ requestFocus(): void; blur(): void; // The focus does not go outside the view with restrictFocusWithin by default, -// setFocusRestricted() allows to turn this restricton off and back on. +// setFocusRestricted() allows to turn this restriction off and back on. setFocusRestricted(restricted: boolean): void; // web only diff --git a/docs/docs/components/webview.md b/docs/docs/components/webview.md index 2a0a8bab6..d0d8718a0 100644 --- a/docs/docs/components/webview.md +++ b/docs/docs/components/webview.md @@ -7,110 +7,4 @@ permalink: docs/components/webview.html next: apis/alert --- -This component displays HTML contents in an embedded browser control. - -To limit the functionality of the browser control, specify one or more sandbox options. For detailed definitions of sandbox flags, refer to the [HTML documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). - - -## Types -``` javascript -enum WebViewSandboxMode { - None = 0, - AllowForms = 1 << 0, - AllowModals = 1 << 1, - AllowOrientationLock = 1 << 2, - AllowPointerLock = 1 << 3, - AllowPopups = 1 << 4, - AllowPopupsToEscapeSandbox = 1 << 5, - AllowPresentation = 1 << 6, - AllowSameOrigin = 1 << 7, - AllowScripts = 1 << 8, - AllowTopNavigation = 1 << 9 -} - -interface WebViewNavigationState { - canGoBack: boolean; - canGoForward: boolean; - loading: boolean; - url: string; - title: string; -} - -interface WebViewErrorState { - description: string; - domain: string; - code: string; -} - -interface WebViewSource { - html: string; - baseUrl?: string; // Native only -} -``` - -## Props -``` javascript -// Allow javascript code to call storage methods? -domStorageEnabled: boolean = true; // Native only - -// JavaScript code that is injected into the control and executed -injectedJavaScript: string = undefined; // Native only - -// Is JavaScript executed within the control? -javaScriptEnabled: boolean = true; - -// HTTP headers to include when fetching the URL. -headers: { [headerName: string]: string } = undefined; - -// Called when an error occurs that prevents the contents from loading -onError: (e: SyntheticEvent) => void = undefined; // Native only - -// Called when the contents successfully load -onLoad: (e: SyntheticEvent) => void = undefined; - -// Called when the contents start to load -onLoadStart: (e: SyntheticEvent) => void = undefined; // Native only - -// Called when a message is posted from within a WebView -onMessage: (e: WebViewMessageEvent) => void = undefined; - -// Called when the navigation state changes -onNavigationStateChange: (navigationState: WebViewNavigationState) => void; - -// Flags that restrict behaviors within the control -sandbox: WebViewSandboxMode = None; // Web only - -// Zooms the page contents to fit the available space -scalesPageToFit: boolean = false; - -// HTML to display in webview (if url is not specified) -source: WebViewSource = undefined; - -// Start loading immediately or wait for reload? -startInLoadingState: boolean = true; // Native only - -// See below for supported styles -style: WebViewStyleRuleSet | WebViewStyleRuleSet[] = []; - -// URL to HTML content -url: string = undefined; -``` - -## Styles -No specialized styles - -## Methods -``` javascript -// Navigate back and forward -goBack(); -goForward(); - -// Posts a message to the web control, allowing for communication between -// the app and the JavaScript code running within the web control. On native -// platforms, the targetOrigin is ignored. -postMessage(message: string, targetOrigin?: string = '*'): void; - -// Force the page to reload -reload(); -``` - +This has been deprecated from ReactXP Core and moved to an extension (reactxp-webview) inline with the React Native Lean Core initiative. diff --git a/docs/docs/extensions/database.md b/docs/docs/extensions/database.md index 68a2d9421..1f0840ac6 100644 --- a/docs/docs/extensions/database.md +++ b/docs/docs/extensions/database.md @@ -9,6 +9,6 @@ next: extensions/imagesvg ReactXP provides a [Storage API](/reactxp/docs/apis/storage) for reading and writing simple key/value pairs. Many apps have more complex storage requirements. For this, we developed a no-SQL database wrapper that works on React Native and on browsers. The solution isn't tied to ReactXP, but they work well together. -For more details, refer to the [NoSqlProvider](https://github.com/Microsoft/NoSQLProvider) github site. +For more details, refer to the [NoSqlProvider](https://github.com/Microsoft/NoSQLProvider) GitHub site. To install: ```npm install nosqlprovider``` diff --git a/docs/docs/extensions/imagesvg.md b/docs/docs/extensions/imagesvg.md index ef05cafc2..32a6c83b9 100644 --- a/docs/docs/extensions/imagesvg.md +++ b/docs/docs/extensions/imagesvg.md @@ -9,7 +9,8 @@ next: extensions/navigator This component displays a vector image (SVG format). Props control the fill color, stroke color and stroke width. -The path(s) are specified using the standard SVG string format. Paths must be specified in a nested SvgPath component instance. Multiple SvgPath children can be specified, each with different stroke and fill parameters. +The path(s) are specified using the standard SVG string format. Paths must be specified in a nested SvgPath component instance. Multiple SvgPath children can be specified, each with different stroke and fill parameters. SvgRect children +are also supported at this time, with the limited props available in react-native-svg. To install: ```npm install reactxp-imagesvg``` or ```yarn add reactxp-imagesvg``` @@ -40,11 +41,10 @@ viewBox: string = undefined; webShadow: boolean = false; // web-specific ``` -## SvgPath Props -``` javascript -// Path definition string -d: string = undefined; +## SvgCommon Props +These props apply to all of the sub-SVG-element types below: +``` javascript // Color and opacity of fill; default values are provided by SVG fillColor: color; fillOpacity: number; @@ -55,6 +55,21 @@ strokeWidth: number; strokeOpacity: number; ``` +## SvgPath Props +``` javascript +// Path definition string +d: string = undefined; +``` + +## SvgRect Props +``` javascript +// Position and dimension information for the rect +x: number; +y: number; +width: number; +height: number; +``` + ## Styles [**Flexbox Styles**](/reactxp/docs/styles.html#flexbox-style-attributes) @@ -77,6 +92,13 @@ return ( fillColor={ 'orange' } d={ 'M 0 0 h 20 v 20 z' } /> + ); ``` diff --git a/docs/docs/extensions/navigator.md b/docs/docs/extensions/navigator.md index 40cf59c95..2bfa05239 100644 --- a/docs/docs/extensions/navigator.md +++ b/docs/docs/extensions/navigator.md @@ -4,7 +4,7 @@ title: Navigator layout: docs category: Extensions permalink: docs/extensions/navigator.html -next: extensions/restclient +next: extensions/netinfo --- This component provides a way for the app to present a virtual stack of "cards", allowing the user to push or pop those cards onto the stack in an animated manner. The caller can control the animation type and direction. @@ -127,12 +127,12 @@ class App extends RX.Component { ); } - private _onNavigatorRef = (naviator: RX.Navigator) => { + private _onNavigatorRef = (navigator: RX.Navigator) => { // Stash away a reference to the mounted navigator this._navigator = navigator; } - private _renderScene = (route: NavigatorRoute) => { + private _renderScene = (navigatorRoute: NavigatorRoute) => { switch (navigatorRoute.routeId) { case NavigationRouteId.MainPanel: return ( diff --git a/docs/docs/extensions/netinfo.md b/docs/docs/extensions/netinfo.md new file mode 100644 index 000000000..d0e9f6cd2 --- /dev/null +++ b/docs/docs/extensions/netinfo.md @@ -0,0 +1,65 @@ +--- +id: extensions/netinfo +title: NetInfo +layout: docs +category: Extensions +permalink: docs/extensions/netinfo.html +next: extensions/restclient +--- + +This interface provides information about network connectivity. + +## Types +``` javascript +enum DeviceNetworkType { + Unknown, + None, + Wifi, + Mobile2G, + Mobile3G, + Mobile4G +} +``` + +## Methods +``` javascript +// Returns a promise that specifies whether the device currently +// has network connectivity +isConnected(): SyncTasks.Promise; + +// Returns the type of network +getType(): SyncTasks.Promise; +``` + +## Events +``` javascript +// Triggered when the connectivity changes +connectivityChangedEvent: SubscribableEvent<(isConnected: boolean) => void>; +``` + +## Sample Usage + +``` javascript +private isConnected: boolean; + +constructor() { + // Query the initial connectivity state. + this.isConnected = false; + RXNetInfo.isConnected().then(isConnected => { + this.isConnected = isConnected; + }); + + RXNetInfo.connectivityChangedEvent.subscribe(isConnected => { + // Update the connectivity state. + this.isConnected = isConnected; + }); +} +``` + +## Other Notes + +On Android, the following permission must be added to make use of the network interfaces. + +``` xml + +``` diff --git a/docs/docs/extensions/restclient.md b/docs/docs/extensions/restclient.md index 68b1d8cc2..e2069f902 100644 --- a/docs/docs/extensions/restclient.md +++ b/docs/docs/extensions/restclient.md @@ -11,20 +11,23 @@ ReactXP provides basic [Network APIs](/reactxp/docs/apis/network) for determinin This extension provides a cross-platform mechanism for wrapping a simple REST API. It supports optional retry logic (including exponential backoff). -For more details, refer to the [SimpleRestClients](https://github.com/Microsoft/SimpleRestClients) github site. +For more details, refer to the [SimpleRestClients](https://github.com/Microsoft/SimpleRestClients) GitHub site. -To install: ```npm install simplerestclients``` +To install: ```npm install simplerestclients``` or ```yarn add simplerestclients``` ### Sample Usage ``` javascript -interface User { +import { GenericRestClient, ApiCallOptions } from 'simplerestclients'; +import SyncTasks = require('synctasks'); + +export interface User { id: string; firstName: string; lastName: string; } -class MyRestClient extends GenericRestClient { +export default class MyRestClient extends GenericRestClient { constructor(private _appId: string) { super('https://myhost.com/api/v1/'); } @@ -50,4 +53,4 @@ class MyRestClient extends GenericRestClient { return this.performApiPut('user/' + user.id, user); } } -``` \ No newline at end of file +``` diff --git a/docs/docs/extensions/video.md b/docs/docs/extensions/video.md index 7e9152adf..79cffd95c 100644 --- a/docs/docs/extensions/video.md +++ b/docs/docs/extensions/video.md @@ -85,8 +85,8 @@ resizeMode: 'contain'|'cover'|'stretch' = 'contain'; // Displays controls for play, pause, etc. showControls: boolean = false; -// Source of video (URL) -source: string; +// Source of video (URL) or resource `id` as resolved by `require()` for `react-native` targets. +source: string | number; // See below for supported styles style: ViewStyleRuleSet | ViewStyleRuleSet[] = []; diff --git a/docs/docs/extensions/virtuallistview.md b/docs/docs/extensions/virtuallistview.md index 82d02331c..62e9f62f5 100644 --- a/docs/docs/extensions/virtuallistview.md +++ b/docs/docs/extensions/virtuallistview.md @@ -4,6 +4,7 @@ title: VirtualListView layout: docs category: Extensions permalink: docs/extensions/virtuallistview.html +next: extensions/webview --- This components supports a vertical list of items within a scrolling area. The visible portion of the list is referred to as the "view port". The list is virtualized, which means that items are rendered only when they are within the view port (or just above or below the view port). @@ -24,7 +25,7 @@ To install: ```npm install reactxp-virtuallistview``` The VirtualListView employs a number of tricks to improve performance. -It uses a technique called "cell recycling" to minimize the number of mounts and unmounts. A cell is a container for a list item. When a cell is no longer visible, it can be temporarily hidden and then reused for the next item that becomes visible. This optimization is most effective when the recycled cell and its contents are used for an item that is similar in content. For this reason, callers need to specify a "template" field to identify similar items. +It uses a technique called "cell recycling" to minimize the number of mounts and unmounts. A cell is a container for a list item. When a cell is no longer visible, it can be temporarily hidden and then reused for the next item that becomes visible. This optimization is most effective when the recycled cell and its contents are used for an item that is similar in content. For this reason, callers need to specify a "template" field to identify similar items. In some cases, disabling cell recycling can be benificial as recycled cells continue their regular react lifecycle even when not visible, which can lead to excessive background re-rendering in some cases. When combining VLV with react libraries (like ReSub) that have subscriptions managed by components can cause this behaviour to manifest. To disable cell recycling on specific cells, exclude the template field from the item descriptor. It also supports "overdraw" to render items above and below the view port. This minimizes chances that the user will scroll to a new portion of the list before new items can be rendered in that area. Overdraw is employed only after the view port is initially filled. This reduces the performance impact of rendering. @@ -86,9 +87,9 @@ class FruitListView extends RX.Component { ); } - private _renderItem(item: FruitListItemInfo, hasFocus?: boolean) { + private _renderItem(details: VirtualListViewCellRenderDetails) { const viewStyle = RX.Styles.createViewStyle({ - height: item.height, + height: details.item.height, backgroundColor: item.template === _headerItemTemplate ? '#ddd' : '#fff', alignItems: 'center' @@ -97,7 +98,7 @@ class FruitListView extends RX.Component { return ( - { item.text } + { details.item.text } ); @@ -139,48 +140,68 @@ interface VirtualListViewItemInfo { ## Props ``` javascript - // Ordered list of descriptors for items to display in the list. - itemList: VirtualListViewItemInfo[]; - - // Callback for rendering item when it becomes visible within view port. - renderItem: (item: VirtualListViewItemInfo, hasFocus?: boolean) => - JSX.Element | JSX.Element[]; - - // Optional padding around the scrolling content within the list. - padding?: number; - - // If true, allows each item to overflow its visible cell boundaries; - // by default, item contents are clipped to cell boundaries. - showOverflow?: boolean; - - // Should the list animate additions, removals and moves within the list? - animateChanges?: boolean; - - // By default, VirtualListView re-renders every item during the render. - // Setting this flag to true allows the list view to re-render only - // items from itemList whose descriptor has changed, thus avoiding - // unnecessary rendering. It uses _.isEqual to perform this check. In - // this mode, renderItem should not depend on any external state, only - // on VirtualListViewItemInfo, to render item. - skipRenderIfItemUnchanged?: boolean; - - // Pass-through properties for scroll view. - keyboardDismissMode?: 'none' | 'interactive' | 'on-drag'; - keyboardShouldPersistTaps?: boolean; - disableScrolling?: boolean; - scrollsToTop?: boolean; // iOS only, scroll to top on status bar tap - disableBouncing?: boolean; // iOS only, bounce override - scrollIndicatorInsets?: { top: number, left: number, - bottom: number, right: number }; // iOS only - onScroll?: (scrollTop: number, scrollLeft: number) => void; - - // Logging callback to debug issues related to the VirtualListView. - logInfo?: (textToLog: string) => void; +// Should the list animate additions, removals and moves within the list? +animateChanges?: boolean; + +initialSelectedKey?: string; + +// Ordered list of descriptors for items to display in the list. +itemList: VirtualListViewItemInfo[]; + +// Use this if you want to vertically offset the focused item from the +// top of the viewport when using keyboard nav +keyboardFocusScrollOffset?: number; + +// Logging callback to debug issues related to the VirtualListView. +logInfo?: (textToLog: string) => void; + +// Callback when an item in the VLV is selected +onItemSelected?: (item: ItemInfo) => void; + +// Optional padding around the scrolling content within the list. +padding?: number; + +// Callback for rendering item when it becomes visible within view port. +renderItem: (renderDetails: VirtualListCellRenderDetails) => + JSX.Element | JSX.Element[]; + +// If true, allows each item to overflow its visible cell boundaries; +// by default, item contents are clipped to cell boundaries. +showOverflow?: boolean; + +// By default, VirtualListView re-renders every item during the render. +// Setting this flag to true allows the list view to re-render only +// items from itemList whose descriptor has changed, thus avoiding +// unnecessary rendering. It uses _.isEqual to perform this check. In +// this mode, renderItem should not depend on any external state, only +// on VirtualListViewItemInfo, to render item. +skipRenderIfItemUnchanged?: boolean; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + +// Pass-through properties for scroll view. +keyboardDismissMode?: 'none' | 'interactive' | 'on-drag'; +keyboardShouldPersistTaps?: boolean; +disableScrolling?: boolean; +scrollsToTop?: boolean; // iOS only, scroll to top when user taps on status bar +disableBouncing?: boolean; // iOS only, bounce override +scrollIndicatorInsets?: { top: number, left: number, + bottom: number, right: number }; // iOS only +onLayout?: (e: RX.Types.ViewOnLayoutEvent) => void; +scrollEventThrottle?: number; +onScroll?: (scrollTop: number, scrollLeft: number) => void; +scrollXAnimatedValue?: RX.Types.AnimatedValue; +scrollYAnimatedValue?: RX.Types.AnimatedValue; + ``` ## Methods ``` javascript // Scrolls the view to the specified top value (specified in pixels). scrollToTop(animated = true, top = 0); + +// Sets selection & focus to specified key +selectItemKey(key: string); ``` diff --git a/docs/docs/extensions/webview.md b/docs/docs/extensions/webview.md new file mode 100644 index 000000000..4a871804c --- /dev/null +++ b/docs/docs/extensions/webview.md @@ -0,0 +1,136 @@ +--- +id: extensions/webview +title: WebView +layout: docs +category: Extensions +permalink: docs/extensions/webview.html +--- + +This component displays HTML contents in an embedded browser control. + +To limit the functionality of the browser control, specify one or more sandbox options. For detailed definitions of sandbox flags, refer to the [HTML documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). + + +## Types +``` javascript +enum WebViewSandboxMode { + None = 0, + AllowForms = 1 << 0, + AllowModals = 1 << 1, + AllowOrientationLock = 1 << 2, + AllowPointerLock = 1 << 3, + AllowPopups = 1 << 4, + AllowPopupsToEscapeSandbox = 1 << 5, + AllowPresentation = 1 << 6, + AllowSameOrigin = 1 << 7, + AllowScripts = 1 << 8, + AllowTopNavigation = 1 << 9, + + // Control https mixed content behavior, never by default + AllowMixedContentAlways = 1 << 10, + AllowMixedContentCompatibilityMode = 1 << 11 +} + +interface WebViewNavigationState { + canGoBack: boolean; + canGoForward: boolean; + loading: boolean; + url: string; + title: string; + readonly navigationType: + | 'click' + | 'formsubmit' + | 'backforward' + | 'reload' + | 'formresubmit' + | 'other'; +} + +interface WebViewErrorState { + description: string; + domain: string; + code: string; +} + +interface WebViewSource { + html: string; + baseUrl?: string; // Native only +} +``` + +## Props +``` javascript +// Allow javascript code to call storage methods? +domStorageEnabled: boolean = true; // Native only + +// JavaScript code that is injected into the control and executed +injectedJavaScript: string = undefined; // Native only + +// Is JavaScript executed within the control? +javaScriptEnabled: boolean = true; + +// Determines whether HTML5 audio and video requires the user to tap them before they start playing. +mediaPlaybackRequiresUserAction: boolean = true; // Native only + +// Determines whether HTML5 videos play inline or use the native full-screen controller. +allowsInlineMediaPlayback: boolean = false; // iOS only + +// HTTP headers to include when fetching the URL. +headers: { [headerName: string]: string } = undefined; + +// Called when an error occurs that prevents the contents from loading +onError: (e: SyntheticEvent) => void = undefined; // Native only + +// Called when the contents successfully load +onLoad: (e: SyntheticEvent) => void = undefined; + +// Called when the contents start to load +onLoadStart: (e: SyntheticEvent) => void = undefined; // Native only + +// Called when a message is posted from within a WebView +onMessage: (e: WebViewMessageEvent) => void = undefined; + +// Called when the navigation state changes +onNavigationStateChange: (navigationState: WebViewNavigationState) => void; // Native only + +// Flags that restrict behaviors within the control +sandbox: WebViewSandboxMode = None; + +// Zooms the page contents to fit the available space; deprecated on +// iOS in RN 0.57 +scalesPageToFit: boolean = false; // Native only + +// HTML to display in webview (if url is not specified) +source: WebViewSource = undefined; + +// Start loading immediately or wait for reload? +startInLoadingState: boolean = true; // Native only + +// See below for supported styles +style: WebViewStyleRuleSet | WebViewStyleRuleSet[] = []; + +// ID that can be used to identify the instantiated element for testing purposes. +testId: string = undefined; + +// URL to HTML content +url: string = undefined; +``` + +## Styles +No specialized styles + +## Methods +``` javascript +// Navigate back and forward +goBack(); +goForward(); + +// Posts a message to the web control, allowing for communication between +// the app and the JavaScript code running within the web control. On native +// platforms, the targetOrigin is ignored. +postMessage(message: string, targetOrigin?: string = '*'): void; + +// Force the page to reload +reload(); +``` + diff --git a/docs/docs/getting-started.md b/docs/docs/getting-started.md index 17fcb79fe..e150ed7d1 100644 --- a/docs/docs/getting-started.md +++ b/docs/docs/getting-started.md @@ -9,6 +9,16 @@ redirect_from: - "docs/index.html" --- +## Building Your First ReactXP App + +To create your first ReactXP app, do the following: +1. Clone the ReactXP repo locally: ```git clone https://github.com/microsoft/reactxp```. +2. Open the ```samples``` directory and pick one of the samples and copy its directory to a new location. [Hello-World](https://github.com/Microsoft/reactxp/tree/master/samples/hello-world) provides a bare-bones starting app. [Hello-World-js](https://github.com/Microsoft/reactxp/tree/master/samples/hello-world-js) is a variant of Hello-World written in Javascript rather than TypeScript. [TodoList](https://github.com/Microsoft/reactxp/tree/master/samples/TodoList) is a more complex example and is a more appropriate starting point for production applications. +3. Follow the build instructions for the sample you've chosen. +4. If desired, rename the directory and project files to reflect the name of your app. + +If you want to create a new ReactXP app, use the command-line tool [create-rx-app](https://github.com/a-tarasyuk/create-rx-app). + ## Web Technologies React apps are written using web programming techniques. This documentation assumes that you are already familiar with web programming concepts including the use of JavaScript, the browser DOM, browser event handling, and CSS styling. There are many online tutorials that cover these concepts. @@ -19,8 +29,3 @@ While it is possible to write ReactXP apps in JavaScript, we recommend using Typ If you are new to React, you should first familiarize yourself with the core concepts. We provide an overview and some [simple examples](react_concepts.html). Also refer to the official [React](https://reactjs.org/) and [React Native](https://facebook.github.io/react-native/) documentation sites. -## Building Your First ReactXP App - -The `samples` directory contains a minimal "Hello World" app that demonstrates some basic ReactXP functionality. You can use this as a starting point. Just follow the build instructions in the README file. - -Nader Dabit has created a helpful [video tutorial](https://medium.com/@dabit3/reactxp-first-look-d3dd1d08febd) that walks you through the steps to build the sample app. diff --git a/docs/docs/react_lifecycle.md b/docs/docs/react_lifecycle.md index 104f2fd42..cb3e8fd2e 100644 --- a/docs/docs/react_lifecycle.md +++ b/docs/docs/react_lifecycle.md @@ -39,7 +39,7 @@ In this example, a UserInfoCard component is rendered for each user in a list. E ## Mounting & Unmounting -When React encounters a component spec that has no corresponding node in the current virtual DOM, it inserts the spec into the virtual DOM. It also allocates a corresponding DOM element (in the case of React JS) or native control (in the case of React Native). This is referred to as *mounting* a component. Likewise, when a component instance is removed from the real DOM or native control hierarhcy, it is said to be *unmounted*. Certain methods, such as *setState*, can be called only while a component is mounted. +When React encounters a component spec that has no corresponding node in the current virtual DOM, it inserts the spec into the virtual DOM. It also allocates a corresponding DOM element (in the case of React JS) or native control (in the case of React Native). This is referred to as *mounting* a component. Likewise, when a component instance is removed from the real DOM or native control hierarchy, it is said to be *unmounted*. Certain methods, such as *setState*, can be called only while a component is mounted. The React.Component base class, from which all components derive, defines several methods that are called immediately before and after a component is mounted and before a component is unmounted. Component classes can override these methods if desired. For example, if you want to set the focus to a text input box, this can be done within the componentDidMount method. diff --git a/docs/docs/styles.md b/docs/docs/styles.md index 974be8da7..9e9dee6c0 100644 --- a/docs/docs/styles.md +++ b/docs/docs/styles.md @@ -24,7 +24,7 @@ Many base components share common subsets of style attributes. For example, almo ## Combining Styles -All of the base components support a *style* prop that can accept a single style or an array of styles. If an array of styles is provided, the styles are combined in such a way that styles with larger indices override styles with smaller indices. Falsy values (false, null, undefined) can also be specified in a style array. This allows for the following common pattern. +All of the base components support a *style* prop that can accept a single style or an array of styles (or a nested array). If an array of styles is provided, the styles are combined in a depth-first manner left to right. Falsy values (false, null, undefined) can also be specified in a style array. This allows for the following common pattern. ``` javascript let buttonTextStyles = [_styles.baseText, this.state.hovering && _styles.hoverText]; @@ -39,7 +39,7 @@ if (this.state.hovering) { } ``` -Within a style array, you can also pass nested arrays. This allows easy manipulation of composite styles. +If "margin" and "padding" attributes are combined with edge-specific attributes (e.g. "marginLeft" or "paddingBottom"), the specific attributes always override the general. This matches the [combining behavior of React Native](https://github.com/necolas/react-native-web/blob/0.10.0/docs/guides/style.md#how-styles-are-resolved) (but differs from CSS). ``` javascript // this.props.style might be undefined, a single style, or a (potentially-nested) @@ -158,6 +158,10 @@ overflow: 'hidden' | 'visible'; **Borders** ```javascript borderWidth: number; +borderTopWidth: number; +borderRightWidth: number; +borderBottomWidth: number; +borderLeftWidth: number; borderColor: color; borderStyle: 'solid' | 'dotted' | 'dashed' | 'none'; borderRadius: number; // Sets all four border radius attributes; value is animatable @@ -169,7 +173,7 @@ borderTopLeftRadius: number = 0; **Shadows** ```javascript -// NOTE: If applied to a Text element, these properties translate to text shadows, +// NOTE: If applied to a Text element, these properties translate to text shadows, // not a box shadow. shadowOffset: { height: number; width: number } = { 0, 0 }; shadowRadius: number = 0; @@ -198,7 +202,6 @@ transform: { scale: number = 0; scaleX: number = 0; scaleY: number = 0; - scaleY: number = 0; translateX: number = 0; translateY: number = 0; } @@ -217,9 +220,9 @@ fontSize: number = undefined; // Shortcut that sets all three font attributes font: { - family: string = undefined; - style: 'normal' | 'italic'; - weight: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | + fontFamily: string = undefined; + fontStyle: 'normal' | 'italic'; + fontWeight: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'; } ``` diff --git a/docs/docs/using-reactxp.md b/docs/docs/using-reactxp.md index da25d008d..7bf594213 100644 --- a/docs/docs/using-reactxp.md +++ b/docs/docs/using-reactxp.md @@ -15,4 +15,29 @@ ReactXP assumes that your main web page will have a DOM element container called The main module is assumed to be called "RXApp", and it must be registered as such by the native code. Refer to the sample app for how to register the module in Android and iOS. +## TypeScript Support +ReactXP is written in TypeScript and includes TypeScript type definition (".d.ts") files for the library. + +## TSLint Support + +ReactXP includes several [tslint](https://www.npmjs.com/package/tslint) custom rules that can be used in your project. + +To use these rules, modify your tslint.json file to point to the rules within the reactxp dist directory, as follows. + +``` + "rulesDirectory": [ + "./node_modules/reactxp/dist/tslint" + ] +``` + +The following tslint rules are provided: + +### grouped-import +This rule enforces that all ambient (non-relative) module imports are grouped together and are above the group of relative imports. + +### incorrect-this-props +This rule checks for common errors in referencing ```this.props``` within methods that pass ```props``` as an input parameter. + +### no-unreferenced-styles +This rule detects and reports any unreferenced entries within a ```_styles``` array. diff --git a/docs/versions/version_history.md b/docs/versions/version_history.md index b9033039b..74bf05d63 100644 --- a/docs/versions/version_history.md +++ b/docs/versions/version_history.md @@ -11,486 +11,578 @@ redirect_from: ## ReactXP Versioning ### Versioning Strategy -A new version of ReactXP will be released a monthly basis (approximately), following the same general update timeline of React Native. Each new version will get its own branch, allowing consumers of the library to take a dependency on a stable code base. +A new version of ReactXP will be released periodically following the same general update timeline of React Native. Each new version will get its own branch, allowing consumers of the library to take a dependency on a stable code base. - -### Version History - -#### Version 1.3.0-rc.1 of reactxp -_Released 13 Jun 2018_ -Fixed accessibility issues with screen reader in Windows UWP implementation. -Removed shouldRasterizeIOS prop on RX.Image. It was never supported in RN, so it was just a no-op. -Fixed bug in RX.Network.getType() which returned the wrong response if the device was connected to ethernet on Android. - -#### Version 1.3.0-rc.0 of reactxp -_Released 10 Jun 2018_ -Fixed a few bugs in keyboard focus handling for Windows UWP. -Web implementation of RX.Image now uses credentials for image fetches if origin header is specified. -Added support for text shadows in RX.Text (shadowColor, shadowOffset, shadowRadius style attributes). -Fixed keyboard navigation logic for multi-root-view case. -Wired up tooltips in web implementation of RX.Button, RX.Image, RX.Link, and RX.View (title prop). -Extended RX.UserInterface.measureWindow to support multi-root-view case. It now takes an optional rootViewId parameter. -Added drag and drop handler support for Mac OS. -Added new static API RX.Image.getMetadata that returns dimensions of an image. -Avoided the use of the deprecated RN.NetInfo "change" event in favor of "connectionChange" so RN doesn't emit warning. -Added back parameter to onBlur event handler that was incorrectly removed in version 1.2.x. - -#### Version 1.2.1 of reactxp -_Released 24 May 2018_ -Wired up onPaste handler for Windows implementation. -Fixed bug that resulted in cached popups to appear when they shouldn't. -Fixed bug in web implementation of RX.ScrollView that resulted in incorrect screen reader announcements. - -#### Version 1.2.0 of reactxp-imagesvg -#### Version 1.2.0 of reactxp-navigation -#### Version 1.2.0 of reactxp-video -#### Version 1.2.0 of reactxp-virtuallistview -_Released 22 May 2018_ -Automatically suppressed system context menu for selectable RX.Text items on Windows if containing view has onContextMenu handler. - -#### Version 1.2.0 of reactxp -_Released 22 May 2018_ -Automatically suppressed system context menu for selectable RX.Text items on Windows if containing view has onContextMenu handler. - -#### Version 1.1.2-rc.3 of reactxp -_Released 21 May 2018_ -Fixed bug in RX.Linking.getInitialUrl, which was returning null rather than undefined for the url in some cases. -Added support for Dilaog trait to trigger yes-dont-hide importantForAccessibility behavior in Windows implementation. -Fixed UWP accessibility announce to make it act the same way as Android. -Create correct Animated.TextInput for Windows. - -#### Version 1.1.2-rc.2 of reactxp -_Released 15 May 2018_ -Improved keyboard focus support. Added focus, blur and requestFocus methods to several existing components. Added new focusArbitrator prop to RX.View, which allows callback to arbitrate between multiple children that are requesting autofocus. -Fixed bug that caused group view children to be invisible to UI automation. -Improved keyboard support for Windows implementation. - -#### Version 1.1.2-rc.1 of reactxp -_Released 9 May 2018_ -Fixed bug in Windows implementation that prevented RX.Input.keyDownEvent from being dispatched. -Fixed bugs in Windows implementation that reported wrong key codes for keyboard events. -Fixed focus management for cacheable popups in Windows implementation. -Fixed type definitions of GestureView, ScrollView and WebView. They were incorrectly extending ViewBase, which pulled in a number of unsupported props. -Fixed bug that caused cached popups to appear on screen when not appropriate. -Added onContextMenu prop to GestureView. -Added accessibility trait for ListItem. -In Windows implementation, use RNW.Hyperlink for rendering RX.Link. -Removed "justifyEnd" prop from RX.ScrollView. It was never implemented as documented. -Added useSafeInsets prop onR X.View to support rendering within safe area on iOS. -Fixed bug RX.StatusBar.setBarStyle where animated parameter was not properly passed to RN. -Added onContextMenu to RX.Link. - -#### Version 1.1.1 of reactxp -_Released 13 Apr 2018_ -Fixed reentrancy issue in popup support. Displaying a popup from within the onDismiss callback was recently broken. -Added disabledOpacity prop for RX.Button component. -Improved handling of RX.Clipboard.setText on web. It now properly handles carriage returns. -Fixed TextInput focusability after focus restriction on Windows. -Fixed accessibility issue related to voice over on web. - -#### Version 1.0.18 of reactxp-navigation -_Released 10 Apr 2018_ -Fixed bug in web implementation that caused a problem when popping multiple items from the navigation stack. - -#### Version 0.2.10 of reactxp-imagesvg -#### Version 1.0.17 of reactxp-navigation -#### Version 0.2.5 of reactxp-video -#### Version 0.1.9 of reactxp-virtuallistview -_Released 4 Apr 2018_ -Rebuilt using reactxp 1.1.0. - -#### Version 1.1.0 of reactxp -_Released 4 Apr 2018_ -Added workaround to enable the keyboard navigation mode when the screen reader is used. - -#### Version 1.1.0-rc.2 of reactxp -_Released 28 Mar 2018_ -Fixed bug in web implementation of animation where completion callback was called multiple times in some cases. - -#### Version 1.1.0-rc.1 of reactxp -_Released 26 Mar 2018_ -Added support for "cacheable" popups. This is useful for popups that involve many views and are costly to recreate from scratch. -Fixed keyboard handler in RX.Link, it was defferring to base class only when onPress was defined, and that was wrong. -Fixed bug in native implementation of TextInput where selection was sometimes lost. -Fixed TextInput reference for focus control on windows. -Implemented hidden scroll indicators in web/ScrollView. - -#### Version 1.0.2 of reactxp -_Released 16 Mar 2018_ -Fixed bug in web TextInput implementation that resulted in a console warning with the latest versions of ReactJS. -Fixed bug in native Button implementation that resulted in corrupted styles. -Fixed accessibility (screen reader) bug in web implementation. - -#### Version 1.0.1 of reactxp -_Released 5 Mar 2018_ -Moved event handlers from ViewProps to ViewPropsShared so AnimatedView has them too. -Fixed recent regression in handling of popups in native implementation. -Events passed to onPress and onLongPress now include touch or mouse coordinates. - -#### Version 0.2.9 of reactxp-imagesvg -#### Version 1.0.16 of reactxp-navigation -#### Version 0.2.4 of reactxp-video -#### Version 0.1.8 of reactxp-virtuallistview -_Released 2 Mar 2018_ -Rebuilt using reactxp 1.0.0 and latest typescript compiler version. - -#### Version 1.0.0 of reactxp -_Released 2 Mar 2018_ -Filled in fields for MouseEvent on web. -Fixed a few style leaks in web implementation. - -#### Version 1.0.0-rc.1 of reactxp -_Released 28 Feb 2018_ - -Improved accessibility handling for Button. -Added select() method to RX.Platform namespace to make it easier to implement platform-specific behavior. -Improved accessibility performance. -Improved performance by avoiding triggering synchronous layout on web. -Fixed behavior of onContextMenu. -Removed unused "type" field from RX.CommonProps interface. -Updated typescript compiler to 2.7.2 and enabled strictPropertyInitialization. -Added ability to set limitFocusWithin without automatically setting aria-hidden=true on web. -Implemented RX.Linking APIs for Windows UWP platform. -Removed "currentTarget" from SyntheticEvent. -Added coordinates/modifiers/button information to MouseEvent definition. - -#### Version 1.0.0-alpha.2 of reactxp -_Released 21 Feb 2018_ - -Switched to new versioning scheme that's independent of RN. -Updated default RN dependency from 0.51.x to 0.53.x, although backward compatibility is maintained. -Added support for numeric keyboards in mobile browsers. -Fixed announceForAccessibility API for Mac. -Added MacOS implementation of Button and Animated. -Added valuenow attribute for slider role support. -Fixed bug in web implementation of Animated where it wasn't properly managing listener subscriptions when animated styles were added to (or removed from) an animated component. -Fix random Android crashes when Talkback is enabled. -Fixed bug in web animation that caused certain CSS properties not to animate correctly because transition was specifying the attribute using camel case rather than CSS (hyphenated) case. This affected attributes like "backgroundColor". -Removed parameter from onBlur event. -Fixed bug in RX.TextInput that affected Windows version: Pass selection in render only after explicitly set. -Added right-click support for Windows platform. -Added more accessibility support for Windows platform. -Use white-space:pre for the aria-live region. - -#### Version 0.51.1 of reactxp -_Released 19 Jan 2018_ - -Fixed regression in native implementation of Animated.View's blur() method. - -#### Version 0.2.3 of reactxp-video -#### Version 1.0.15 of reactxp-navigator -#### Version 0.2.8 of reactxp-imagesvg -#### Version 0.1.7 of reactxp-virtuallistview -_Released 18 Jan 2018_ - -Updated for RN 0.51 compatibility. - - -#### Version 0.51.0 of reactxp -_Released 18 Jan 2018_ - -Fixed focusable View condition for VoiceOver in web implementation. -Exposed web-specific ariaRoleDescription prop to work around other VoiceOver issues. -Updated RN for Windows UWP dependency. -Fixed recent regression that broke focus and blur calls in iOS and Android implementations of AnimatedTextInput. - -#### Version 0.51.0-alpha.9 of reactxp -_Released 17 Jan 2018_ - -Removed console error related to animations of values not currently associated with any mounted component. It was too noisy. - -#### Version 0.51.0-alpha.8 of reactxp -_Released 16 Jan 2018_ - -Fixed bug in Windows UWP implementation related to selection ranges in TextInput. -Fixed screen reader issue in Mac implementation. -Removed ```textAlign``` prop from TextInput. It was extraneous, since it's already supported as a style attribute. -Updated Windows UWP dependency to use the latest version of RN for UWP. -Worked around issue with screen readers on Chrome browsers. -Added currentTarget field back to SyntheticEvent. -Added support for "switch" aria type (web implementation). -Fixed recent regression in web animation code. - -#### Version 0.51.0-alpha.5 of reactxp -_Released 11 Jan 2018_ - -Eliminated limitation within RX.Button where only one child element was allowed. -Fixed regression where native implementation of RX.View with onPress handler didn't provide touch feedback. - -#### Version 0.51.0-alpha.4 of reactxp -_Released 10 Jan 2018_ - -Added code to native implementation of RX.Network so it works with versions of RN before and after 0.48.x. -Fixed regression in web implementation of RX.TextInput. -Fixed bug that caused incorrect behavior of RX.Modal on native platforms. - -#### Version 0.51.0-alpha.2 of reactxp -_Released 9 Jan 2018_ - -Fixed bug in native implementation of RX.ActivityIndicator. It wasn't properly handling the delay prop. -Added support in web implementation of RX.TextInput for custom keyboard types on mobile web browsers. -Added focus and keyboard navigation support for native UWP platform. -Added support for injection of HTML content into RX.WebView. -Added support for postMessage and onMessage handler in RX.WebView for bidirectional communication. - -#### Version 0.51.0-alpha.1 of reactxp -_Released 6 Jan 2018_ - -Fixed break in device dimension change event due to change in RN. -Removed use of RX.Button implementation within RX.View for native-common implementation. -Fixed bug in web implementation of RX.Clipboard.getText. It shouldn't throw. -Fixed timing bug in web implementation of GestureView. -Fixed popup positioning for right-to-left languages in native-common implementation. -Fixed bug in web implementation of TextInput that caused assertion in React. -Breaking change: Removed 'cursor' prop from RX.Button. It was redundant with the 'cursor' style. -New feature: RX.Input.key[Up|Down]Event now allow event subscribers to cancel the event. -New feature: Changed RX.Modal.isDisplayed to accept undefined parameter, in which case it determines whether _any_ modal is displayed. -New feature: Added RX.Popup.isDisplayed method. -Reimplemented web implementation of animation APIs. Removed many limitations of previous implementation and fixed several bugs. Documented remaining limitations. -Fixed bug in web implementation of RX.TextInput that resulted in assertions within React. -Fixed bug in web implementation of RX.Picker. It wasn't correctly combining styles. -Added support in web implementation of RX.TextInput for keyboard type (applicable on mobile web browsers). -Removed use of deprecated RX.NetInfo.fetch method. - -#### Version 0.46.6 of reactxp -_Released 13 Dec 2017_ - -Fixed potential crash in web implementation of RX.ScrollView. -Fixed bug in UWP implementation of RX.Popup, allowing background to be clickable. -In web implementation of RX.ScrollView, added support for clicking on scroll bar to adjust position of thumb. -Added dev warning when using nested RX.Button items. -Fixed a potential crash in web implementation of RX.GestureView. -Implemented drag-and-drop support in UWP implementation of RX.View. - -#### Version 0.46.5 of reactxp -_Released 31 Oct 2017_ - -Added Android "mode" prop to Picker. -Added type definitions for RX.Stateless and RX.ComponentBase. -Updated to React 16.0.0 and React-Dom 16.0.0. -Added RX.UserInterface.registerRootView API to allow registration of secondary views. Also added rootViewId option to RX.Modal and RX.Popup so they can be displayed on secondary views. -Fixed bug in focus restoration on web implementation. -Replaced use of deprecated BackAndroid with BackHandler, avoiding deprecation warnings. -Fixed bug in RX.Button RN implementation where opacity was not property restored after changing disabled prop. - -#### Version 0.46.3 of reactxp -_Released 7 Oct 2017_ - -Added missing focus() method to RX.Animated.View interface. -Exported RX.AnimatedImage, RX.AnimatedText, RX.AnimatedTextInput, and RX.AnimatedView. -Added accessibilityLiveRegion prop to ViewProps for Android and web. -Exported explicit types for ShadowOffset, ScrollIndicatorInsets. -Fixed crash in web RootView when clicking on a popup anchor. -Fixed race condition in hover of Button on web. - -#### Version 0.2.2 of reactxp-video -#### Version 1.0.13 of reactxp-navigator -#### Version 0.2.7 of reactxp-imagesvg -#### Version 0.1.6 of reactxp-virtuallistview -_Released 21 Sep 2017_ - -Updated for RN 0.46 compatibility. -Removed custom react.d.ts and react-dom.d.ts files in favor of public versions. - -#### Version 0.46.2 of reactxp -_Released 21 Sep 2017_ - -Added onContextMenu support on web for Text components. -Exposed attributes to make menus and listboxes accessible on web. -Added new RX.Animated.createValue and RX.Animated.interpolate methods. The old way of instantiating a value and creating an interpolation will be deprecated going forward. -Made a breaking change to Alert.show interface - combined optional parameters into an AlertOptions interface. This will allow for better extensibility in the future. -Updated RN dependency to 0.46. -Removed custom react.d.ts and react-dom.d.ts files in favor of public versions. - -#### Version 0.46.0_rc.2 of reactxp -_Released 19 Sep 2017_ - -Changed RX.Link props to make url mandatory. -Added new Alert implementation for web. It now presents a modal-based themable dialog box. -Fixed bug in ScrollView styles from previous release. -Exposed aria-checked property on button type for web. -Added key attribute to KeyboardEvent. -Fixed bug in web code where onScrollBeginDrag and onScrollEndDrag were called unconditionally even if they were undefined. -Enabled strict null checks in TS compiler and fixed a number of bugs that were exposed. - -#### Version 0.46.0_rc.1 of reactxp -_Released 5 Sep 2017_ - -First pre-release version of 0.46. -Removed Navigator component and moved to an extension. -Fixed style definition for ScrollView so it doesn't include child-related flexbox styles, which aren't supported. - -#### Version 0.42.0 of reactxp -_Released 5 Sep 2017_ - -Removed rc from version. - -#### Version 0.42.0_rc.25 of reactxp -_Released 18 Aug 2017_ - -On web, if there's a queued onScroll event when the scroll position is manually set, cancel the onScroll. - -#### Version 0.42.0_rc.24 of reactxp -_Released 9 Aug 2017_ - -Added accessibility support for GestureView. -Fixed bug in web version that prevented animated fontSize from working. - -#### Version 0.42.0_rc.22 of reactxp -_Released 30 July 2017_ - -On RN platforms, initialProps is now passed to the main view. -Added new PopupOptions field preventDismissOnPress that prevents the popup from being dismissed implicitly when the user clicks or taps outside of the popup or the anchor. -Fixed bug in web implementation of TextInput where border styling was not honored. -Fixed bug on Android that allowed presses to background of Modal to go through. - -#### Version 0.42.0_rc.20 of reactxp -_Released 15 July 2017_ - -Updated to TypeScript 2.4, which caught several bugs in the ReactXP code. -Made Styles.combine much more flexible - it now supports arbitrarily nested arrays of styles. -Changed Network API namespace for detecting network type so it's consistent with other ReactXP APIs. Added documentation. - -#### Version 0.1.6 of reactxp-video -_Released 15 July 2017_ - -Updated to TypeScript 2.4 and made changes to work with latest ReactXP core. - -#### Version 0.2.4 of reactxp-imagesvg -_Released 15 July 2017_ - -Updated to TypeScript 2.4 and made changes to work with latest ReactXP core. - -#### Version 0.42.0_rc.18 of reactxp -_Released 13 July 2017_ - -Fixed runtime crash when running web implementation in Electron. -Added a way to provide screen reader focus to TextInput on web. - -#### Version 0.42.0_rc.17 of reactxp -_Released 4 July 2017_ - -Added ability to set accessibility focus for text input controls. -Added support for iOS-specific ActivationState for RN extensions. - -#### Version 0.42.0_rc.16 of reactxp -_Released 30 June 2017_ - -Fixed another bug in handling of default border width on web. -Added setFocusRestricted and setFocusLimited methods and support for nested keyboard focus on web. -Added isNavigatingWithKdyboard method and keyboardNavigationEvent. - - -#### Version 0.42.0_rc.12 of reactxp -_Released 16 June 2017_ - -Added support for new limitFocusWidth prop for constraining keyboard focus. -Fixed bug in handling of mailto URLs on web in the Link component. -Added support for flexGrow, flexShrink, and flexBasis props. - - -#### Version 0.42.0_rc.11 of reactxp -_Released 13 June 2017_ - -Fixed bugs in web implementation of focus manager. -Added new API (enableTouchLatencyEvents) and event (touchLatencyEvent) in UserInterface namespace for detecting delays in touch event handling. -Fixed crash in native implementation of Link component that resulted in uncaught exception for some types of links. -Fixed flexDirection style default for web implementation in Image component. -Fixed inconsistency in handling of borders between web and RN when borderStyle is not specified. +Following semver rules, the major version (the first number in the version string) will be incremented for breaking changes. The minor version (the second number) will be incremented for major new functionality that does not break existing contracts or behaviors. -#### Version 0.42.0_rc.10 of reactxp -_Released 25 May 2017_ - -Added new International API namespace for controlling right-to-left mirroring behavior. - - -#### Version 0.1.2 of reactxp-virtualistview -_Released 23 May 2017_ - -Republished because index files were missing in previous publish. - - -#### Version 0.42.0_rc.9 of reactxp -_Released 17 May 2017_ - -Fixed bug in Navigator that caused crash in hello-world sample. - - -#### Version 0.42.0_rc.8 of reactxp -_Released 16 May 2017_ - -Removed Profiling API namespace and dependency on react-addons-perf. - - -#### Version 0.1.1 of reactxp-virtualistview -_Released 11 May 2017_ - -Republished because "dist" directory was missing in previous publish. - - -#### Version 0.1.2 of reactxp-video -_Released 11 May 2017_ - -Published first version of reactxp-video extension. - - -#### Version 0.2.0 of reactxp-imagesvg -_Released 10 May 2017_ - -Switched from old version of react-native-art-svg to latest version of react-native-svg. - - -#### Version 0.42.0_rc.5 of reactxp -_Released 10 May 2017_ - -Fixed incorrect import path (using wrong case). -Fixed bug in native View implementation - was using stale props. -Added importantForLayout prop on View (web specific). -Fixed bug in native NavigatorExperimentalDelegate - was using wrong props. - - -#### Version 0.42.0_rc.4 of reactxp -_Released 27 Apr 2017_ - -Changed web implementation of Text to prevent copying text to clipboard. -Eliminated the need to specify box-sizing CSS in external CSS file. -Fixed accessibility focus bugs. - - -#### Version 0.42.0_rc.3 of reactxp -_Released 26 Apr 2017_ - -Added onLongPress prop for Link. -Fixed accessibility bug relating to Modal dialogs. - - -#### Version 0.42.0_rc.2 of reactxp -_Released 18 Apr 2017_ - -Added missing box-sizing CSS directives for web. -Fixed bug in native implementation of View related to accessibility. - - -#### Version 0.1.0 of reactxp-imagesvg -_Released 26 Apr 2017_ - -Published first version of reactxp-imagesvg extension. - - -#### Version 0.42.0_rc.1 of reactxp -_Released 9 Apr 2017_ - -Updated project to use recent versions of React (15.5.3) and React Native (0.42.3). - +### Version History -#### Version 0.34.3 of reactxp -_Released 7 Apr 2017_ +#### Version 2.0.0 of reactxp - _30 November 2019_ +* All releases and notes going forward will be tracked on the [Github ReactXP Releases page](https://github.com/microsoft/reactxp/releases) + +#### Version 2.0.0-rc.2 of reactxp-video - _9 October 2019_ +* Updated react-native-video to 4.X + +#### Version 2.0.0-rc.2 of reactxp-webview - _12 September 2019_ +* Upgraded react-native-webview dependency + +#### Version 2.0.0-rc.1 of reactxp - _27 July 2019_ +* Adopted new major version number to reflect breaking changes with netinfo and webview. +* No other functionality since 1.7.0-rc.1 was published. + +#### Version 1.7.0-rc.1 of reactxp-video, reactxp-imagesvg, reactxp-navigation - _14 July 2019_ +* No new functionality, just version and dependency updates. + +#### Version 1.7.0-rc.1 of reactxp - _14 July 2019_ +* #1077: Added longPress support for web. +* #1080: Addes upport for delayLongPress on web. +* #1079: Fixed bug that caused onTouchMove not to trigger on mobile web. +* #1082: Added support on web for onTouchStart, onTouchEnd, and onTouchCancel props for RX.View. +* #1087: Added support on web for onHoverEnd. +* #1059: Improved support for RN 0.59. +* #1089: Added support on web for onTouchMoveCapture and onTouchStartCapture props of RX.View. +* #1098: Fixed bug on web where reference to HTML element was not released properly, resulting in leak. +* #1088: Added support on web for scrollEnabled prop in RX.ScrollView. +* #1098: Fixed bug in handling of images on RN platforms. +* #1118: Fixed bug on web related to pan gestures. +* #1114: Fixed crash on Android relating to TextInput event processing. +* #1102: Fixed bug on web where animated properties were not properly updated if they were interpolated. +* #1117: Added support on web for blockPointerEvents prop on RX.View. +* #1101: Extracted RX.WebView out of ReactXP core into an extension. +* #1091: Fixed bug on web in onPressIn processing where event could get triggered twice. + +#### Version 2.0.0 of reactxp-virtuallistview - _6 Apr 2019_ +* #1073: Removed internal string-based refs with React.RefObject. + +#### Version 1.6.1 of reactxp - _23 Mar 2019_ +* #1062: Fixed TextInput defaultValue not working on native platforms +* #1060: Fixed Ref type. +* #1058: Fixed ref assert on Windows. + +#### Version 1.6.1 of reactxp-video - _23 Mar 2019_ +* #1066: Fixed video extension to support react-native local assets. + +#### Version 1.6.1 of reactxp-navigation - _23 Mar 2019_ +* #1063: Fixed regression in reactxp-navigation. + +#### Version 1.6.0 of reactxp-imagesvg, reactxp-navigation, reactxp-video - _16 Mar 2019_ +* No new features; updated dependencies. + +#### Version 1.6.0 of reactxp - _16 Mar 2019_ +* No new features; updated dependencies. + +#### Version 1.6.0-rc.4 of reactxp - _15 Mar 2019_ +* #1055: Fixed crash due to incompatibilty with newly-released RN 59. + +#### Version 1.6.0-rc.3 of reactxp - _10 Mar 2019_ +* #891: Fixed bad interaction between RX.Clipboard.getText() and iOS Safari. + +#### Version 1.6.0-rc.2 of reactxp - _9 Mar 2019_ +* #1041: Fixed textDecorationStyle and textDecorationColor on web. +* #1042: Fixed transform rotate styles on web so they take a unit (e.g. "deg") for consistency with RN. +* #1040: Fixed auto-dismissing popups on the web. +* #1026: Changed margin and padding style combination rules on web to match RN. + +#### Version 1.6.0-rc.1 of reactxp - _17 Feb 2019_ +* #961: Fixed crash when calling setScrollTop/Left on native version of ScrollView. +* #972: If blurOnSubmit is specified on a TextInput, the code now respects that value. +* #974: Fixed bug in native Button implementation where 'false' style would be passed when disableTouchOpacityAnimation was specified. +* #980: Fixed bug in web implementation of onLongPress. +* #976: Made multiline TextInput growth behavior on web match native. +* #984: Added code to catch exception in web implementation of Storage.setItem method. +* #996: Added stronger typings for ref callbacks. +* #993: Added support for mediaPlaybackRequiresUserAction and allowsInlinedMediaPlayer props for WebView. +* #957: Added context mode to the popup container handling type list. +* #994: Removed msHyphens css property in web implementation of Text. +* #1001: Fixed units for rotateZ translation type for web animations. +* #1004: Fixed bug that resulted in crash when ReactXP ran in node (test) environment. +* #1006: Made selectItemKey scrollTo behaviour configurable - scrolling isn't always desired. +* #1016: View responder events props are now triggered properly. +* #1024: Added more mouse cursor types for web version of GestureView. +* Added support for interpolated animation values that have angle units (e.g. "90deg") on web. + +#### Version 2.0.0-rc.3 of reactxp-virtuallistview - _30 Jan 2019_ +* #1006: Make selectItemKey scrollTo behaviour configurable - scrolling isn't always desired +* #1007: Perf Improvements + +#### Version 2.0.0-rc.2 of reactxp-virtuallistview - _15 Jan 2019_ +* #989: Auto-scroll VLV on mount when initialScrollKey prop is provided +* #989: Fix keyboard scrolling bugs when non-keyboard-navigable items are interspersed with keyboard-navigable items + +#### Version 2.0.0-rc.1 of reactxp-virtuallistview - _11 Jan 2019_ +* #944: Rework VirtualListView for improved accessibility/performance (this contains breaking API changes - see documentation for new API) + +#### Version 1.5.0 of reactxp-imagesvg, reactxp-navigation, reactxp-video, reactxp-virtuallistview - _1 Dec 2018_ +* No new features; updated dependencies. + +#### Version 1.5.0 of reactxp - _1 Dec 2018_ +* #935: Maded ReactXP compatible with React.Fragment. +* #933: Reset VoiceOver queue when app goes inactive or in background (iOS and Windows). +* #939: Added keyboard event mapping for kePress handling in View (Windows and MacOS). +* #941: Updated RX.Animated.InterpolatedValue to allow for chaining interpolations. +* #942: Added key mappings for MacOS and wired onKeyPress for RX.View. +* #943: Added focus and blur calls for RX.Button, RX.Link, RX.Text and RX.View. +* #946: Fixed crashing bug in accessibility for iOS and MacOS. +* #949: Added onFocus, onBlur and onKeyPress support for GestureView. +* #948: Respect negative tabIndex in Button on MacOS. +* #953: Wired up tabIndex prop for web implementation of RX.TextInput. + +#### Version 1.5.0-rc.4 of reactxp - _18 Nov 2018_ +* #909: Eliminated not-prebound callbacks in view resize detector on web (perf improvement). +* #912: Fixed VoiceOver iOS 12 issue. +* #913 and #923: Added key codes that are specific for MacOS. +* #916: Added basic tabindex handling on views for MacOS. +* #920: Removed deep comparison on every button prop change (perf improvement). +* #917: Added onKeyDown support for MacOS ScrollView. +* #922: Removed undocumented and broken (onRN) API: addToScrolLeft and addToScrollTop on RX.ScrollView. +* #928: Fixed bug in _buildInternalProps of View relating to tabIndex. +* #927: Fixed drag support on MacOS. +* Added CONTRIBUTION guide. + +#### Version 1.5.0-rc.1 of reactxp-virtuallistview - _11 Nov 2018_ +* #899: Fix web accessibility +* #902: Mac accessibility improvements (keyboard focus). + +#### Version 1.5.0-rc.3 of reactxp - _11 Nov 2018_ +* #898: Ensure taht onKeyDown/Focus/Blur events are sent from ScrollView. +* #895: On Windows, make FocusManager track View instances with negative tabIndex. +* #901: Optimization on native platforms: when there are no accessibilityTraits, don't create an additional unneeded array. +* #902: Mac accessibility improvements (keyboard focus). + +#### Version 1.5.0-rc.2 of reactxp - _28 Oct 2018_ +* Fixed regression introduced recently in web version of ScrollView. + +#### Version 1.5.0-rc.1 of reactxp - _27 Oct 2018_ +New functionality: +* #848: Added support for RTL (right-to-left) change event on native platforms. +* #843: Added new AlertOption preventDismissOnPress. +* #847: Added support for Animated.Event, which allows animations to be associated with scroll events. +* #868: Added support for placeholder text color on web platform. +Bug fixes: +* #833: Eliminated rerender of app when mousing over popups. +* #846: Disabled mouse gestures in main view when a modal dialog is overlaying the main view. +* #854: Removed draggable="false" in web implementation of View, since this is the default value. +* #853: Emulate cache-control: max stale on iOS. +* #869: Eliminate excess focus calls. +* #877 and #875: Fixed crashes relating to popups due to race condition in unmounting. +* #873: Fixed scroll view focus issue on MacOS. +* Fixed several "hanging promises" that didn't properly deal with error conditions. + +#### Version 1.4.0 of reactxp - _30 Sep 2018_ +* Added the ability to programmatically retrieve the text selection for RX.Text (if selectable attribute is true). Includes test cases in RXPTest sample. +* Added drag and drop capabilities to RX.View (including onDragStart, onDrag, onDragEnd props). Includes test cases in RXPTest sample. + +#### Version 1.4.0-rc.1 of reactxp-navigation - _21 Sep 2018_ +* Changed renderScene to accept a return value of null rather than undefined, making it consistent with other render functions. + +#### Version 1.4.0-rc.2 of reactxp - _15 Sep 2018_ +* Fixed bug #800: If there are only cached popups and no visible one the main remains inaccessible for screen readers. +* Fixed bug #815: Show warning in console if disallowed style combinations appear. + +#### Version 1.4.0-rc.1 of reactxp - _9 Sep 2018_ +* Worked around change in recent versions of RN that removed support for Images with children. +* Changed announceForAccessibility implementation to use Assertive live region type instead of Polite. +* In web implementation of RX.Image, always show the img tag if XHR request option is used. +* Fixed bug #744: On web implementation, styling behavior differed between developmenta nd production. +* Added support for the new React.RefObject variant of ref prop. +* Added support for multi-window apps to RX.Alert. +* Added support for onLongPress to RX.GestureView. +* Fixed bug #793: In web implementation, cursor type was overridden in some cases. +* Added useWebKit prop for native RN.WebView in prep for NR 0.57 on iOS. +* Fixed bug that caused testID not to be set properly for RX.View instances. + +#### Version 1.3.2 of reactxp-imagesvg - _25 Aug 2018_ +* Added support for SvgRect children within SvgImage. + +#### Version 1.3.1 of reactxp-imagesvg - _7 Aug 2018_ +* Fixed bug in native implementation that caused runtime warning every time SvgPath was used. + +#### Version 1.3.2 of reactxp - _2 Aug 2018_ +* Fixed bug #745: WebView.onMessage receives additional props which are not defined in Types.WebViewMessageEvent. +* Fixed bug #746 relating to cursor overrides for buttons on the web implementation. +* Fixed bug #749: Set size attribute of input HTML element to 1. +* Fixed bug #753: isRightMouseButton implementation that works also on Mac. +* Fixed bug #752: Accessibility fix for Clipboard. +* Fixed bug #756: Prevent a crash during onLayout handling on web. +* Fixed bug #761: Update usages of findDOMNode to indicate that it returns null. +* Fixed bug #767: buttonStyles may be undefined; fixed inconsistency in onAccessibilityTapIOS definition for Button and View. +* Fixed regression in Timers.ts. Some environments don't define "global" and use "window" instead for the built-in timer functions. +* Use semver for reactxp dependencies. +* Feature #764: Add support for Android WebView compatibility modes. + +#### Version 1.3.1 of reactxp-virtuallistview - _2 Aug 2018_ +* Added support for testId prop. + +#### Version 1.3.2 of reactxp - _7 Jul 2018_ +* Updated custom tslint rule groupedImportRule to treat imports starting with '@' as relative rather than ambient. +* Made 'auto' a valid resizeMode for images in web implementation. +* Added support for 'title' prop on RX.TextInput. + +#### Version 1.3.0 of reactxp-imagesvg, reactxp-navigation, reactxp-video, reactxp-virtuallistview - _28 Jun 2018_ +* No new features; updated dependencies. + +#### Version 1.3.0 of reactxp - _28 Jun 2018_ +* Added support for function keys in native desktop implmenetations. +* Fixed recent regression that caused a crash when using the web implementation in a non-browser environment like node. +* Reverted change in behavior on web implementation of ActivityState.Inactive. This state is no longer used on the web, as before 1.3.0-rc.4. + +#### Version 1.3.0-rc.6 of reactxp - _25 Jun 2018_ +* Added support for testId prop to all reactxp components. On native, it uses testID. On web, it adds a data-test-id attribute to the node. +* Added three new tslint custom rules that are useful for reactxp projects. + +#### Version 1.3.0-rc.5 of reactxp - _24 Jun 2018_ +* Added missing definition for getMetadata method in RX.Image. +* Implemented RX.International methods for web platform. + +#### Version 1.3.0-rc.4 of reactxp - _19 Jun 2018_ +* Enabled context menu on keyboard input in Windows UWP implementation. +* On web implementation, augmented AppActivityState. Inactive state now indicates that main window is not in focus. +* On web implementation, eliminated dependency on ifvisible library, shrinking the footprint of reactxp. + +#### Version 1.3.0-rc.3 of reactxp - _16 Jun 2018_ +* [Breaking Change] Removed hideDeleteButton prop in RX.TextInput in favor of clearButtonMode prop, which applies to iOS and Windows UWP. + +#### Version 1.3.0-rc.2 of reactxp - _14 Jun 2018_ +* [Breaking Change] Renamed several methods in RX.Animated.ValueListener that were meant to be private. +* Improved screen reader support in Windows UWP implementation. +* On iOS implementation, automatically set decelerationRate to "fast" if snapToInterval is set. +* Added hideDeleteButton prop to RX.TextInput for Windows UWP. + +#### Version 1.3.0-rc.1 of reactxp - _13 Jun 2018_ +* Fixed accessibility issues with screen reader in Windows UWP implementation. +* Removed shouldRasterizeIOS prop on RX.Image. It was never supported in RN, so it was just a no-op. +* Fixed bug in RX.Network.getType() which returned the wrong response if the device was connected to ethernet on Android. + +#### Version 1.3.0-rc.0 of reactxp - _10 Jun 2018_ +* Fixed a few bugs in keyboard focus handling for Windows UWP. +* Web implementation of RX.Image now uses credentials for image fetches if origin header is specified. +* Added support for text shadows in RX.Text (shadowColor, shadowOffset, shadowRadius style attributes). +* Fixed keyboard navigation logic for multi-root-view case. +* Wired up tooltips in web implementation of RX.Button, RX.Image, RX.Link, and RX.View (title prop). +* Extended RX.UserInterface.measureWindow to support multi-root-view case. It now takes an optional rootViewId parameter. +* Added drag and drop handler support for Mac OS. +* Added new static API RX.Image.getMetadata that returns dimensions of an image. +* Avoided the use of the deprecated RN.NetInfo "change" event in favor of "connectionChange" so RN doesn't emit warning. +* Added back parameter to onBlur event handler that was incorrectly removed in version 1.2.x. + +#### Version 1.2.1 of reactxp - _24 May 2018_ +* Wired up onPaste handler for Windows implementation. +* Fixed bug that resulted in cached popups to appear when they shouldn't. +* Fixed bug in web implementation of RX.ScrollView that resulted in incorrect screen reader announcements. + +#### Version 1.2.0 of reactxp-imagesvg, reactxp-navigation, reactxp-video, reactxp-virtuallistview - _22 May 2018_ +* Automatically suppressed system context menu for selectable RX.Text items on Windows if containing view has onContextMenu handler. + +#### Version 1.2.0 of reactxp - _22 May 2018_ +* Automatically suppressed system context menu for selectable RX.Text items on Windows if containing view has onContextMenu handler. + +#### Version 1.1.2-rc.3 of reactxp - _21 May 2018_ +* Fixed bug in RX.Linking.getInitialUrl, which was returning null rather than undefined for the url in some cases. +* Added support for Dilaog trait to trigger yes-dont-hide importantForAccessibility behavior in Windows implementation. +* Fixed UWP accessibility announce to make it act the same way as Android. +* Create correct Animated.TextInput for Windows. + +#### Version 1.1.2-rc.2 of reactxp - _15 May 2018_ +* Improved keyboard focus support. Added focus, blur and requestFocus methods to several existing components. Added new focusArbitrator prop to RX.View, which allows callback to arbitrate between multiple children that are requesting autofocus. +* Fixed bug that caused group view children to be invisible to UI automation. +* Improved keyboard support for Windows implementation. + +#### Version 1.1.2-rc.1 of reactxp - _9 May 2018_ +* Fixed bug in Windows implementation that prevented RX.Input.keyDownEvent from being dispatched. +* Fixed bugs in Windows implementation that reported wrong key codes for keyboard events. +* Fixed focus management for cacheable popups in Windows implementation. +* Fixed type definitions of GestureView, ScrollView and WebView. They were incorrectly extending ViewBase, which pulled in a number of unsupported props. +* Fixed bug that caused cached popups to appear on screen when not appropriate. +* Added onContextMenu prop to GestureView. +* Added accessibility trait for ListItem. +* In Windows implementation, use RNW.Hyperlink for rendering RX.Link. +* Removed "justifyEnd" prop from RX.ScrollView. It was never implemented as documented. +* Added useSafeInsets prop onR X.View to support rendering within safe area on iOS. +* Fixed bug RX.StatusBar.setBarStyle where animated parameter was not properly passed to RN. +* Added onContextMenu to RX.Link. + +#### Version 1.1.1 of reactxp - _13 Apr 2018_ +* Fixed reentrancy issue in popup support. Displaying a popup from within the onDismiss callback was recently broken. +* Added disabledOpacity prop for RX.Button component. +* Improved handling of RX.Clipboard.setText on web. It now properly handles carriage returns. +* Fixed TextInput focusability after focus restriction on Windows. +* Fixed accessibility issue related to voice over on web. + +#### Version 1.0.18 of reactxp-navigation - _10 Apr 2018_ +* Fixed bug in web implementation that caused a problem when popping multiple items from the navigation stack. + +#### Version 0.2.10 of reactxp-imagesvg, 1.0.17 of reactxp-navigation, 0.2.5 of reactxp-video, 0.1.9 of reactxp-virtuallistview - _4 Apr 2018_ +* Rebuilt using reactxp 1.1.0. + +#### Version 1.1.0 of reactxp - _4 Apr 2018_ +* Added workaround to enable the keyboard navigation mode when the screen reader is used. + +#### Version 1.1.0-rc.2 of reactxp - _28 Mar 2018_ +* Fixed bug in web implementation of animation where completion callback was called multiple times in some cases. + +#### Version 1.1.0-rc.1 of reactxp - _26 Mar 2018_ +* Added support for "cacheable" popups. This is useful for popups that involve many views and are costly to recreate from scratch. +* Fixed keyboard handler in RX.Link, it was defferring to base class only when onPress was defined, and that was wrong. +* Fixed bug in native implementation of TextInput where selection was sometimes lost. +* Fixed TextInput reference for focus control on windows. +* Implemented hidden scroll indicators in web/ScrollView. + +#### Version 1.0.2 of reactxp - _16 Mar 2018_ +* Fixed bug in web TextInput implementation that resulted in a console warning with the latest versions of ReactJS. +* Fixed bug in native Button implementation that resulted in corrupted styles. +* Fixed accessibility (screen reader) bug in web implementation. + +#### Version 1.0.1 of reactxp - _5 Mar 2018_ +* Moved event handlers from ViewProps to ViewPropsShared so AnimatedView has them too. +* Fixed recent regression in handling of popups in native implementation. +* Events passed to onPress and onLongPress now include touch or mouse coordinates. + +#### Version 0.2.9 of reactxp-imagesvg, 1.0.16 of reactxp-navigation, 0.2.4 of reactxp-video, 0.1.8 of reactxp-virtuallistview - _2 Mar 2018_ +* Rebuilt using reactxp 1.0.0 and latest typescript compiler version. + +#### Version 1.0.0 of reactxp - _2 Mar 2018_ +* Filled in fields for MouseEvent on web. +* Fixed a few style leaks in web implementation. + +#### Version 1.0.0-rc.1 of reactxp - _28 Feb 2018_ +* Improved accessibility handling for Button. +* Added select() method to RX.Platform namespace to make it easier to implement platform-specific behavior. +* Improved accessibility performance. +* Improved performance by avoiding triggering synchronous layout on web. +* Fixed behavior of onContextMenu. +* Removed unused "type" field from RX.CommonProps interface. +* Updated typescript compiler to 2.7.2 and enabled strictPropertyInitialization. +* Added ability to set limitFocusWithin without automatically setting aria-hidden=true on web. +* Implemented RX.Linking APIs for Windows UWP platform. +* Removed "currentTarget" from SyntheticEvent. +* Added coordinates/modifiers/button information to MouseEvent definition. + +#### Version 1.0.0-alpha.2 of reactxp - _21 Feb 2018_ +* Switched to new versioning scheme that's independent of RN. +* Updated default RN dependency from 0.51.x to 0.53.x, although backward compatibility is maintained. +* Added support for numeric keyboards in mobile browsers. +* Fixed announceForAccessibility API for Mac. +* Added MacOS implementation of Button and Animated. +* Added valuenow attribute for slider role support. +* Fixed bug in web implementation of Animated where it wasn't properly managing listener subscriptions when animated styles were added to (or removed from) an animated component. +* Fix random Android crashes when Talkback is enabled. +* Fixed bug in web animation that caused certain CSS properties not to animate correctly because transition was specifying the attribute using camel case rather than CSS (hyphenated) case. This affected attributes like "backgroundColor". +* Removed parameter from onBlur event. +* Fixed bug in RX.TextInput that affected Windows version: Pass selection in render only after explicitly set. +* Added right-click support for Windows platform. +* Added more accessibility support for Windows platform. +* Use white-space:pre for the aria-live region. + +#### Version 0.51.1 of reactxp - _19 Jan 2018_ +* Fixed regression in native implementation of Animated.View's blur() method. + +#### Version 0.2.3 of reactxp-video, 1.0.15 of reactxp-navigator, 0.2.8 of reactxp-imagesvg, 0.1.7 of reactxp-virtuallistview - _18 Jan 2018_ +* Updated for RN 0.51 compatibility. + +#### Version 0.51.0 of reactxp - _18 Jan 2018_ +* Fixed focusable View condition for VoiceOver in web implementation. +* Exposed web-specific ariaRoleDescription prop to work around other VoiceOver issues. +* Updated RN for Windows UWP dependency. +* Fixed recent regression that broke focus and blur calls in iOS and Android implementations of AnimatedTextInput. + +#### Version 0.51.0-alpha.9 of reactxp - _17 Jan 2018_ +* Removed console error related to animations of values not currently associated with any mounted component. It was too noisy. + +#### Version 0.51.0-alpha.8 of reactxp - _16 Jan 2018_ +* Fixed bug in Windows UWP implementation related to selection ranges in TextInput. +* Fixed screen reader issue in Mac implementation. +* Removed ```textAlign``` prop from TextInput. It was extraneous, since it's already supported as a style attribute. +* Updated Windows UWP dependency to use the latest version of RN for UWP. +* Worked around issue with screen readers on Chrome browsers. +* Added currentTarget field back to SyntheticEvent. +* Added support for "switch" aria type (web implementation). +* Fixed recent regression in web animation code. + +#### Version 0.51.0-alpha.5 of reactxp - _11 Jan 2018_ +* Eliminated limitation within RX.Button where only one child element was allowed. +* Fixed regression where native implementation of RX.View with onPress handler didn't provide touch feedback. + +#### Version 0.51.0-alpha.4 of reactxp - _10 Jan 2018_ +* Added code to native implementation of RX.Network so it works with versions of RN before and after 0.48.x. +* Fixed regression in web implementation of RX.TextInput. +* Fixed bug that caused incorrect behavior of RX.Modal on native platforms. + +#### Version 0.51.0-alpha.2 of reactxp - _9 Jan 2018_ +* Fixed bug in native implementation of RX.ActivityIndicator. It wasn't properly handling the delay prop. +* Added support in web implementation of RX.TextInput for custom keyboard types on mobile web browsers. +* Added focus and keyboard navigation support for native UWP platform. +* Added support for injection of HTML content into RX.WebView. +* Added support for postMessage and onMessage handler in RX.WebView for bidirectional communication. + +#### Version 0.51.0-alpha.1 of reactxp - _6 Jan 2018_ +* Fixed break in device dimension change event due to change in RN. +* Removed use of RX.Button implementation within RX.View for native-common implementation. +* Fixed bug in web implementation of RX.Clipboard.getText. It shouldn't throw. +* Fixed timing bug in web implementation of GestureView. +* Fixed popup positioning for right-to-left languages in native-common implementation. +* Fixed bug in web implementation of TextInput that caused assertion in React. +* Breaking change: Removed 'cursor' prop from RX.Button. It was redundant with the 'cursor' style. +* New feature: RX.Input.key[Up|Down]Event now allow event subscribers to cancel the event. +* New feature: Changed RX.Modal.isDisplayed to accept undefined parameter, in which case it determines whether _any_ modal is displayed. +* New feature: Added RX.Popup.isDisplayed method. +* Reimplemented web implementation of animation APIs. Removed many limitations of previous implementation and fixed several bugs. Documented remaining limitations. +* Fixed bug in web implementation of RX.TextInput that resulted in assertions within React. +* Fixed bug in web implementation of RX.Picker. It wasn't correctly combining styles. +* Added support in web implementation of RX.TextInput for keyboard type (applicable on mobile web browsers). +* Removed use of deprecated RX.NetInfo.fetch method. + +#### Version 0.46.6 of reactxp - _13 Dec 2017_ +* Fixed potential crash in web implementation of RX.ScrollView. +* Fixed bug in UWP implementation of RX.Popup, allowing background to be clickable. +* In web implementation of RX.ScrollView, added support for clicking on scroll bar to adjust position of thumb. +* Added dev warning when using nested RX.Button items. +* Fixed a potential crash in web implementation of RX.GestureView. +* Implemented drag-and-drop support in UWP implementation of RX.View. + +#### Version 0.46.5 of reactxp - _31 Oct 2017_ +* Added Android "mode" prop to Picker. +* Added type definitions for RX.Stateless and RX.ComponentBase. +* Updated to React 16.0.0 and React-Dom 16.0.0. +* Added RX.UserInterface.registerRootView API to allow registration of secondary views. Also added rootViewId option to RX.Modal and RX.Popup so they can be displayed on secondary views. +* Fixed bug in focus restoration on web implementation. +* Replaced use of deprecated BackAndroid with BackHandler, avoiding deprecation warnings. +* Fixed bug in RX.Button RN implementation where opacity was not property restored after changing disabled prop. + +#### Version 0.46.3 of reactxp - _7 Oct 2017_ +* Added missing focus() method to RX.Animated.View interface. +* Exported RX.AnimatedImage, RX.AnimatedText, RX.AnimatedTextInput, and RX.AnimatedView. +* Added accessibilityLiveRegion prop to ViewProps for Android and web. +* Exported explicit types for ShadowOffset, ScrollIndicatorInsets. +* Fixed crash in web RootView when clicking on a popup anchor. +* Fixed race condition in hover of Button on web. + +#### Version 0.2.2 of reactxp-video, 1.0.13 of reactxp-navigator, 0.2.7 of reactxp-imagesvg, 0.1.6 of reactxp-virtuallistview - _21 Sep 2017_ +* Updated for RN 0.46 compatibility. +* Removed custom react.d.ts and react-dom.d.ts files in favor of public versions. + +#### Version 0.46.2 of reactxp - _21 Sep 2017_ +* Added onContextMenu support on web for Text components. +* Exposed attributes to make menus and listboxes accessible on web. +* Added new RX.Animated.createValue and RX.Animated.interpolate methods. The old way of instantiating a value and creating an interpolation will be deprecated going forward. +* Made a breaking change to Alert.show interface - combined optional parameters into an AlertOptions interface. This will allow for better extensibility in the future. +* Updated RN dependency to 0.46. +* Removed custom react.d.ts and react-dom.d.ts files in favor of public versions. + +#### Version 0.46.0_rc.2 of reactxp - _19 Sep 2017_ +* Changed RX.Link props to make url mandatory. +* Added new Alert implementation for web. It now presents a modal-based themable dialog box. +* Fixed bug in ScrollView styles from previous release. +* Exposed aria-checked property on button type for web. +* Added key attribute to KeyboardEvent. +* Fixed bug in web code where onScrollBeginDrag and onScrollEndDrag were called unconditionally even if they were undefined. +* Enabled strict null checks in TS compiler and fixed a number of bugs that were exposed. + +#### Version 0.46.0_rc.1 of reactxp - _5 Sep 2017_ +* First pre-release version of 0.46. +* Removed Navigator component and moved to an extension. +* Fixed style definition for ScrollView so it doesn't include child-related flexbox styles, which aren't supported. + +#### Version 0.42.0 of reactxp - _5 Sep 2017_ +* Removed rc from version. + +#### Version 0.42.0_rc.25 of reactxp - _18 Aug 2017_ +* On web, if there's a queued onScroll event when the scroll position is manually set, cancel the onScroll. + +#### Version 0.42.0_rc.24 of reactxp - _9 Aug 2017_ +* Added accessibility support for GestureView. +* Fixed bug in web version that prevented animated fontSize from working. + +#### Version 0.42.0_rc.22 of reactxp - _30 July 2017_ +* On RN platforms, initialProps is now passed to the main view. +* Added new PopupOptions field preventDismissOnPress that prevents the popup from being dismissed implicitly when the user clicks or taps outside of the popup or the anchor. +* Fixed bug in web implementation of TextInput where border styling was not honored. +* Fixed bug on Android that allowed presses to background of Modal to go through. + +#### Version 0.42.0_rc.20 of reactxp - _15 July 2017_ +* Updated to TypeScript 2.4, which caught several bugs in the ReactXP code. +* Made Styles.combine much more flexible - it now supports arbitrarily nested arrays of styles. +* Changed Network API namespace for detecting network type so it's consistent with other ReactXP APIs. Added documentation. + +#### Version 0.1.6 of reactxp-video - _15 July 2017_ +* Updated to TypeScript 2.4 and made changes to work with latest ReactXP core. + +#### Version 0.2.4 of reactxp-imagesvg - _15 July 2017_ +* Updated to TypeScript 2.4 and made changes to work with latest ReactXP core. + +#### Version 0.42.0_rc.18 of reactxp - _13 July 2017_ +* Fixed runtime crash when running web implementation in Electron. +* Added a way to provide screen reader focus to TextInput on web. + +#### Version 0.42.0_rc.17 of reactxp - _4 July 2017_ +* Added ability to set accessibility focus for text input controls. +* Added support for iOS-specific ActivationState for RN extensions. + +#### Version 0.42.0_rc.16 of reactxp - _30 June 2017_ +* Fixed another bug in handling of default border width on web. +* Added setFocusRestricted and setFocusLimited methods and support for nested keyboard focus on web. +* Added isNavigatingWithKdyboard method and keyboardNavigationEvent. + +#### Version 0.42.0_rc.12 of reactxp - _16 June 2017_ +* Added support for new limitFocusWidth prop for constraining keyboard focus. +* Fixed bug in handling of mailto URLs on web in the Link component. +* Added support for flexGrow, flexShrink, and flexBasis props. + +#### Version 0.42.0_rc.11 of reactxp - _13 June 2017_ +* Fixed bugs in web implementation of focus manager. +* Added new API (enableTouchLatencyEvents) and event (touchLatencyEvent) in UserInterface namespace for detecting delays in touch event handling. +* Fixed crash in native implementation of Link component that resulted in uncaught exception for some types of links. +* Fixed flexDirection style default for web implementation in Image component. +* Fixed inconsistency in handling of borders between web and RN when borderStyle is not specified. + +#### Version 0.42.0_rc.10 of reactxp - _25 May 2017_ +* Added new International API namespace for controlling right-to-left mirroring behavior. + +#### Version 0.1.2 of reactxp-virtualistview - _23 May 2017_ +* Republished because index files were missing in previous publish. + +#### Version 0.42.0_rc.9 of reactxp - _17 May 2017_ +* Fixed bug in Navigator that caused crash in hello-world sample. + +#### Version 0.42.0_rc.8 of reactxp - _16 May 2017_ +* Removed Profiling API namespace and dependency on react-addons-perf. + +#### Version 0.1.1 of reactxp-virtualistview - _11 May 2017_ +* Republished because "dist" directory was missing in previous publish. + +#### Version 0.1.2 of reactxp-video - _11 May 2017_ +* Published first version of reactxp-video extension. + +#### Version 0.2.0 of reactxp-imagesvg - _10 May 2017_ +* Switched from old version of react-native-art-svg to latest version of react-native-svg. + +#### Version 0.42.0_rc.5 of reactxp - _10 May 2017_ +* Fixed incorrect import path (using wrong case). +* Fixed bug in native View implementation - was using stale props. +* Added importantForLayout prop on View (web specific). +* Fixed bug in native NavigatorExperimentalDelegate - was using wrong props. + +#### Version 0.42.0_rc.4 of reactxp - _27 Apr 2017_ +* Changed web implementation of Text to prevent copying text to clipboard. +* Eliminated the need to specify box-sizing CSS in external CSS file. +* Fixed accessibility focus bugs. + +#### Version 0.42.0_rc.3 of reactxp - _26 Apr 2017_ +* Added onLongPress prop for Link. +* Fixed accessibility bug relating to Modal dialogs. + +#### Version 0.42.0_rc.2 of reactxp - _18 Apr 2017_ +* Added missing box-sizing CSS directives for web. +* Fixed bug in native implementation of View related to accessibility. -Added new props to ScrollView. Updated package.json to properly reflect peerDependencies on react and react-native. +#### Version 0.1.0 of reactxp-imagesvg - _26 Apr 2017_ +* Published first version of reactxp-imagesvg extension. +#### Version 0.42.0_rc.1 of reactxp - _9 Apr 2017_ +* Updated project to use recent versions of React (15.5.3) and React Native (0.42.3). -#### Version 0.34.1 of reactxp -_Released 6 Apr 2017_ +#### Version 0.34.3 of reactxp - _7 Apr 2017_ +* Added new props to ScrollView. Updated package.json to properly reflect peerDependencies on react and react-native. -This is the initial public release of the ReactXP core library. It is built against React Native 0.34. We are working on updating it to a newer version of React Native, and this will be released shortly. +#### Version 0.34.1 of reactxp - _6 Apr 2017_ +* This is the initial public release of the ReactXP core library. It is built against React Native 0.34. We are working on updating it to a newer version of React Native, and this will be released shortly. diff --git a/extensions/imagesvg/.eslintrc.json b/extensions/imagesvg/.eslintrc.json new file mode 100644 index 000000000..3ff892a96 --- /dev/null +++ b/extensions/imagesvg/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "parserOptions": { + "project": "./tsconfig.json" + }, + "extends": ["skype", "skype/react"], + "rules": {}, + "overrides": [ + { + "files": [ + "*.tsx" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + { + "files": [ + "PluginBaseChecker.ts" + ], + "rules": { + "@typescript-eslint/no-unused-vars": "off" + } + } + ] +} diff --git a/extensions/imagesvg/package.json b/extensions/imagesvg/package.json index 729e036ec..9017e0004 100644 --- a/extensions/imagesvg/package.json +++ b/extensions/imagesvg/package.json @@ -1,27 +1,33 @@ { "name": "reactxp-imagesvg", - "version": "1.2.0", + "version": "2.0.0", "description": "Plugin for ReactXP that provides support for SVG (scalable vector graphics) for all platforms", "author": "ReactXP Team ", "license": "MIT", "scripts": { - "build": "npm run tslint && tsc", - "tslint": "tslint -p tsconfig.json -r tslint.json -r ./node_modules/tslint-microsoft-contrib --fix || true" + "build": "tsc", + "lint": "eslint --ext .ts,.tsx src", + "lint:fix": "npm run lint -- --fix" }, "dependencies": { - "assert": "^1.3.0", - "react-native-svg": "^5.4.0", - "reactxp": "^1.2.0" + "react-native-svg": "^9.13.3" }, "peerDependencies": { - "react-dom": "16.2.0", - "react-native": "^0.51.0" + "react": "^16.3", + "reactxp": "^2.0.0", + "react-dom": "^16.3", + "react-native": ">=0.57", + "react-native-windows": "^0.57.1" }, "devDependencies": { - "@types/node": "^7.0.12", - "tslint": "5.10.0", - "tslint-microsoft-contrib": "5.0.3", - "typescript": "2.8.3" + "@types/react-native": "^0.60.23", + "@typescript-eslint/eslint-plugin": "2.15.0", + "eslint": "6.8.0", + "eslint-config-skype": "1.5.0", + "eslint-plugin-import": "2.19.1", + "eslint-plugin-react": "7.17.0", + "reactxp": "^2.0.0", + "typescript": "3.7.4" }, "types": "dist/web/PluginBase.d.ts" } diff --git a/extensions/imagesvg/src/android/PluginBase.tsx b/extensions/imagesvg/src/android/PluginBase.tsx index 787d1debf..5080b2ff8 100644 --- a/extensions/imagesvg/src/android/PluginBase.tsx +++ b/extensions/imagesvg/src/android/PluginBase.tsx @@ -1,13 +1,14 @@ /* -* PluginBase.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the Android implementation of the plugin. -*/ + * PluginBase.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Android implementation of the plugin. + */ +import * as Types from '../common/Types'; import ImageSvg from '../native-common/ImageSvg'; import SvgPath from '../native-common/SvgPath'; -import Types = require('../common/Types'); +import SvgRect from '../native-common/SvgRect'; -export { ImageSvg as default, SvgPath, Types }; +export { ImageSvg as default, SvgPath, SvgRect, Types }; diff --git a/extensions/imagesvg/src/common/Interfaces.ts b/extensions/imagesvg/src/common/Interfaces.ts index e5240c653..79c7b2f07 100644 --- a/extensions/imagesvg/src/common/Interfaces.ts +++ b/extensions/imagesvg/src/common/Interfaces.ts @@ -1,14 +1,14 @@ /* -* Interfaces.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Interface exposed by ImageSvg component. -*/ + * Interfaces.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Interface exposed by ImageSvg component. + */ -import React = require('react'); +import * as React from 'react'; -import Types = require('./Types'); +import * as Types from './Types'; export abstract class ImageSvg extends React.Component { } @@ -16,9 +16,13 @@ export abstract class ImageSvg extends React.Component export abstract class SvgPath extends React.Component { } +export abstract class SvgRect extends React.Component { +} + export interface PluginInterface { Types: typeof Types; - + default: typeof ImageSvg; SvgPath: typeof SvgPath; + SvgRect: typeof SvgRect; } diff --git a/extensions/imagesvg/src/common/PluginBaseChecker.ts b/extensions/imagesvg/src/common/PluginBaseChecker.ts index 5d4ac261a..f2b1672fb 100644 --- a/extensions/imagesvg/src/common/PluginBaseChecker.ts +++ b/extensions/imagesvg/src/common/PluginBaseChecker.ts @@ -1,23 +1,21 @@ /* -* PluginBaseChecker.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type check all the pluginbase exports against the desired interface. -*/ + * PluginBaseChecker.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type check all the pluginbase exports against the desired interface. + */ -import Interfaces = require('./Interfaces'); +import * as AndroidPlugin from '../android/PluginBase'; +import * as iOSPlugin from '../ios/PluginBase'; +import * as macOSPlugin from '../macos/PluginBase'; +import * as WebPlugin from '../web/PluginBase'; +import * as WindowsPlugin from '../windows/PluginBase'; -import AndroidPlugin = require('../android/PluginBase'); -import iOSPlugin = require('../ios/PluginBase'); -import macOSPlugin = require('../macos/PluginBase'); -import WebPlugin = require('../web/PluginBase'); -import WindowsPlugin = require('../windows/PluginBase'); +import * as Interfaces from './Interfaces'; -/* tslint:disable:no-unused-variable */ const _typeCheckerAndroid: Interfaces.PluginInterface = AndroidPlugin; const _typeCheckeriOS: Interfaces.PluginInterface = iOSPlugin; const _typeCheckermacOS: Interfaces.PluginInterface = macOSPlugin; const _typeCheckerWeb: Interfaces.PluginInterface = WebPlugin; const _typeCheckerWindows: Interfaces.PluginInterface = WindowsPlugin; -/* tslint:enable:no-unused-variable */ diff --git a/extensions/imagesvg/src/common/Types.ts b/extensions/imagesvg/src/common/Types.ts index d3de2454c..d3560d28a 100644 --- a/extensions/imagesvg/src/common/Types.ts +++ b/extensions/imagesvg/src/common/Types.ts @@ -1,15 +1,17 @@ /* -* Types.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definitions to support the plugin. -*/ + * Types.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type definitions to support the plugin. + */ import { Types as RXTypes } from 'reactxp'; +import * as React from 'react'; export interface ImageSvgStyle extends RXTypes.ViewStyle { } + export declare type ImageSvgStyleRuleSet = RXTypes.StyleRuleSet; export interface SvgCommonProps { @@ -21,7 +23,7 @@ export interface SvgCommonProps { fillOpacity?: number; } -export interface ImageSvgProps extends SvgCommonProps, RXTypes.CommonStyledProps { +export interface ImageSvgProps extends SvgCommonProps, RXTypes.CommonStyledProps { children?: RXTypes.ReactNode; height: number; width: number; @@ -31,6 +33,16 @@ export interface ImageSvgProps extends SvgCommonProps, RXTypes.CommonStyledProps preserveAspectRatio?: string; webShadow?: string; } + export interface SvgPathProps extends SvgCommonProps { d?: string; } + +export interface SvgRectProps extends SvgCommonProps { + width: number; + height: number; + x: number; + y: number; +} + +export class ImageSvg extends React.Component {} diff --git a/extensions/imagesvg/src/common/assert.ts b/extensions/imagesvg/src/common/assert.ts new file mode 100644 index 000000000..46aba16a5 --- /dev/null +++ b/extensions/imagesvg/src/common/assert.ts @@ -0,0 +1,14 @@ +/** + * assert + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + */ +const assert = (cond: any, message?: string | undefined): void => { + if (!cond) { + throw new Error(message || 'Assertion Failed'); + } +}; + +export default assert; diff --git a/extensions/imagesvg/src/ios/PluginBase.tsx b/extensions/imagesvg/src/ios/PluginBase.tsx index 69e3f7133..80f587975 100644 --- a/extensions/imagesvg/src/ios/PluginBase.tsx +++ b/extensions/imagesvg/src/ios/PluginBase.tsx @@ -1,13 +1,14 @@ /* -* PluginBase.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the iOS implementation of the plugin. -*/ + * PluginBase.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the iOS implementation of the plugin. + */ +import * as Types from '../common/Types'; import ImageSvg from '../native-common/ImageSvg'; import SvgPath from '../native-common/SvgPath'; -import Types = require('../common/Types'); +import SvgRect from '../native-common/SvgRect'; -export { ImageSvg as default, SvgPath, Types }; +export { ImageSvg as default, SvgPath, SvgRect, Types }; diff --git a/extensions/imagesvg/src/macos/PluginBase.tsx b/extensions/imagesvg/src/macos/PluginBase.tsx index 69e3f7133..80f587975 100644 --- a/extensions/imagesvg/src/macos/PluginBase.tsx +++ b/extensions/imagesvg/src/macos/PluginBase.tsx @@ -1,13 +1,14 @@ /* -* PluginBase.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the iOS implementation of the plugin. -*/ + * PluginBase.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the iOS implementation of the plugin. + */ +import * as Types from '../common/Types'; import ImageSvg from '../native-common/ImageSvg'; import SvgPath from '../native-common/SvgPath'; -import Types = require('../common/Types'); +import SvgRect from '../native-common/SvgRect'; -export { ImageSvg as default, SvgPath, Types }; +export { ImageSvg as default, SvgPath, SvgRect, Types }; diff --git a/extensions/imagesvg/src/native-common/ImageSvg.tsx b/extensions/imagesvg/src/native-common/ImageSvg.tsx index a2dc19ed5..8327b50ec 100644 --- a/extensions/imagesvg/src/native-common/ImageSvg.tsx +++ b/extensions/imagesvg/src/native-common/ImageSvg.tsx @@ -1,23 +1,21 @@ /** -* ImageSvg.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* RN-specific implementation of the cross-platform abstraction for -* SVG (scalable vector graphics) images. -*/ + * ImageSvg.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG (scalable vector graphics) images. + */ -import assert = require('assert'); -import React = require('react'); -import RNSvg = require('react-native-svg'); +import * as React from 'react'; +import * as RNSvg from 'react-native-svg'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import assert from '../common/assert'; +import { ImageSvgProps } from '../common/Types'; -export class ImageSvg extends React.Component { +export class ImageSvg extends React.Component { render() { - - assert.ok(this.props.width && this.props.height, 'The width and height on imagesvg are mandatory.'); + assert(this.props.width && this.props.height, 'The width and height on imagesvg are mandatory.'); if (this.props.width > 0 && this.props.height > 0) { return ( @@ -32,9 +30,9 @@ export class ImageSvg extends React.Component { { this.props.children } ); - } else { - return null; } + + return null; } } diff --git a/extensions/imagesvg/src/native-common/SvgPath.tsx b/extensions/imagesvg/src/native-common/SvgPath.tsx index cdbec63a2..feda5fbcc 100644 --- a/extensions/imagesvg/src/native-common/SvgPath.tsx +++ b/extensions/imagesvg/src/native-common/SvgPath.tsx @@ -1,29 +1,27 @@ /** -* SvgPath.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* RN-specific implementation of the cross-platform abstraction for -* SVG Path (scalable vector graphics) elements. -*/ + * SvgPath.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG Path elements. + */ -import React = require('react'); -import RNSvg = require('react-native-svg'); +import * as React from 'react'; +import * as RNSvg from 'react-native-svg'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import { SvgPathProps } from '../common/Types'; -export class SvgPath extends React.Component { +export class SvgPath extends React.Component { render() { return ( ); } diff --git a/extensions/imagesvg/src/native-common/SvgRect.tsx b/extensions/imagesvg/src/native-common/SvgRect.tsx new file mode 100644 index 000000000..42574236e --- /dev/null +++ b/extensions/imagesvg/src/native-common/SvgRect.tsx @@ -0,0 +1,33 @@ +/** + * SvgPath.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG Rect elements. + */ + +import * as React from 'react'; +import * as RNSvg from 'react-native-svg'; + +import { SvgRectProps } from '../common/Types'; + +export class SvgRect extends React.Component { + render() { + return ( + + ); + } +} + +export default SvgRect; diff --git a/extensions/imagesvg/src/typings/react-native-svg.d.ts b/extensions/imagesvg/src/typings/react-native-svg.d.ts index 564758a67..da4de9cf3 100644 --- a/extensions/imagesvg/src/typings/react-native-svg.d.ts +++ b/extensions/imagesvg/src/typings/react-native-svg.d.ts @@ -1,66 +1,66 @@ /** -* react-native-svg.d.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definition file for the React Native SVG module. -* https://github.com/react-native-community/react-native-svg -*/ + * react-native-svg.d.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type definition file for the React Native SVG module. + * https://github.com/react-native-community/react-native-svg + */ declare module 'react-native-svg' { - import React = require('react'); - import RN = require('react-native'); + import * as React from 'react'; + import * as RN from 'react-native'; type ArrayType = [string] | [number]; interface SvgProps extends RN.ComponentPropsBase { - height?: string, - width?: string, - viewBox?: string, - opacity?: number, + height?: string; + width?: string; + viewBox?: string; + opacity?: number; preserveAspectRatio?: string; style?: RN.StyleRuleSet; } interface BaseProps extends RN.ComponentPropsBase { - fill?: string, //The fill prop refers to the color inside the shape. - fillOpacity?: number, // This prop specifies the opacity of the color or the content the current object is filled with. - stroke?: string, //The stroke prop controls how the outline of a shape appears. - strokeWidth?: number, //The strokeWidth prop specifies the width of the outline on the current object. - strokeOpacity?: number, //The strokeOpacity prop specifies the opacity of the outline on the current object. - x?: number, - y?: number, - strokeLinecap?: string, //oneOf(['butt', 'square', 'round']), - strokeCap?: string, //.oneOf(['butt', 'square', 'round']), - strokeLinejoin?: string, //oneOf(['miter', 'bevel', 'round']), - strokeJoin?: string, //.oneOf(['miter', 'bevel', 'round']), - strokeDasharray?: ArrayType, - scale?: number, //Scale value on the current object. - rotate?: number, //Rotation degree value on the current object. - originX?: number, //Transform originX coordinates for the current object. - originY?: number //Transform originY coordinates for the current object. + fill?: string; // The fill prop refers to the color inside the shape. + fillOpacity?: number; // This prop specifies the opacity of the color or the content the current object is filled with. + stroke?: string; // The stroke prop controls how the outline of a shape appears. + strokeWidth?: number; // The strokeWidth prop specifies the width of the outline on the current object. + strokeOpacity?: number; // The strokeOpacity prop specifies the opacity of the outline on the current object. + x?: number; + y?: number; + strokeLinecap?: string; // oneOf(['butt', 'square', 'round']), + strokeCap?: string; // .oneOf(['butt', 'square', 'round']), + strokeLinejoin?: string; // oneOf(['miter', 'bevel', 'round']), + strokeJoin?: string; // .oneOf(['miter', 'bevel', 'round']), + strokeDasharray?: ArrayType; + scale?: number; // Scale value on the current object. + rotate?: number; // Rotation degree value on the current object. + originX?: number; // Transform originX coordinates for the current object. + originY?: number; // Transform originY coordinates for the current object. } interface TransformProps extends BaseProps { - scaleX: number, - scaleY: number, - transform: number, + scaleX: number; + scaleY: number; + transform: number; } interface PathProps extends BaseProps { - d: string + d: string; } interface RectProps extends BaseProps { - width?: number, - height?: number + width?: number; + height?: number; } interface TextProps extends BaseProps { - textAnchor: ('start' | 'middle' | 'end'), - fontFamily: string, - fontSize: number, + textAnchor: ('start' | 'middle' | 'end'); + fontFamily: string; + fontSize: number; } export class Svg extends React.Component { } diff --git a/extensions/imagesvg/src/typings/react-native.d.ts b/extensions/imagesvg/src/typings/react-native.d.ts deleted file mode 100644 index f6587f177..000000000 --- a/extensions/imagesvg/src/typings/react-native.d.ts +++ /dev/null @@ -1,1091 +0,0 @@ -/** -* react-native.d.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definition file for React Native, based on the React.js definition file -* on https://github.com/borisyankov/DefinitelyTyped. -*/ - -declare module 'react-native' { - // - // React - // ---------------------------------------------------------------------- - - import React = require('react'); - - // BT: Adding ProgressBarAndroid. It's not part of the DefinitelyTyped definitions. - class ProgressBarAndroid extends React.Component {} - - type ReactElement = React.ReactElement; - type ReactNode = React.ReactNode; - - function createElement

( - type: string, - props?: P, - ...children: React.ReactNode[]): React.ReactElement

; - - function cloneElement

( - element: P, - props ?: any - ): React.ReactElement

; - - interface SyntheticEvent extends React.SyntheticEvent {} - - function isValidElement(object: {}): boolean; - function findNodeHandle(componentOrHandle: any): number; - - var Children: React.ReactChildren; - - type PlatformString = 'android'|'ios'|'windows'; - var Platform: { - OS: PlatformString, - Version?: number - }; - - // - // Component base - // ---------------------------------------------------------------------- - - abstract class ReactNativeBaseComponent extends React.Component { - setNativeProps(nativeProps: P): void; - focus(): void; - blur(): void; - measure(callback: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void)): void; - measureLayout(relativeToNativeNode: number, onSuccess: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void), onFail: () => void): void; - refs: { - [key: string]: ReactNativeBaseComponent; - } - } - - // - // Style rules - // ---------------------------------------------------------------------- - - type StyleRuleSet = Object | Object[]; - - // - // Specific components - // ---------------------------------------------------------------------- - - interface ComponentPropsBase { - ref?: string | ((obj: ReactNativeBaseComponent) => void); - key?: string | number; - } - - interface ComponentPropsStyleBase extends ComponentPropsBase { - style?: StyleRuleSet | StyleRuleSet[]; - } - - interface ImageSource { - uri: string; - headers?: {[header: string]: string}; - } - - interface ImageProps extends ComponentPropsStyleBase { - onLayout?: Function; - resizeMode?: string; - resizeMethod?: string; // android only prop: 'auto' | 'resize' | 'scale' - source?: ImageSource | number; - testID?: string; - - // iOS - accessibilityLabel?: string; - shouldRasterizeIOS?: boolean; - accessible?: boolean; - capInsets?: Object; - defaultSource?: Object; - onError?: Function; - onLoad?: Function; - onLoadEnd?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - onProgress?: Function; - - // Android - fadeDuration?: number; - } - - interface ActivityIndicatorProps extends ComponentPropsBase { - animating?: boolean; - color?: string; - onLayout?: Function; - size?: string; // enum { 'small', 'large' } - } - - interface TextProps extends ComponentPropsStyleBase { - importantForAccessibility?: string; // 'auto' | 'yes' | 'no' | 'no-hide-descendants'; - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - children? : React.ReactNode; - numberOfLines? : number; - ellipsizeMode? : 'head' | 'middle' | 'tail' // There's also 'clip' but it is iOS only - onLayout? : Function; - onPress? : Function; - onLongPress? : Function; - selectable? : boolean; // only on android, windows - testID? : string; - - // iOS - suppressHighlighting?: boolean; - - // Android - textBreakStrategy?: 'highQuality' | 'simple'| 'balanced'; - elevation?: number; - } - - export interface PickerProps extends ComponentPropsStyleBase { - - /** - * Callback for when an item is selected. This is called with the - * following parameters: - * - itemValue: the value prop of the item that was selected - * - itemPosition: the index of the selected item in this picker - * @param itemValue - * @param itemPosition - */ - onValueChange?: ( itemValue: any, itemPosition: number ) => void - - /** - * Value matching value of one of the items. - * Can be a string or an integer. - */ - selectedValue?: any - - style?: StyleRuleSet | StyleRuleSet[] - - /** - * Used to locate this view in end-to-end tests. - */ - testId?: string - - ref?: string | ((obj: ReactNativeBaseComponent) => void); - } - - interface TouchableWithoutFeedbackProps extends ComponentPropsBase { - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - accessible?: boolean; - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - delayLongPress?: number; - delayPressIn?: number; - delayPressOut?: number; - onLayout?: Function; - onLongPress?: Function; - onPress?: Function; - onPressIn?: Function; - onPressOut?: Function - } - - interface TouchableHighlightProps extends TouchableWithoutFeedbackProps, ComponentPropsStyleBase { - activeOpacity? : number; - children? : React.ReactNode; - onHideUnderlay?: Function; - onShowUnderlay?: Function; - underlayColor? : string; - } - - interface ResponderProps { - onMoveShouldSetResponder? : Function; - onResponderGrant? : Function; - onResponderMove? : Function; - onResponderReject? : Function; - onResponderRelease? : Function; - onResponderTerminate? : Function; - onResponderTerminationRequest? : Function; - onStartShouldSetResponder? : Function; - onStartShouldSetResponderCapture?: Function; - } - - interface ViewOnLayoutEvent { - nativeEvent: { - layout: { - x: number, - y: number, - width: number, - height: number - } - } - } - - type ViewLayerType = 'none' | 'software' | 'hardware'; - - interface CommonAccessibilityProps { - accessibilityLabel? : string; - accessible? : boolean; - onAcccessibilityTap? : Function; - - // android - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityLiveRegion? : string; //enum ( 'none', 'polite', 'assertive' ) - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - - // iOS - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - } - - interface ViewProps extends ComponentPropsBase, ResponderProps, ComponentPropsStyleBase, CommonAccessibilityProps { - children? : any; - onLayout? : ((ev: ViewOnLayoutEvent) => void); - onMagicTap? : Function; - pointerEvents? : string; //enum( 'box-none', 'none', 'box-only', 'auto' ); - removeClippedSubviews? : boolean; - testID? : string; - - // android - collapsable? : boolean; - needsOffscreenAlphaCompositing?: boolean; - renderToHardwareTextureAndroid?: boolean; - viewLayerTypeAndroid? : ViewLayerType; - elevation? : number; - - // iOS - onAccessibilityTapIOS?: Function; - shouldRasterizeIOS? : boolean; - } - - interface ScrollViewProps extends ViewProps { - children?: any; - - contentContainerStyle?: StyleRuleSet | StyleRuleSet[]; - horizontal?: boolean; - keyboardDismissMode?: 'none' | 'interactive' | 'on-drag'; - keyboardShouldPersistTaps?: 'always' | 'never' | 'handled'; - onScroll?: Function; - onScrollBeginDrag?: Function; - onScrollEndDrag?: Function; - onContentSizeChange?: (width: number, height: number) => void; - showsHorizontalScrollIndicator?: boolean; - showsVerticalScrollIndicator?: boolean; - removeClippedSubviews?: boolean; - - // iOS - automaticallyAdjustContentInsets?: boolean; - //contentInset?: EdgeInsetsPropType; - //contentOffset?: PointPropType; - bounces?: boolean; - bouncesZoom?: boolean; - alwaysBounceHorizontal?: boolean; - alwaysBounceVertical?: boolean; - centerContent?: boolean; - decelerationRate?: number; - directionalLockEnabled?: boolean; - canCancelContentTouches?: boolean; - maximumZoomScale?: number; - minimumZoomScale?: number; - onScrollAnimationEnd?: Function; - pagingEnabled?: boolean; - scrollEnabled?: boolean; - scrollEventThrottle?: number; - scrollsToTop?: boolean; - stickyHeaderIndices?: [number]; - snapToInterval?: number; - snapToAlignment?: string; // enum( 'start', 'center', 'end' ) - zoomScale?: number; - overScrollMode?: string; //enum( 'always', 'always-if-content-scrolls', 'never' ) - // iOS - scrollIndicatorInsets?: {top: number, left: number, bottom: number, right: number }; - } - - interface ListViewDataSourceCallback { - rowHasChanged: (r1: T, r2: T) => boolean; - } - - interface ListViewDataSource { - new (onAsset: ListViewDataSourceCallback): ListViewDataSource; - cloneWithRows(rowList: T[]): void; - } - - interface ListViewProps extends ScrollViewProps { - dataSource: Object; //PropTypes.instanceOf(ListViewDataSource).isRequired - renderSeparator?: Function; - renderRow: Function; - initialListSize?: number; - onEndReached?: (e: React.SyntheticEvent) => void; - onEndReachedThreshold?: number; - pageSize?: number; - renderFooter?: Function; - renderHeader?: Function; - renderSectionHeader?: Function; - renderScrollComponent: Function; - scrollRenderAheadDistance?: number; - onChangeVisibleRows?: Function; - removeClippedSubviews?: boolean; - } - - interface ModalProps extends ComponentPropsBase { - animationType?: string; // enum( 'none', 'slide', 'fade' ) - onDismiss?: Function; - transparent?: boolean; - onRequestClose: () => void; - } - - interface TextInputProps extends ComponentPropsStyleBase, CommonAccessibilityProps { - autoCapitalize?: string; // enum('none', 'sentences', 'words', 'characters') - autoCorrect?: boolean; - autoFocus?: boolean; - blurOnSubmit?: boolean; - defaultValue?: string; - editable?: boolean; - keyboardType?: string; // enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search') - multiline?: boolean; - onBlur?: ((e: React.FocusEvent) => void); - onKeyPress?: (e: SyntheticEvent) => void; - onChange?: Function; - onChangeText?: ((changedText: string) => void); - onSelectionChange?: ((selection: SyntheticEvent) => void); - onEndEditing?: Function; - onFocus?: ((e: React.FocusEvent) => void); - onLayout?: ((props: { x: number, y: number, width: number, height: number }) => void); - onSubmitEditing?: Function; - onScroll?: Function; - placeholder?: string; - placeholderTextColor?: string; - returnKeyType?: string; // enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call') - secureTextEntry?: boolean; - testID?: string; - textAlign?: string; // enum('auto' | 'left' | 'right' | 'center' | 'justify') - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - selection?: { start: number, end: number }; - - //iOS and android - selectionColor?: string; - - value: string; - //iOS - clearButtonMode?: string; // enum('never', 'while-editing', 'unless-editing', 'always') - clearTextOnFocus?: boolean; - enablesReturnKeyAutomatically?: boolean; - keyboardAppearance?: string; // enum ('default', 'light', 'dark') - maxLength?: number; - numberOfLines?: number; - selectTextOnFocus?: boolean; - selectionState?: any; // see DocumentSelectionState.js - spellCheck?: boolean; - //android - textAlignVertical?: string; // enum('top', 'center', 'bottom') - textAlignVerticalAndroid?: string; // enum('top', 'center', 'bottom') - textAlignAndroid?: string; - underlineColorAndroid?: string; - disableFullscreenUI?: boolean; - textBreakStrategy?: 'highQuality' | 'simple' | 'balanced'; - } - - interface TextInputState { - currentlyFocusedField(): number; - focusTextInput(textFieldID?: number): void; - blurTextInput(textFieldID?: number): void; - } - - interface WebViewProps extends ComponentPropsStyleBase { - automaticallyAdjustContentInsets?: boolean; - bounces?: boolean; - contentInset?: {top: number, left: number, bottom: number, right: number }; - injectedJavaScript?: string; - javaScriptEnabled?: boolean; - domStorageEnabled?: boolean; - onShouldStartLoadWithRequest?: Function; - onNavigationStateChange?: Function; - onLoad?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - renderError?: Function; - onError?: Function; - renderLoading?: Function; - scalesPageToFit?: boolean; - scrollEnabled?: boolean; - startInLoadingState?: boolean; - source?: { uri: string; method?: string; headers?: Object; body?: string; } | { html: string; baseUrl?: string; }; - } - - interface DatePickerIOSProps extends ComponentPropsStyleBase { - date?: Date; - maximumDate?: Date; - minimumDate?: Date; - minuteInterval?: number; - mode?: string; - timeZoneOffsetInMinutes?: number; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerIOS extends ReactNativeBaseComponent { - } - - interface DatePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerAndroid extends ReactNativeBaseComponent { - static open(options: { date: Date, maxDate: Date, minDate: Date }): Promise; - static dateSetAction: Function; - static dismissedAction: Function; - } - - interface TimePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class TimePickerAndroid extends ReactNativeBaseComponent { - static open(options: { hour: number, minute: number, is24Hour: boolean }): Promise; - static timeSetAction: Function; - static dismissedAction: Function; - } - - type DatePickerAction = { - action: Function; - day: number; - month: number; - year: number; - } - - type TimePickerAction = { - action: Function; - hour: number; - minute: number; - } - - class Image extends ReactNativeBaseComponent { - static prefetch(url: string): Promise; - } - class ActivityIndicator extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - class Picker extends ReactNativeBaseComponent { - static Item: any; - } - class TouchableHighlight extends ReactNativeBaseComponent { } - class TouchableWithoutFeedback extends ReactNativeBaseComponent { } - class View extends ReactNativeBaseComponent { } - class ScrollView extends ReactNativeBaseComponent { - getInnerViewNode(): number; - // TODO: Define ScrollResponder type - scrollTo(val: { x?: number; y?: number; animated?: boolean; }): void; - scrollBy(val: { deltaX?: number; deltaY?: number; animated?: boolean; }): void; - } - class ListView extends ReactNativeBaseComponent { - static DataSource: ListViewDataSource; - } - class Modal extends ReactNativeBaseComponent { } - class TextInput extends ReactNativeBaseComponent { - static State: TextInputState; - } - class WebView extends ReactNativeBaseComponent { - reload() : void; - goBack() : void; - goForward() : void; - } - - interface ActionSheetOptions { - options: string[]; - cancelButtonIndex?: number; - destructiveButtonIndex?: number; - title?: string; - message?: string; - } - - interface ShareActionSheetOptions { - message?: string; - url?: string; - subject?: string; - excludedActivityTypes?: string[]; - } - - class ActionSheetIOS { - static showActionSheetWithOptions(options: ActionSheetOptions, callback: (buttonIndex: number) => void): void; - static showShareActionSheetWithOptions(options: ShareActionSheetOptions, failureCallback: (error: string) => void, successCallback: (success: boolean, method: string) => void): void; - } - - class BackAndroid { - static addEventListener(eventName: string, callback: () => boolean): void; - static removeEventListener(eventName: string, callback: () => boolean): void; - } - - interface NavigatorIOSRoute { - component: any; - title: string; - passProps?: any; - backButtonTitle?: string; - backButtonIcon?: any; - leftButtonTitle?: string; - leftButtonIcon?: any; - onLeftButtonPress?: () => void; - rightButtonTitle?: string; - rightButtonIcon?: any; - onRightButtonPress?: () => void; - wrapperStyle?: any; - } - - interface NavigatorIOSProps extends ComponentPropsBase { - barTintColor?: string; - initialRoute: NavigatorIOSRoute; - itemWrapperStyle?: StyleRuleSet | StyleRuleSet[]; - navigationBarHidden?: boolean; - shadowHidden?: boolean; - style?:any; - tintColor?: string; - titleTextColor?: string; - translucent?: boolean; - interactivePopGestureEnabled?: boolean; - } - - class StatusBar { - // Native - static setHidden(hidden: boolean, animation?: string): void; //'none'|'fade'|'slide'; - - // iOS - static setBarStyle(barStyle: string, animated: boolean): void; //'default'|'light-content'; - static setNetworkActivityIndicatorVisible(value: boolean): void; - - // Android - static setBackgroundColor(color: string, animated?: boolean): void; - static setTranslucent(translucent: boolean): void; - } - - interface EventSubscription { - remove(): void; - } - - interface NavigatorIOSNavigationContext { - addListener(event: string, callback: (route: NavigatorIOSRoute) => void): EventSubscription; - } - - interface NavigatorIOSState { - observedTopOfStack: number; - requestedTopOfStack: number; - routeStack: NavigatorIOSRoute[]; - } - - class NavigatorIOS extends ReactNativeBaseComponent { - navigationContext: NavigatorIOSNavigationContext; - push(route: NavigatorIOSRoute): void; - pop(): void; - popN(n: number): void; - replace(route: NavigatorIOSRoute): void; - replacePrevious(route: NavigatorIOSRoute): void; - replacePreviousAndPop(route: NavigatorIOSRoute): void; - resetTo(route: NavigatorIOSRoute): void; - popToRoute(route: NavigatorIOSRoute): void; - popToTop(): void; - } - - // StyleSheet - class StyleSheet { - static create(obj: { [key: string]: any }): any; - static flatten: (s: StyleSheet) => { [key: string]: any }; - } - - class AppRegistry { - static registerComponent(appKey: string, getComponentFunc: Function): any; - } - - type CameraRollProps = { - /** - * The number of photos wanted in reverse order of the photo application - * (i.e. most recent first for SavedPhotos). - */ - first: number, - - /** - * A cursor that matches `page_info { end_cursor }` returned from a previous - * call to `getPhotos` - */ - after?: string, - - /** - * Specifies which group types to filter the results to. - */ - groupTypes?: string, // enum { 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream', 'SavedPhotos', // default }, - - /** - * Specifies filter on group names, like 'Recent Photos' or custom album - * titles. - */ - groupName?: string, - - /** - * Specifies filter on asset type - */ - assetType?: string; // enum { 'All', 'Videos', 'Photos', // default }, - - } - - type GetPhotosCallbackPropNode = { - node: { - type: string, - group_name: string, - image: { - uri: string, - height: number, - width: number, - isStored?: boolean, - }, - timestamp: number, - location?: { - latitude?: number, - longitude?: number, - altitude?: number, - heading?: number, - speed?: number, - } - } - } - - type GetPhotosCallbackProps = { - edges: GetPhotosCallbackPropNode[], - page_info: { - has_next_page: boolean, - start_cursor?: string, - end_cursor?: string, - } - } - - class Clipboard { - static setString(content: string): void; - static getString(): Promise; - } - - class CameraRoll { - static saveImageWithTag(tag: string, successCallback: Function, errorCallback: Function): void; - static getPhotos(params: CameraRollProps, callback: ((props: GetPhotosCallbackProps) => void), errorCallback: Function): void; - } - - class Linking { - static getInitialURL(): Promise; - static openURL(url: string): Promise; - static canOpenURL(url: string): Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - } - - class AccessibilityInfo { - static fetch: () => Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - static announceForAccessibility(announcement: string): void; - static setAccessibilityFocus(reactTag: number): void; - } - - interface AlertButtonSpec { - text?: string; - onPress?: () => void; - style?: string; // enum {default', 'cancel', 'destructive'} - } - - class Alert { - static alert( - title: string, - message?: string, - buttons?: AlertButtonSpec[], - type?: string // enum { 'default', 'plain-text', 'secure-text', 'login-password'} - ): void; - } - - class PushNotificationIOS { - static presentLocalNotification(details: { category: string, alertBody: string, soundName?: string}): void; - static scheduleLocalNotification(details: {alertBody: string, fireDate: Date}): void; - - static getApplicationIconBadgeNumber(callback: (badgeCount:number) => void): void; - static setApplicationIconBadgeNumber(number: number): void; - - static addEventListener(type: string, handler: (event: any) => void): void; - - static requestPermissions(permissions?: {alert?: boolean, badge?: boolean, sound?: boolean}): void; - static abandonPermissions(): void; - static checkPermissions(callback: (permissions: {alert: boolean, badge: boolean, sound: boolean}) => void): void; - - static getInitialNotification(): Promise; - - getMessage(): string; - getSound(): string; - getAlert(): any; - getBadgeCount(): number; - getData(): any; - } - - interface PanResponderGestureState { - stateID: number; - moveX: number; - moveY: number; - x0: number; - y0: number; - dx: number; - dy: number; - vx: number; - vy: number; - numberActiveTouches: number; - } - - interface ResponderSyntheticEvent extends React.SyntheticEvent { - touchHistory: Function; - } - - type PanResponderCreateConfig = { - onMoveShouldSetPanResponder?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean, - onMoveShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderReject?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderGrant?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderStart?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderEnd?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderRelease?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderMove?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminate?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminationRequest?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onShouldBlockNativeResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), // android only - onStartShouldSetResponderCapture?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void, - - } - - class PanResponder { - static create(config: PanResponderCreateConfig): PanResponder; - panHandlers: ResponderProps; - } - - type DimensionType = { - width: number, - height: number, - scale: number, - fontScale: number, - } - - class Dimensions { - static set(obj: any): boolean; - static get(key: string): DimensionType; - } - - type RCTAppStateData = { app_state: string } - type RCTAppState = { - getCurrentAppState(successCallback: (appStateData: RCTAppStateData) => void, failureCallback: () => void): void; - } - - type FileInput = { - selectImage: Function; - } - - type SnapshotOptions = { - width?: number; - height?: number; - format?: 'png' | 'jpeg'; - quality?: number; - } - - type UIManager = { - measure: Function; - measureInWindow: Function; - measureLayout: Function; - measureLayoutRelativeToParent: Function; - dispatchViewManagerCommand: Function; - - getMaxContentSizeMultiplier: Function; - setMaxContentSizeMultiplier: Function; - - // ios - takeSnapshot: (view: any, options?: SnapshotOptions) => Promise; - - // Android - sendAccessibilityEvent: Function; - } - - type AccessibilityManager = { - getMultiplier: Function; - announceForAccessibility (announcement: string): void; - } - - // We don't use this module, but need to be able to check its existance - type NativeAnimatedModule = { - - }; - - class ImagePickerManager { - showImagePicker: Function; - launchCamera: Function; - launchImageLibrary: Function; - } - - class NativeModules { - static AppState: RCTAppState; - static FileInput: FileInput; - static UIManager: UIManager; - static AccessibilityManager: AccessibilityManager; - static ImagePickerManager: ImagePickerManager; - static Networking: { - clearCookies(callback: (success: boolean) => void): void; - } - static ContextMenuAndroid: { - show(buttons: any, callback: (command: string) => void): void; - } - static NativeAnimation: NativeAnimatedModule; - } - - class AsyncStorage { - static getItem(key: string, callback: (error: any, result: string) => void): void; - static setItem(key: string, value: string, callback: (error: any) => void): void; - static removeItem(key: string, callback: (error: any) => void): void; - static clear(callback: (error: any) => void): void; - } - - class NetInfo { - static isConnected: { - addEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - removeEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - fetch: () => Promise; - } - static fetch(): Promise; - } - - class Easing { - static bezier(x1: number, y1: number, x2: number, y2: number): ((input: number) => number); - static linear(): ((input: number) => number); - } - - interface AnimationConfig { - isInteraction?: boolean; - useNativeDriver?: boolean; - } - - interface AnimatedTimingConfig extends AnimationConfig { - toValue: number; - duration?: number; - delay?: number - easing?: (input: number) => number; - } - - interface CompositeAnimation { - start(callback?: AnimatedEndCallback): void; - stop: () => void; - } - - type AnimatedEndResult = { finished: boolean }; - type AnimatedEndCallback = (result: AnimatedEndResult) => void; - - module Animated { - function createAnimatedComponent(Component: any, notCollapsable?: boolean): any; - function delay(time: number): CompositeAnimation; - function timing(value: Animated.Value, config: AnimatedTimingConfig): CompositeAnimation; - function parallel(animations: CompositeAnimation[]): CompositeAnimation - function sequence(animations: CompositeAnimation[]): CompositeAnimation - class Value { - constructor(val: number); - setValue(value: number): void; - addListener(callback: any): string; - removeListener(id: string): void; - removeAllListeners(): void; - interpolate(config: any): Value; - } - class View extends ReactNativeBaseComponent { } - class Image extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - } - - interface IUpdateLayoutAnimationConfig { - duration?: number; - delay?: number; - - springDamping?: number; - initialVelocity?: number; - - type?: string; - } - - interface ICreateLayoutAnimationConfig extends IUpdateLayoutAnimationConfig { - property?: string; - } - - interface ILayoutAnimationConfig { - duration: number; - create?: ICreateLayoutAnimationConfig; - update?: IUpdateLayoutAnimationConfig; - } - - module LayoutAnimation { - function configureNext(config: ILayoutAnimationConfig): void; - - module Types { - var spring: string; - var linear: string; - var easeInEaseOut: string; - var easeIn: string; - var easeOut: string; - var keyboard: string; - } - - module Properties { - var opacity: string; - var scaleXY: string; - } - } - - class DeviceEventSubscription { - remove(): void; - } - - class NativeAppEventEmitter { - static addListener(eventId: string, callback: Function): DeviceEventSubscription; - } - - module DeviceEventEmitter{ - function addListener(name: string, callback: Function): void; - } - - module AppState { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module AppStateIOS { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module Touchable { - type RectOffset = { - top: number, - left: number, - right: number, - bottom: number - } - - interface State { - touchable: any - } - - interface TouchableMixin extends React.Mixin { - touchableGetInitialState: () => State - touchableHandleStartShouldSetResponder: () => {} - touchableHandleResponderTerminationRequest: () => {} - touchableHandleResponderGrant: (e: React.SyntheticEvent, dispatchID: string) => {} - touchableHandleResponderMove: (e: React.SyntheticEvent) => {} - touchableHandleResponderRelease: (e: React.SyntheticEvent) => {} - touchableHandleResponderTerminate: (e: React.SyntheticEvent) => {} - touchableHandleActivePressIn?: (e: React.SyntheticEvent) => {} - touchableHandleActivePressOut?: (e: React.SyntheticEvent) => {} - touchableHandlePress?: (e: React.SyntheticEvent) => {} - touchableHandleLongPress?: (e: React.SyntheticEvent) => {} - touchableGetHighlightDelayMS?: () => number - touchableGetPressRectOffset?: () => RectOffset - } - - var Mixin: TouchableMixin; - } - - class EmitterSubscription { - remove(): void; - } - - module Keyboard { - function addListener(eventType: string, listener: Function, context?: any): EmitterSubscription; - function removeAllListeners(eventType: string): void; - function removeSubscription(subscription: EmitterSubscription): void; - } - - module PixelRatio { - /** - * Returns the device pixel density. Some examples: - * - * - PixelRatio.get() === 1 - * - mdpi Android devices (160 dpi) - * - PixelRatio.get() === 1.5 - * - hdpi Android devices (240 dpi) - * - PixelRatio.get() === 2 - * - iPhone 4, 4S - * - iPhone 5, 5c, 5s - * - iPhone 6 - * - xhdpi Android devices (320 dpi) - * - PixelRatio.get() === 3 - * - iPhone 6 plus - * - xxhdpi Android devices (480 dpi) - * - PixelRatio.get() === 3.5 - * - Nexus 6 - **/ - function get(): number; - - /** - * Returns the scaling factor for font sizes. This is the ratio that is used to calculate the - * absolute font size, so any elements that heavily depend on that should use this to do - * calculations. - * - * If a font scale is not set, this returns the device pixel ratio. - * - * Currently this is only implemented on Android and reflects the user preference set in - * Settings > Display > Font size, on iOS it will always return the default pixel ratio. - * @platform android - **/ - function getFontScale(): number; - - /** - * Converts a layout size (dp) to pixel size (px). - * - * Guaranteed to return an integer number. - **/ - function getPixelSizeForLayoutSize(layoutSize: number): number; - - /** - * Rounds a layout size (dp) to the nearest layout size that corresponds to - * an integer number of pixels. For example, on a device with a PixelRatio - * of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to - * exactly (8.33 * 3) = 25 pixels. - **/ - function roundToNearestPixel(layoutSize: number): number; - } - - interface IncrementalProps extends ComponentPropsStyleBase { - onDone?: () => void; - name: string; - children?: any; - } - - interface IncrementalPresenterProps extends ComponentPropsStyleBase { - name: string; - disabled?: boolean; - onDone?: () => void; - onLayout?: (event: Object) => void; - style?: any; - children?: any; - } - - class Incremental extends ReactNativeBaseComponent { - } - - class IncrementalGroup extends ReactNativeBaseComponent{ - } - - class IncrementalPresenter extends ReactNativeBaseComponent { - } - - module JSEventLoopWatchdog { - function install(obj: any): void; - } - - module InteractionManager { - function setDeadline(deadline: number): void; - } - - interface I18nManager { - isRTL: boolean - allowRTL: (allowRTL: boolean) => {} - forceRTL: (forceRTL: boolean) => {} - } - - export var I18nManager: I18nManager; -} - -interface GeoConfiguration { - skipPermissionRequests: boolean; -} - -interface Geolocation { - // React Native addition to navigator.geolocation - setRNConfiguration(config: GeoConfiguration): void; -} - diff --git a/extensions/imagesvg/src/web/ImageSvg.tsx b/extensions/imagesvg/src/web/ImageSvg.tsx index cf3f7ede6..e1d7e7018 100644 --- a/extensions/imagesvg/src/web/ImageSvg.tsx +++ b/extensions/imagesvg/src/web/ImageSvg.tsx @@ -1,29 +1,27 @@ /* -* ImageSvg.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Web-specific implementation of the cross-platform abstraction for -* SVG (scalable vector graphics) images. -*/ - -import assert = require('assert'); -import React = require('react'); -import ReactDOM = require('react-dom'); + * ImageSvg.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Web-specific implementation of the cross-platform abstraction for + * SVG (scalable vector graphics) images. + */ + +import * as React from 'react'; import { Styles as RXStyles } from 'reactxp'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import assert from '../common/assert'; +import { ImageSvgProps } from '../common/Types'; -export class ImageSvg extends React.Component { +export class ImageSvg extends React.Component { render() { - assert.ok(this.props.width && this.props.height, 'The width and height on imagesvg are mandatory.'); + assert(this.props.width && this.props.height, 'The width and height on imagesvg are mandatory.'); if (this.props.width > 0 && this.props.height > 0) { - let combinedStyles = RXStyles.combine([{ + const combinedStyles = RXStyles.combine([{ display: 'flex', - position: 'relative' - }, this.props.style]) as any; + position: 'relative', + } as any, this.props.style]); if (this.props.fillColor !== undefined) { combinedStyles.fill = this.props.fillColor; @@ -54,10 +52,10 @@ export class ImageSvg extends React.Component { } if (this.props.webShadow) { - let aliases = RXStyles.getCssPropertyAliasesCssStyle(); + const aliases = RXStyles.getCssPropertyAliasesCssStyle(); if (this._isFilterDropShadowSupported()) { - let filterAlias = aliases['filter'] || 'filter'; + const filterAlias = aliases.filter || 'filter'; combinedStyles[filterAlias] = 'drop-shadow(' + this.props.webShadow + ')'; } } diff --git a/extensions/imagesvg/src/web/PluginBase.ts b/extensions/imagesvg/src/web/PluginBase.ts index d2df9068f..fc5ed7bee 100644 --- a/extensions/imagesvg/src/web/PluginBase.ts +++ b/extensions/imagesvg/src/web/PluginBase.ts @@ -1,13 +1,15 @@ /* -* PluginBase.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the Web implementation of the plugin. -*/ + * PluginBase.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Web implementation of the plugin. + */ + +import * as Types from '../common/Types'; import ImageSvg from './ImageSvg'; import SvgPath from './SvgPath'; -import Types = require('../common/Types'); +import SvgRect from './SvgRect'; -export { ImageSvg as default, SvgPath, Types }; +export { ImageSvg as default, SvgPath, SvgRect, Types }; diff --git a/extensions/imagesvg/src/web/SvgPath.tsx b/extensions/imagesvg/src/web/SvgPath.tsx index 988d1ef6a..b154530b0 100644 --- a/extensions/imagesvg/src/web/SvgPath.tsx +++ b/extensions/imagesvg/src/web/SvgPath.tsx @@ -1,18 +1,17 @@ /* -* SvgPath.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Web-specific implementation of the cross-platform abstraction for -* SVG Path (scalable vector graphics) images. -*/ + * SvgPath.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Web-specific implementation of the cross-platform abstraction for + * SVG Path elements. + */ -import React = require('react'); +import * as React from 'react'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import { SvgPathProps } from '../common/Types'; -export class SvgPath extends React.Component { +export class SvgPath extends React.Component { render() { return ( { + render() { + return ( + + ); + } +} + +export default SvgRect; diff --git a/extensions/imagesvg/src/windows/ImageSvg.tsx b/extensions/imagesvg/src/windows/ImageSvg.tsx index 95c831533..ab526967e 100644 --- a/extensions/imagesvg/src/windows/ImageSvg.tsx +++ b/extensions/imagesvg/src/windows/ImageSvg.tsx @@ -1,20 +1,19 @@ -/** -* ImageSvg.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* RN-specific implementation of the cross-platform abstraction for -* SVG (scalable vector graphics) images. -*/ +/** + * ImageSvg.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG (scalable vector graphics) images. + */ -import React = require('react'); +import * as React from 'react'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import { ImageSvgProps } from '../common/Types'; // TODO: #694092 Not implemented -export class ImageSvg extends React.Component { +export class ImageSvg extends React.Component { render(): any { return null; } diff --git a/extensions/imagesvg/src/windows/PluginBase.ts b/extensions/imagesvg/src/windows/PluginBase.ts index 2221dc6b1..0e184f946 100644 --- a/extensions/imagesvg/src/windows/PluginBase.ts +++ b/extensions/imagesvg/src/windows/PluginBase.ts @@ -1,13 +1,15 @@ /* -* PluginBase.ts -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the UWP implementation of the plugin. -*/ + * PluginBase.ts + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the UWP implementation of the plugin. + */ + +import * as Types from '../common/Types'; import ImageSvg from './ImageSvg'; import SvgPath from './SvgPath'; -import Types = require('../common/Types'); +import SvgRect from './SvgRect'; -export { ImageSvg as default, SvgPath, Types }; +export { ImageSvg as default, SvgPath, SvgRect, Types }; diff --git a/extensions/imagesvg/src/windows/SvgPath.tsx b/extensions/imagesvg/src/windows/SvgPath.tsx index 500a93d03..fecabb851 100644 --- a/extensions/imagesvg/src/windows/SvgPath.tsx +++ b/extensions/imagesvg/src/windows/SvgPath.tsx @@ -1,20 +1,19 @@ /* -* SvgPath.tsx -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* RN-specific implementation of the cross-platform abstraction for -* SVG Path (scalable vector graphics) elements. -*/ + * SvgPath.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG Path elements. + */ -import React = require('react'); +import * as React from 'react'; -import SvgInterfaces = require('../common/Interfaces'); -import SvgTypes = require('../common/Types'); +import { SvgPathProps } from '../common/Types'; // TODO: #694092 Not implemented -export class SvgPath extends React.Component { +export class SvgPath extends React.Component { render(): any { return null; } diff --git a/extensions/imagesvg/src/windows/SvgRect.tsx b/extensions/imagesvg/src/windows/SvgRect.tsx new file mode 100644 index 000000000..efcfe62cf --- /dev/null +++ b/extensions/imagesvg/src/windows/SvgRect.tsx @@ -0,0 +1,22 @@ +/* + * SvgRect.tsx + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform abstraction for + * SVG Rect elements. + */ + +import * as React from 'react'; + +import { SvgRectProps } from '../common/Types'; + +// TODO: #694092 Not implemented + +export class SvgRect extends React.Component { + render(): any { + return null; + } +} + +export default SvgRect; diff --git a/extensions/imagesvg/tsconfig.json b/extensions/imagesvg/tsconfig.json index 09543f798..b504e8484 100644 --- a/extensions/imagesvg/tsconfig.json +++ b/extensions/imagesvg/tsconfig.json @@ -7,13 +7,12 @@ "target": "es5", "experimentalDecorators": true, "noImplicitAny": true, - "outDir": "dist/" + "outDir": "dist/", + "skipLibCheck": true }, - "include": [ "src/**/*" ], - "exclude": [ "dist", "node_modules" diff --git a/extensions/imagesvg/tslint.json b/extensions/imagesvg/tslint.json deleted file mode 100644 index d6667ff9b..000000000 --- a/extensions/imagesvg/tslint.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "rules": { - "align": [true, "statements"], - "class-name": true, - "curly": true, - "eofline": true, - "forin": true, - "indent": [true, "spaces"], - "interface-name": [true, "never-prefix"], - "label-position": true, - "max-line-length": [ true, 140 ], - "no-arg": true, - "no-bitwise": false, - "no-console": [true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-consecutive-blank-lines": true, - "no-construct": true, - "no-debugger": true, - "no-duplicate-variable": true, - "no-empty": true, - "no-eval": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": false, - "no-unused-expression": true, - "one-line": [true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "quotemark": [true, "single", "jsx-single"], - "radix": true, - "semicolon": true, - "triple-equals": [true, "allow-null-check"], - "variable-name": false, - "whitespace": [true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - } -} \ No newline at end of file diff --git a/extensions/navigation/.eslintrc.json b/extensions/navigation/.eslintrc.json new file mode 100644 index 000000000..45914c8c0 --- /dev/null +++ b/extensions/navigation/.eslintrc.json @@ -0,0 +1,43 @@ +{ + "parserOptions": { + "project": "./tsconfig.json" + }, + "extends": ["skype", "skype/react"], + "rules": { + "no-console": [ + "error", + { + "allow": [ + "error" + ] + } + ] + }, + "overrides": [ + { + "files": [ + "*.tsx" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + { + "files": [ + "Navigator.tsx" + ], + "rules": { + "no-duplicate-imports": "off" + } + }, + { + "files": [ + "*.d.ts" + ], + "rules": { + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/member-naming": "off" + } + } + ] +} diff --git a/extensions/navigation/.gitignore b/extensions/navigation/.gitignore index b1866059e..dc65a21e8 100644 --- a/extensions/navigation/.gitignore +++ b/extensions/navigation/.gitignore @@ -1,3 +1,4 @@ dist node_modules .DS_Store +package-lock.json \ No newline at end of file diff --git a/extensions/navigation/package.json b/extensions/navigation/package.json index 8fa5a573c..8aa5fcfe4 100644 --- a/extensions/navigation/package.json +++ b/extensions/navigation/package.json @@ -1,10 +1,11 @@ { "name": "reactxp-navigation", - "version": "1.2.0", + "version": "2.0.0", "description": "Plugin for ReactXP that provides a navigation framework", "scripts": { "build": "tsc", - "tslint": "tslint --project tsconfig.json -r tslint.json --fix || true" + "lint": "eslint --ext .ts,.tsx src", + "lint:fix": "npm run lint -- --fix" }, "repository": { "type": "git", @@ -16,23 +17,30 @@ "react" ], "dependencies": { - "@types/lodash": "^4.14.109", - "@types/node": "^6.0.65", - "assert": "^1.3.0", - "lodash": "^4.17.10", + "lodash": "^4.17.15", "rebound": "^0.1.0", - "reactxp": "^1.2.0", - "reactxp-experimental-navigation": "^1.0.13" + "reactxp-experimental-navigation": "1.0.14" }, "peerDependencies": { - "react": "16.2.0", - "react-dom": "16.2.0", - "react-native": "^0.53.3", - "react-native-windows": "^0.53.3" + "react": "^16.3.0", + "reactxp": "^2.0.0", + "react-dom": "^16.3.0", + "react-native": ">=0.57", + "react-native-windows": "^0.57.1" }, "devDependencies": { - "tslint": "5.10.0", - "typescript": "2.8.3" + "@types/lodash": "^4.14.149", + "@types/react-dom": "^16.9.4", + "@types/react-native": "^0.60.23", + "@typescript-eslint/eslint-plugin": "2.15.0", + "eslint": "6.8.0", + "eslint-config-skype": "1.5.0", + "eslint-plugin-import": "2.20.0", + "eslint-plugin-react": "7.17.0", + "react": "^16.3.0", + "react-dom": "^16.3.0", + "reactxp": "^2.0.0", + "typescript": "3.7.4" }, "author": "ReactXP Team ", "license": "MIT", diff --git a/extensions/navigation/src/common/Types.ts b/extensions/navigation/src/common/Types.ts index 266ceea62..f6c12f19a 100644 --- a/extensions/navigation/src/common/Types.ts +++ b/extensions/navigation/src/common/Types.ts @@ -1,14 +1,14 @@ /** -* Types.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* Type definitions for reactxp-naviigation extension. -*/ + * Types.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * Type definitions for reactxp-naviigation extension. + */ // Use only for type data -import React = require('react'); -import RX = require('reactxp'); +import * as React from 'react'; +import * as RX from 'reactxp'; export type ReactNode = React.ReactNode; @@ -38,50 +38,52 @@ export interface NavigatorRoute { } // NOTE: Experimental navigator only -export type NavigationTransitionSpec = { +export interface NavigationTransitionSpec { duration?: number; // NOTE: Elastic and bounce easing will not work as expected due to how the navigator interpolates styles easing?: RX.Types.Animated.EasingFunction; -}; +} // NOTE: Experimental navigator only -export type NavigationTransitionStyleConfig = { - // By default input range is defined as [index - 1, index, index + 1]; - // Input and output ranges must contain the same number of elements - inputRange?: number[]; - opacityOutput: number | number[]; - scaleOutput: number | number[]; - translateXOutput: number | number[]; - translateYOutput: number | number[]; -}; +export interface NavigationTransitionStyleConfig { + // By default input range is defined as [index - 1, index, index + 1]; + // Input and output ranges must contain the same number of elements + inputRange?: number[]; + opacityOutput: number | number[]; + scaleOutput: number | number[]; + translateXOutput: number | number[]; + translateYOutput: number | number[]; +} // NOTE: Experimental navigator only -export type CustomNavigatorSceneConfig = { - // Optional transition styles - transitionStyle?: (sceneIndex: number, sceneDimensions: RX.Types.Dimensions) => NavigationTransitionStyleConfig; - // Optional overrides for duration, easing, and timing - transitionSpec?: NavigationTransitionSpec; - // Optional cardStyle override - cardStyle?: RX.Types.ViewStyleRuleSet; - // Optionally hide drop shadow - hideShadow?: boolean; - // Optionally flip the visual order of the last two scenes - presentBelowPrevious?: boolean; -}; +export interface CustomNavigatorSceneConfig { + // Optional transition styles + transitionStyle: (sceneIndex: number, sceneDimensions: RX.Types.Dimensions) => NavigationTransitionStyleConfig; + // Optional overrides for duration, easing, and timing + transitionSpec?: NavigationTransitionSpec; + // Optional cardStyle override + cardStyle?: RX.Types.ViewStyleRuleSet; + // Optionally hide drop shadow + hideShadow?: boolean; + // Optionally flip the visual order of the last two scenes + presentBelowPrevious?: boolean; +} export interface NavigatorProps extends RX.CommonProps { - renderScene: (route: NavigatorRoute) => JSX.Element | undefined; - navigateBackCompleted?: () => void; - // NOTE: Arguments are only passed to transitionStarted by the experimental navigator - transitionStarted?: (progress?: RX.Types.AnimatedValue, - toRouteId?: string, fromRouteId?: string, - toIndex?: number, fromIndex?: number) => void; - transitionCompleted?: () => void; - cardStyle?: RX.Types.ViewStyleRuleSet; - children?: ReactNode; - // Selector of the navigator delegate. Currently make difference only in react-native. - delegateSelector?: NavigatorDelegateSelector; + renderScene: (route: NavigatorRoute) => JSX.Element | null; + navigateBackCompleted?: () => void; + // NOTE: Arguments are only passed to transitionStarted by the experimental navigator + transitionStarted?: (progress?: RX.Types.AnimatedValue, + toRouteId?: string, + fromRouteId?: string, + toIndex?: number, + fromIndex?: number) => void; + transitionCompleted?: () => void; + cardStyle?: RX.Types.ViewStyleRuleSet; + children?: ReactNode; + // Selector of the navigator delegate. Currently make difference only in react-native. + delegateSelector?: NavigatorDelegateSelector; } export enum CommandType { @@ -136,16 +138,16 @@ export abstract class NavigatorDelegate { this._owner.props.navigateBackCompleted(); } - // Indicate that we handled the event. + // Indicate that we handled the event. return true; } return false; - } + }; abstract getRoutes(): NavigatorRoute[]; abstract immediatelyResetRouteStack(nextRouteStack: NavigatorRoute[]): void; - abstract render(): JSX.Element; + abstract render(): JSX.Element | null; abstract processCommand(commandQueue: NavigationCommand[]): void; abstract handleBackPress(): void; } diff --git a/extensions/navigation/src/common/assert.ts b/extensions/navigation/src/common/assert.ts new file mode 100644 index 000000000..46aba16a5 --- /dev/null +++ b/extensions/navigation/src/common/assert.ts @@ -0,0 +1,14 @@ +/** + * assert + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + */ +const assert = (cond: any, message?: string | undefined): void => { + if (!cond) { + throw new Error(message || 'Assertion Failed'); + } +}; + +export default assert; diff --git a/extensions/navigation/src/common/lodashMini.ts b/extensions/navigation/src/common/lodashMini.ts index 8392bd7ff..6c5fce390 100644 --- a/extensions/navigation/src/common/lodashMini.ts +++ b/extensions/navigation/src/common/lodashMini.ts @@ -1,18 +1,17 @@ /** -* lodashMini.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Imports a subset of lodash library needed for ReactXP's implementation. -*/ + * lodashMini.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Imports a subset of lodash library needed for ReactXP's implementation. + */ import assign = require('lodash/assign'); import clone = require('lodash/clone'); import cloneDeep = require('lodash/cloneDeep'); import flatten = require('lodash/flatten'); import get = require('lodash/get'); -import isArray = require('lodash/isArray'); import isEmpty = require('lodash/isEmpty'); import isEqual = require('lodash/isEqual'); import isNumber = require('lodash/isNumber'); @@ -29,7 +28,6 @@ export { cloneDeep, flatten, get, - isArray, isEmpty, isEqual, isNumber, diff --git a/extensions/navigation/src/native-common/Navigator.tsx b/extensions/navigation/src/native-common/Navigator.tsx index a15aef384..8635155e7 100644 --- a/extensions/navigation/src/native-common/Navigator.tsx +++ b/extensions/navigation/src/native-common/Navigator.tsx @@ -1,32 +1,30 @@ /** -* Navigator.tsx -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Common native implementation for Navigator on mobile. -*/ - -import RN = require('react-native'); -import React = require('react'); -import RX = require('reactxp'); - + * Navigator.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Common native implementation for Navigator on mobile. + */ +import * as RX from 'reactxp'; + +import * as Types from '../common/Types'; import { Navigator as BaseNavigator, NavigatorDelegate, NavigatorDelegateSelector as DelegateSelector, NavigationCommand, NavigatorState, - CommandType + NavigatorProps, + NavigatorRoute, + CommandType, } from '../common/Types'; import NavigatorExperimentalDelegate from './NavigatorExperimentalDelegate'; -import { NavigatorProps, NavigatorRoute } from '../common/Types'; -import Types = require('../common/Types'); export class DefaultDelegateSelector implements DelegateSelector { getNavigatorDelegate(navigator: BaseNavigator) { - return new NavigatorExperimentalDelegate(navigator); + return new NavigatorExperimentalDelegate(navigator); } } @@ -57,52 +55,52 @@ export class NavigatorImpl extends BaseNavigator { } protected getRoutes(): NavigatorRoute[] { - return this._delegate.getRoutes(); + return this._delegate.getRoutes(); } // Push a new route if initial route doesn't exist - public push(route: NavigatorRoute): void { + push(route: NavigatorRoute): void { this._enqueueCommand({ type: CommandType.Push, param: { - route: route - } + route: route, + }, }); } - public pop(): void { + pop(): void { this._enqueueCommand({ type: CommandType.Pop, - param: {} + param: {}, }); } - public replace(route: NavigatorRoute): void { + replace(route: NavigatorRoute): void { this._enqueueCommand({ type: CommandType.Replace, param: { - route: route - } + route: route, + }, }); } - public replacePrevious(route: NavigatorRoute): void { + replacePrevious(route: NavigatorRoute): void { this._enqueueCommand({ type: CommandType.Replace, param: { route: route, - value: -1 - } + value: -1, + }, }); } // This method replaces the route at the given index of the stack and pops to that index. - public replaceAtIndex(route: NavigatorRoute, index: number): void { - let routes = this.getRoutes(); + replaceAtIndex(route: NavigatorRoute, index: number): void { + const routes = this.getRoutes(); // Pop to index route and then replace if not last one if (index < routes.length - 1) { - let route = routes[index]; + const route = routes[index]; this.popToRoute(route); } @@ -111,34 +109,34 @@ export class NavigatorImpl extends BaseNavigator { } // Reset route stack with default route stack - public immediatelyResetRouteStack(nextRouteStack: NavigatorRoute[]): void { - this._delegate.immediatelyResetRouteStack(nextRouteStack); + immediatelyResetRouteStack(nextRouteStack: NavigatorRoute[]): void { + this._delegate.immediatelyResetRouteStack(nextRouteStack); } - public popToRoute(route: NavigatorRoute): void { + popToRoute(route: NavigatorRoute): void { this._enqueueCommand({ type: CommandType.Pop, param: { - route: route - } + route: route, + }, }); } - public popToTop(): void { + popToTop(): void { this._enqueueCommand({ type: CommandType.Pop, param: { - value: -1 - } + value: -1, + }, }); } - public getCurrentRoutes(): NavigatorRoute[] { + getCurrentRoutes(): NavigatorRoute[] { return this.getRoutes(); } // Render without initial route to get a reference for Navigator object - public render(): JSX.Element { + render(): JSX.Element { return this._delegate.render(); } @@ -152,7 +150,7 @@ export class NavigatorImpl extends BaseNavigator { } } -export import Types = Types; export default NavigatorImpl; export const Navigator = NavigatorImpl; export const NavigatorDelegateSelector = new DefaultDelegateSelector(); +export { Types }; diff --git a/extensions/navigation/src/native-common/NavigatorExperimentalDelegate.tsx b/extensions/navigation/src/native-common/NavigatorExperimentalDelegate.tsx index 5528af198..8ff568984 100644 --- a/extensions/navigation/src/native-common/NavigatorExperimentalDelegate.tsx +++ b/extensions/navigation/src/native-common/NavigatorExperimentalDelegate.tsx @@ -1,25 +1,25 @@ /** -* NavigatorExperimentalDelegate.tsx -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Delegate which encapsulates experimental react-native Navigator experience. -* The main difference of Experimental Navigator is that it uses Animated for navigation animation -* so we can enable useNativeDriver options for those animations. -* -* Currently, Android support on NativeAnimations is more stable and performant than iOS. -* That's why we need to have the ability to pick different implementations for different platforms. -*/ - -import _ = require('../common/lodashMini'); -import assert = require('assert'); -import Navigation = require('reactxp-experimental-navigation'); -import React = require('react'); -import RX = require('reactxp'); -import RN = require('react-native'); - -import { + * NavigatorExperimentalDelegate.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Delegate which encapsulates experimental react-native Navigator experience. + * The main difference of Experimental Navigator is that it uses Animated for navigation animation + * so we can enable useNativeDriver options for those animations. + * + * Currently, Android support on NativeAnimations is more stable and performant than iOS. + * That's why we need to have the ability to pick different implementations for different platforms. + */ + +import * as React from 'react'; +import * as RN from 'react-native'; +import * as RX from 'reactxp'; +import * as Navigation from 'reactxp-experimental-navigation'; + +import assert from '../common/assert'; +import * as _ from '../common/lodashMini'; +import { CommandType, CustomNavigatorSceneConfig, Navigator, @@ -27,7 +27,7 @@ import { NavigationCommand, NavigatorDelegate, NavigatorRoute, - NavigatorState + NavigatorState, } from '../common/Types'; type NavigationSceneRendererProps = Navigation.NavigationSceneRendererProps; @@ -54,14 +54,12 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { private _state: Navigation.NavigationState; private _transitionSpec: TransitionSpec; - private _navigationInProgress: boolean; constructor(navigator: Navigator) { super(navigator); - const route: NavigationRouteState = { key: '0', route: { routeId: 0, sceneConfigType: 0 }}; - this._state = { index: 0, routes: [ route ] }; + const route: NavigationRouteState = { key: '0', route: { routeId: 0, sceneConfigType: 0 } }; + this._state = { index: 0, routes: [route] }; this._transitionSpec = this._buildTransitionSpec(this._state); - console.log('initial transition spec is:', this._transitionSpec); } getRoutes(): NavigatorRoute[] { @@ -73,54 +71,53 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { // Reset route stack with default route stack immediatelyResetRouteStack(nextRouteStack: NavigatorRoute[]): void { - console.log('Stack state before reset:', this._state); const prevState = this._state; this._state = this._createParentState(nextRouteStack, prevState); this._transitionSpec = this._buildTransitionSpec(this._state); - console.log('Immediate stack reset:', this._state, this._transitionSpec); - this._owner.setState({state: this._state}); + this._owner.setState({ state: this._state }); } // Render without initial route to get a reference for Navigator object render(): JSX.Element { return ( ); } - private _convertCustomTransitionConfig(config: CustomNavigatorSceneConfig | undefined): - Navigation.NavigationCustomTransitionConfig | undefined { + private _convertCustomTransitionConfig( + config: CustomNavigatorSceneConfig | undefined): Navigation.NavigationCustomTransitionConfig | undefined { if (!config) { return undefined; } - let nativeConfig: Navigation.NavigationCustomTransitionConfig = { + const nativeConfig: Navigation.NavigationCustomTransitionConfig = { transitionStyle: config.transitionStyle, - presentBelowPrevious: config.presentBelowPrevious + presentBelowPrevious: config.presentBelowPrevious, }; if (config.transitionSpec) { - let transitionSpec: Navigation.NavigationTransitionSpec = {}; + const transitionSpec: Navigation.NavigationTransitionSpec = {}; if (config.transitionSpec.duration) { transitionSpec.duration = config.transitionSpec.duration; } if (config.transitionSpec.easing) { transitionSpec.easing = config.transitionSpec.easing.function; } - + nativeConfig.transitionSpec = transitionSpec; + } return nativeConfig; @@ -129,11 +126,11 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { private _buildTransitionSpec(state: Navigation.NavigationState): TransitionSpec { const route = (state.routes[state.index] as NavigationRouteState).route; let direction: Navigation.NavigationGestureDirection = 'horizontal'; - let customSceneConfig: Navigation.NavigationCustomTransitionConfig | undefined = undefined; - let enableGesture: boolean = false; - let responseDistance: number = 0; - let hideShadow = route && route.customSceneConfig && route.customSceneConfig.hideShadow; - let cardStyle: RX.Types.ViewStyleRuleSet | undefined = route && route.customSceneConfig + let customSceneConfig: Navigation.NavigationCustomTransitionConfig | undefined; + let enableGesture = false; + let responseDistance = 0; + const hideShadow = route && route.customSceneConfig && route.customSceneConfig.hideShadow; + const cardStyle: RX.Types.ViewStyleRuleSet | undefined = route && route.customSceneConfig ? route.customSceneConfig.cardStyle : undefined; let gestureDistanceSet = false; @@ -162,8 +159,8 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { } break; // Currently we support only right to left animation - //case NavigatorSceneConfigType.FloatFromRight: - //case NavigatorSceneConfigType.FloatFromLeft: + // case NavigatorSceneConfigType.FloatFromRight: + // case NavigatorSceneConfigType.FloatFromLeft: default: break; } @@ -188,34 +185,32 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { private _onTransitionEnd = () => { this._transitionSpec = this._buildTransitionSpec(this._state); - console.log('onTransitionEnd', this._transitionSpec); - this._owner.setState({state: this._state}); + this._owner.setState({ state: this._state }); if (this._owner.props.transitionCompleted) { this._owner.props.transitionCompleted(); } - } + }; private _onTransitionStart = (transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps) => { - console.log('onTransitionStart', this._transitionSpec); if (this._owner.props.transitionStarted) { const fromIndex = prevTransitionProps && prevTransitionProps.scene ? prevTransitionProps.scene.index : undefined; const toIndex = transitionProps.scene ? transitionProps.scene.index : undefined; const fromRouteId = prevTransitionProps && prevTransitionProps.scene ? prevTransitionProps.scene.route.key : undefined; const toRouteId = transitionProps.scene ? transitionProps.scene.route.key : undefined; this._owner.props.transitionStarted( - transitionProps.position, + transitionProps.position, toRouteId, fromRouteId, - toIndex, + toIndex, fromIndex); } - } + }; // Callback from Navigator.js to RX.Navigator private _renderScene = (props: NavigationSceneRendererProps): JSX.Element => { - let parentState: NavigationState = props.navigationState; - let sceneState: NavigationRouteState = parentState.routes[props.scene.index] as NavigationRouteState; + const parentState: NavigationState = props.navigationState; + const sceneState: NavigationRouteState = parentState.routes[props.scene.index] as NavigationRouteState; // Does the route exist? if (sceneState && sceneState.route) { @@ -225,7 +220,7 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { // No route? Return empty scene. return ; - } + }; handleBackPress(): void { this._owner.pop(); @@ -238,16 +233,16 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { } const previousState: NavigationState = this._state; - let useNewStateAsScene = false; + let useNewStateAsScene = false; + + const command = commandQueue.shift()!; + const route = command.param.route; + const value = command.param.value; - let command = commandQueue.shift()!!!; - let route = command.param.route; - let value = command.param.value; - console.log('processing navigation command:', JSON.stringify(command), 'on stack:', JSON.stringify(this._state)); switch (command.type) { case CommandType.Push: useNewStateAsScene = true; - this._state = StateUtils.push(this._state, this._createState(route!!!)); + this._state = StateUtils.push(this._state, this._createState(route)); break; case CommandType.Pop: @@ -268,10 +263,10 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { case CommandType.Replace: if (value === -1) { this._state = StateUtils.replaceAtIndex(this._state, this._state.routes.length - 2, - this._createState(route!!!)); + this._createState(route)); } else { this._state = StateUtils.replaceAtIndex(this._state, this._state.routes.length - 1, - this._createState(route!!!)); + this._createState(route)); } break; @@ -281,17 +276,14 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { break; } - console.log('stack after execution is:', JSON.stringify(this._state)); - if (previousState !== this._state) { if (useNewStateAsScene) { this._transitionSpec = this._buildTransitionSpec(this._state); } else { this._transitionSpec = this._buildTransitionSpec(previousState); } - console.log('transition spec:', this._transitionSpec, useNewStateAsScene); - this._owner.setState({state: this._state}); + this._owner.setState({ state: this._state }); } } @@ -300,15 +292,15 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { */ private _onNavigateBack = () => { this.onBackPress(); - } + }; private _createState(route: NavigatorRoute): NavigationRouteState { - return { key: route.routeId.toString(), route: route}; + return { key: route.routeId.toString(), route: route }; } private _createParentState(routes: NavigatorRoute[], prevState: NavigationState): NavigationState { const prevRoutes = prevState.routes as NavigationRouteState[]; - let children = _.map(routes, (element, index) => { + const children = _.map(routes, (element: NavigatorRoute, index: number) => { if (prevRoutes.length > index) { const prevRoute = prevRoutes[index]; // Navigator state reducer is a little bit naive, @@ -333,19 +325,19 @@ export class NavigatorExperimentalDelegate extends NavigatorDelegate { } private _popN(state: NavigationState, n: number): NavigationState { - assert.ok(n > 0, 'n < 0 please pass positive value'); + assert(n > 0, 'n < 0 please pass positive value'); const initialRoutes = state.routes; const initialLength = initialRoutes.length; - assert.ok(initialLength >= n, 'navigation stack underflow'); + assert(initialLength >= n, 'navigation stack underflow'); - let result: NavigationState = _.clone(state); + const result: NavigationState = _.clone(state); result.routes = initialRoutes.slice(0, initialLength - n); result.index = initialLength - n - 1; return result; } private _popToRoute(state: NavigationState, route: NavigatorRoute): NavigationState { - let popCount: number = 0; + let popCount = 0; for (let i = state.routes.length - 1; i >= 0; i--) { const child = state.routes[i] as NavigationRouteState; if (route.routeId === child.route.routeId) { diff --git a/extensions/navigation/src/typings/react-native-deprecated-custom-components.d.ts b/extensions/navigation/src/typings/react-native-deprecated-custom-components.d.ts index cf4b22b09..b2a6ac64a 100644 --- a/extensions/navigation/src/typings/react-native-deprecated-custom-components.d.ts +++ b/extensions/navigation/src/typings/react-native-deprecated-custom-components.d.ts @@ -1,5 +1,5 @@ declare module 'react-native-deprecated-custom-components' { - import RN = require('react-native'); + import * as RN from 'react-native'; interface NavigatorProps extends RN.ComponentPropsBase { configureScene?: Function; @@ -7,8 +7,8 @@ declare module 'react-native-deprecated-custom-components' { initialRouteStack?: any[]; navigatorBar?: any; navigator?: Navigator; - onDidFocus?: Function; //deprecated - onWillFocus?: Function; //deprecated + onDidFocus?: Function; // deprecated + onWillFocus?: Function; // deprecated renderScene: Function; sceneStyle?: RN.StyleRuleSet | RN.StyleRuleSet[]; } @@ -21,7 +21,7 @@ declare module 'react-native-deprecated-custom-components' { FloatFromBottom: any; FloatFromBottomAndroid: any; FadeAndroid: any; - HorizontalSwipeJump:any; + HorizontalSwipeJump: any; }; getCurrentRoutes(): any[]; jumpBack(): void; @@ -36,5 +36,4 @@ declare module 'react-native-deprecated-custom-components' { popToRoute(route: any): void; popToTop(): void; } - -} \ No newline at end of file +} diff --git a/extensions/navigation/src/typings/react-native.d.ts b/extensions/navigation/src/typings/react-native.d.ts deleted file mode 100644 index f6587f177..000000000 --- a/extensions/navigation/src/typings/react-native.d.ts +++ /dev/null @@ -1,1091 +0,0 @@ -/** -* react-native.d.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definition file for React Native, based on the React.js definition file -* on https://github.com/borisyankov/DefinitelyTyped. -*/ - -declare module 'react-native' { - // - // React - // ---------------------------------------------------------------------- - - import React = require('react'); - - // BT: Adding ProgressBarAndroid. It's not part of the DefinitelyTyped definitions. - class ProgressBarAndroid extends React.Component {} - - type ReactElement = React.ReactElement; - type ReactNode = React.ReactNode; - - function createElement

( - type: string, - props?: P, - ...children: React.ReactNode[]): React.ReactElement

; - - function cloneElement

( - element: P, - props ?: any - ): React.ReactElement

; - - interface SyntheticEvent extends React.SyntheticEvent {} - - function isValidElement(object: {}): boolean; - function findNodeHandle(componentOrHandle: any): number; - - var Children: React.ReactChildren; - - type PlatformString = 'android'|'ios'|'windows'; - var Platform: { - OS: PlatformString, - Version?: number - }; - - // - // Component base - // ---------------------------------------------------------------------- - - abstract class ReactNativeBaseComponent extends React.Component { - setNativeProps(nativeProps: P): void; - focus(): void; - blur(): void; - measure(callback: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void)): void; - measureLayout(relativeToNativeNode: number, onSuccess: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void), onFail: () => void): void; - refs: { - [key: string]: ReactNativeBaseComponent; - } - } - - // - // Style rules - // ---------------------------------------------------------------------- - - type StyleRuleSet = Object | Object[]; - - // - // Specific components - // ---------------------------------------------------------------------- - - interface ComponentPropsBase { - ref?: string | ((obj: ReactNativeBaseComponent) => void); - key?: string | number; - } - - interface ComponentPropsStyleBase extends ComponentPropsBase { - style?: StyleRuleSet | StyleRuleSet[]; - } - - interface ImageSource { - uri: string; - headers?: {[header: string]: string}; - } - - interface ImageProps extends ComponentPropsStyleBase { - onLayout?: Function; - resizeMode?: string; - resizeMethod?: string; // android only prop: 'auto' | 'resize' | 'scale' - source?: ImageSource | number; - testID?: string; - - // iOS - accessibilityLabel?: string; - shouldRasterizeIOS?: boolean; - accessible?: boolean; - capInsets?: Object; - defaultSource?: Object; - onError?: Function; - onLoad?: Function; - onLoadEnd?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - onProgress?: Function; - - // Android - fadeDuration?: number; - } - - interface ActivityIndicatorProps extends ComponentPropsBase { - animating?: boolean; - color?: string; - onLayout?: Function; - size?: string; // enum { 'small', 'large' } - } - - interface TextProps extends ComponentPropsStyleBase { - importantForAccessibility?: string; // 'auto' | 'yes' | 'no' | 'no-hide-descendants'; - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - children? : React.ReactNode; - numberOfLines? : number; - ellipsizeMode? : 'head' | 'middle' | 'tail' // There's also 'clip' but it is iOS only - onLayout? : Function; - onPress? : Function; - onLongPress? : Function; - selectable? : boolean; // only on android, windows - testID? : string; - - // iOS - suppressHighlighting?: boolean; - - // Android - textBreakStrategy?: 'highQuality' | 'simple'| 'balanced'; - elevation?: number; - } - - export interface PickerProps extends ComponentPropsStyleBase { - - /** - * Callback for when an item is selected. This is called with the - * following parameters: - * - itemValue: the value prop of the item that was selected - * - itemPosition: the index of the selected item in this picker - * @param itemValue - * @param itemPosition - */ - onValueChange?: ( itemValue: any, itemPosition: number ) => void - - /** - * Value matching value of one of the items. - * Can be a string or an integer. - */ - selectedValue?: any - - style?: StyleRuleSet | StyleRuleSet[] - - /** - * Used to locate this view in end-to-end tests. - */ - testId?: string - - ref?: string | ((obj: ReactNativeBaseComponent) => void); - } - - interface TouchableWithoutFeedbackProps extends ComponentPropsBase { - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - accessible?: boolean; - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - delayLongPress?: number; - delayPressIn?: number; - delayPressOut?: number; - onLayout?: Function; - onLongPress?: Function; - onPress?: Function; - onPressIn?: Function; - onPressOut?: Function - } - - interface TouchableHighlightProps extends TouchableWithoutFeedbackProps, ComponentPropsStyleBase { - activeOpacity? : number; - children? : React.ReactNode; - onHideUnderlay?: Function; - onShowUnderlay?: Function; - underlayColor? : string; - } - - interface ResponderProps { - onMoveShouldSetResponder? : Function; - onResponderGrant? : Function; - onResponderMove? : Function; - onResponderReject? : Function; - onResponderRelease? : Function; - onResponderTerminate? : Function; - onResponderTerminationRequest? : Function; - onStartShouldSetResponder? : Function; - onStartShouldSetResponderCapture?: Function; - } - - interface ViewOnLayoutEvent { - nativeEvent: { - layout: { - x: number, - y: number, - width: number, - height: number - } - } - } - - type ViewLayerType = 'none' | 'software' | 'hardware'; - - interface CommonAccessibilityProps { - accessibilityLabel? : string; - accessible? : boolean; - onAcccessibilityTap? : Function; - - // android - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityLiveRegion? : string; //enum ( 'none', 'polite', 'assertive' ) - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - - // iOS - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - } - - interface ViewProps extends ComponentPropsBase, ResponderProps, ComponentPropsStyleBase, CommonAccessibilityProps { - children? : any; - onLayout? : ((ev: ViewOnLayoutEvent) => void); - onMagicTap? : Function; - pointerEvents? : string; //enum( 'box-none', 'none', 'box-only', 'auto' ); - removeClippedSubviews? : boolean; - testID? : string; - - // android - collapsable? : boolean; - needsOffscreenAlphaCompositing?: boolean; - renderToHardwareTextureAndroid?: boolean; - viewLayerTypeAndroid? : ViewLayerType; - elevation? : number; - - // iOS - onAccessibilityTapIOS?: Function; - shouldRasterizeIOS? : boolean; - } - - interface ScrollViewProps extends ViewProps { - children?: any; - - contentContainerStyle?: StyleRuleSet | StyleRuleSet[]; - horizontal?: boolean; - keyboardDismissMode?: 'none' | 'interactive' | 'on-drag'; - keyboardShouldPersistTaps?: 'always' | 'never' | 'handled'; - onScroll?: Function; - onScrollBeginDrag?: Function; - onScrollEndDrag?: Function; - onContentSizeChange?: (width: number, height: number) => void; - showsHorizontalScrollIndicator?: boolean; - showsVerticalScrollIndicator?: boolean; - removeClippedSubviews?: boolean; - - // iOS - automaticallyAdjustContentInsets?: boolean; - //contentInset?: EdgeInsetsPropType; - //contentOffset?: PointPropType; - bounces?: boolean; - bouncesZoom?: boolean; - alwaysBounceHorizontal?: boolean; - alwaysBounceVertical?: boolean; - centerContent?: boolean; - decelerationRate?: number; - directionalLockEnabled?: boolean; - canCancelContentTouches?: boolean; - maximumZoomScale?: number; - minimumZoomScale?: number; - onScrollAnimationEnd?: Function; - pagingEnabled?: boolean; - scrollEnabled?: boolean; - scrollEventThrottle?: number; - scrollsToTop?: boolean; - stickyHeaderIndices?: [number]; - snapToInterval?: number; - snapToAlignment?: string; // enum( 'start', 'center', 'end' ) - zoomScale?: number; - overScrollMode?: string; //enum( 'always', 'always-if-content-scrolls', 'never' ) - // iOS - scrollIndicatorInsets?: {top: number, left: number, bottom: number, right: number }; - } - - interface ListViewDataSourceCallback { - rowHasChanged: (r1: T, r2: T) => boolean; - } - - interface ListViewDataSource { - new (onAsset: ListViewDataSourceCallback): ListViewDataSource; - cloneWithRows(rowList: T[]): void; - } - - interface ListViewProps extends ScrollViewProps { - dataSource: Object; //PropTypes.instanceOf(ListViewDataSource).isRequired - renderSeparator?: Function; - renderRow: Function; - initialListSize?: number; - onEndReached?: (e: React.SyntheticEvent) => void; - onEndReachedThreshold?: number; - pageSize?: number; - renderFooter?: Function; - renderHeader?: Function; - renderSectionHeader?: Function; - renderScrollComponent: Function; - scrollRenderAheadDistance?: number; - onChangeVisibleRows?: Function; - removeClippedSubviews?: boolean; - } - - interface ModalProps extends ComponentPropsBase { - animationType?: string; // enum( 'none', 'slide', 'fade' ) - onDismiss?: Function; - transparent?: boolean; - onRequestClose: () => void; - } - - interface TextInputProps extends ComponentPropsStyleBase, CommonAccessibilityProps { - autoCapitalize?: string; // enum('none', 'sentences', 'words', 'characters') - autoCorrect?: boolean; - autoFocus?: boolean; - blurOnSubmit?: boolean; - defaultValue?: string; - editable?: boolean; - keyboardType?: string; // enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search') - multiline?: boolean; - onBlur?: ((e: React.FocusEvent) => void); - onKeyPress?: (e: SyntheticEvent) => void; - onChange?: Function; - onChangeText?: ((changedText: string) => void); - onSelectionChange?: ((selection: SyntheticEvent) => void); - onEndEditing?: Function; - onFocus?: ((e: React.FocusEvent) => void); - onLayout?: ((props: { x: number, y: number, width: number, height: number }) => void); - onSubmitEditing?: Function; - onScroll?: Function; - placeholder?: string; - placeholderTextColor?: string; - returnKeyType?: string; // enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call') - secureTextEntry?: boolean; - testID?: string; - textAlign?: string; // enum('auto' | 'left' | 'right' | 'center' | 'justify') - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - selection?: { start: number, end: number }; - - //iOS and android - selectionColor?: string; - - value: string; - //iOS - clearButtonMode?: string; // enum('never', 'while-editing', 'unless-editing', 'always') - clearTextOnFocus?: boolean; - enablesReturnKeyAutomatically?: boolean; - keyboardAppearance?: string; // enum ('default', 'light', 'dark') - maxLength?: number; - numberOfLines?: number; - selectTextOnFocus?: boolean; - selectionState?: any; // see DocumentSelectionState.js - spellCheck?: boolean; - //android - textAlignVertical?: string; // enum('top', 'center', 'bottom') - textAlignVerticalAndroid?: string; // enum('top', 'center', 'bottom') - textAlignAndroid?: string; - underlineColorAndroid?: string; - disableFullscreenUI?: boolean; - textBreakStrategy?: 'highQuality' | 'simple' | 'balanced'; - } - - interface TextInputState { - currentlyFocusedField(): number; - focusTextInput(textFieldID?: number): void; - blurTextInput(textFieldID?: number): void; - } - - interface WebViewProps extends ComponentPropsStyleBase { - automaticallyAdjustContentInsets?: boolean; - bounces?: boolean; - contentInset?: {top: number, left: number, bottom: number, right: number }; - injectedJavaScript?: string; - javaScriptEnabled?: boolean; - domStorageEnabled?: boolean; - onShouldStartLoadWithRequest?: Function; - onNavigationStateChange?: Function; - onLoad?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - renderError?: Function; - onError?: Function; - renderLoading?: Function; - scalesPageToFit?: boolean; - scrollEnabled?: boolean; - startInLoadingState?: boolean; - source?: { uri: string; method?: string; headers?: Object; body?: string; } | { html: string; baseUrl?: string; }; - } - - interface DatePickerIOSProps extends ComponentPropsStyleBase { - date?: Date; - maximumDate?: Date; - minimumDate?: Date; - minuteInterval?: number; - mode?: string; - timeZoneOffsetInMinutes?: number; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerIOS extends ReactNativeBaseComponent { - } - - interface DatePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerAndroid extends ReactNativeBaseComponent { - static open(options: { date: Date, maxDate: Date, minDate: Date }): Promise; - static dateSetAction: Function; - static dismissedAction: Function; - } - - interface TimePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class TimePickerAndroid extends ReactNativeBaseComponent { - static open(options: { hour: number, minute: number, is24Hour: boolean }): Promise; - static timeSetAction: Function; - static dismissedAction: Function; - } - - type DatePickerAction = { - action: Function; - day: number; - month: number; - year: number; - } - - type TimePickerAction = { - action: Function; - hour: number; - minute: number; - } - - class Image extends ReactNativeBaseComponent { - static prefetch(url: string): Promise; - } - class ActivityIndicator extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - class Picker extends ReactNativeBaseComponent { - static Item: any; - } - class TouchableHighlight extends ReactNativeBaseComponent { } - class TouchableWithoutFeedback extends ReactNativeBaseComponent { } - class View extends ReactNativeBaseComponent { } - class ScrollView extends ReactNativeBaseComponent { - getInnerViewNode(): number; - // TODO: Define ScrollResponder type - scrollTo(val: { x?: number; y?: number; animated?: boolean; }): void; - scrollBy(val: { deltaX?: number; deltaY?: number; animated?: boolean; }): void; - } - class ListView extends ReactNativeBaseComponent { - static DataSource: ListViewDataSource; - } - class Modal extends ReactNativeBaseComponent { } - class TextInput extends ReactNativeBaseComponent { - static State: TextInputState; - } - class WebView extends ReactNativeBaseComponent { - reload() : void; - goBack() : void; - goForward() : void; - } - - interface ActionSheetOptions { - options: string[]; - cancelButtonIndex?: number; - destructiveButtonIndex?: number; - title?: string; - message?: string; - } - - interface ShareActionSheetOptions { - message?: string; - url?: string; - subject?: string; - excludedActivityTypes?: string[]; - } - - class ActionSheetIOS { - static showActionSheetWithOptions(options: ActionSheetOptions, callback: (buttonIndex: number) => void): void; - static showShareActionSheetWithOptions(options: ShareActionSheetOptions, failureCallback: (error: string) => void, successCallback: (success: boolean, method: string) => void): void; - } - - class BackAndroid { - static addEventListener(eventName: string, callback: () => boolean): void; - static removeEventListener(eventName: string, callback: () => boolean): void; - } - - interface NavigatorIOSRoute { - component: any; - title: string; - passProps?: any; - backButtonTitle?: string; - backButtonIcon?: any; - leftButtonTitle?: string; - leftButtonIcon?: any; - onLeftButtonPress?: () => void; - rightButtonTitle?: string; - rightButtonIcon?: any; - onRightButtonPress?: () => void; - wrapperStyle?: any; - } - - interface NavigatorIOSProps extends ComponentPropsBase { - barTintColor?: string; - initialRoute: NavigatorIOSRoute; - itemWrapperStyle?: StyleRuleSet | StyleRuleSet[]; - navigationBarHidden?: boolean; - shadowHidden?: boolean; - style?:any; - tintColor?: string; - titleTextColor?: string; - translucent?: boolean; - interactivePopGestureEnabled?: boolean; - } - - class StatusBar { - // Native - static setHidden(hidden: boolean, animation?: string): void; //'none'|'fade'|'slide'; - - // iOS - static setBarStyle(barStyle: string, animated: boolean): void; //'default'|'light-content'; - static setNetworkActivityIndicatorVisible(value: boolean): void; - - // Android - static setBackgroundColor(color: string, animated?: boolean): void; - static setTranslucent(translucent: boolean): void; - } - - interface EventSubscription { - remove(): void; - } - - interface NavigatorIOSNavigationContext { - addListener(event: string, callback: (route: NavigatorIOSRoute) => void): EventSubscription; - } - - interface NavigatorIOSState { - observedTopOfStack: number; - requestedTopOfStack: number; - routeStack: NavigatorIOSRoute[]; - } - - class NavigatorIOS extends ReactNativeBaseComponent { - navigationContext: NavigatorIOSNavigationContext; - push(route: NavigatorIOSRoute): void; - pop(): void; - popN(n: number): void; - replace(route: NavigatorIOSRoute): void; - replacePrevious(route: NavigatorIOSRoute): void; - replacePreviousAndPop(route: NavigatorIOSRoute): void; - resetTo(route: NavigatorIOSRoute): void; - popToRoute(route: NavigatorIOSRoute): void; - popToTop(): void; - } - - // StyleSheet - class StyleSheet { - static create(obj: { [key: string]: any }): any; - static flatten: (s: StyleSheet) => { [key: string]: any }; - } - - class AppRegistry { - static registerComponent(appKey: string, getComponentFunc: Function): any; - } - - type CameraRollProps = { - /** - * The number of photos wanted in reverse order of the photo application - * (i.e. most recent first for SavedPhotos). - */ - first: number, - - /** - * A cursor that matches `page_info { end_cursor }` returned from a previous - * call to `getPhotos` - */ - after?: string, - - /** - * Specifies which group types to filter the results to. - */ - groupTypes?: string, // enum { 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream', 'SavedPhotos', // default }, - - /** - * Specifies filter on group names, like 'Recent Photos' or custom album - * titles. - */ - groupName?: string, - - /** - * Specifies filter on asset type - */ - assetType?: string; // enum { 'All', 'Videos', 'Photos', // default }, - - } - - type GetPhotosCallbackPropNode = { - node: { - type: string, - group_name: string, - image: { - uri: string, - height: number, - width: number, - isStored?: boolean, - }, - timestamp: number, - location?: { - latitude?: number, - longitude?: number, - altitude?: number, - heading?: number, - speed?: number, - } - } - } - - type GetPhotosCallbackProps = { - edges: GetPhotosCallbackPropNode[], - page_info: { - has_next_page: boolean, - start_cursor?: string, - end_cursor?: string, - } - } - - class Clipboard { - static setString(content: string): void; - static getString(): Promise; - } - - class CameraRoll { - static saveImageWithTag(tag: string, successCallback: Function, errorCallback: Function): void; - static getPhotos(params: CameraRollProps, callback: ((props: GetPhotosCallbackProps) => void), errorCallback: Function): void; - } - - class Linking { - static getInitialURL(): Promise; - static openURL(url: string): Promise; - static canOpenURL(url: string): Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - } - - class AccessibilityInfo { - static fetch: () => Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - static announceForAccessibility(announcement: string): void; - static setAccessibilityFocus(reactTag: number): void; - } - - interface AlertButtonSpec { - text?: string; - onPress?: () => void; - style?: string; // enum {default', 'cancel', 'destructive'} - } - - class Alert { - static alert( - title: string, - message?: string, - buttons?: AlertButtonSpec[], - type?: string // enum { 'default', 'plain-text', 'secure-text', 'login-password'} - ): void; - } - - class PushNotificationIOS { - static presentLocalNotification(details: { category: string, alertBody: string, soundName?: string}): void; - static scheduleLocalNotification(details: {alertBody: string, fireDate: Date}): void; - - static getApplicationIconBadgeNumber(callback: (badgeCount:number) => void): void; - static setApplicationIconBadgeNumber(number: number): void; - - static addEventListener(type: string, handler: (event: any) => void): void; - - static requestPermissions(permissions?: {alert?: boolean, badge?: boolean, sound?: boolean}): void; - static abandonPermissions(): void; - static checkPermissions(callback: (permissions: {alert: boolean, badge: boolean, sound: boolean}) => void): void; - - static getInitialNotification(): Promise; - - getMessage(): string; - getSound(): string; - getAlert(): any; - getBadgeCount(): number; - getData(): any; - } - - interface PanResponderGestureState { - stateID: number; - moveX: number; - moveY: number; - x0: number; - y0: number; - dx: number; - dy: number; - vx: number; - vy: number; - numberActiveTouches: number; - } - - interface ResponderSyntheticEvent extends React.SyntheticEvent { - touchHistory: Function; - } - - type PanResponderCreateConfig = { - onMoveShouldSetPanResponder?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean, - onMoveShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderReject?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderGrant?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderStart?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderEnd?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderRelease?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderMove?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminate?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminationRequest?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onShouldBlockNativeResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), // android only - onStartShouldSetResponderCapture?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void, - - } - - class PanResponder { - static create(config: PanResponderCreateConfig): PanResponder; - panHandlers: ResponderProps; - } - - type DimensionType = { - width: number, - height: number, - scale: number, - fontScale: number, - } - - class Dimensions { - static set(obj: any): boolean; - static get(key: string): DimensionType; - } - - type RCTAppStateData = { app_state: string } - type RCTAppState = { - getCurrentAppState(successCallback: (appStateData: RCTAppStateData) => void, failureCallback: () => void): void; - } - - type FileInput = { - selectImage: Function; - } - - type SnapshotOptions = { - width?: number; - height?: number; - format?: 'png' | 'jpeg'; - quality?: number; - } - - type UIManager = { - measure: Function; - measureInWindow: Function; - measureLayout: Function; - measureLayoutRelativeToParent: Function; - dispatchViewManagerCommand: Function; - - getMaxContentSizeMultiplier: Function; - setMaxContentSizeMultiplier: Function; - - // ios - takeSnapshot: (view: any, options?: SnapshotOptions) => Promise; - - // Android - sendAccessibilityEvent: Function; - } - - type AccessibilityManager = { - getMultiplier: Function; - announceForAccessibility (announcement: string): void; - } - - // We don't use this module, but need to be able to check its existance - type NativeAnimatedModule = { - - }; - - class ImagePickerManager { - showImagePicker: Function; - launchCamera: Function; - launchImageLibrary: Function; - } - - class NativeModules { - static AppState: RCTAppState; - static FileInput: FileInput; - static UIManager: UIManager; - static AccessibilityManager: AccessibilityManager; - static ImagePickerManager: ImagePickerManager; - static Networking: { - clearCookies(callback: (success: boolean) => void): void; - } - static ContextMenuAndroid: { - show(buttons: any, callback: (command: string) => void): void; - } - static NativeAnimation: NativeAnimatedModule; - } - - class AsyncStorage { - static getItem(key: string, callback: (error: any, result: string) => void): void; - static setItem(key: string, value: string, callback: (error: any) => void): void; - static removeItem(key: string, callback: (error: any) => void): void; - static clear(callback: (error: any) => void): void; - } - - class NetInfo { - static isConnected: { - addEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - removeEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - fetch: () => Promise; - } - static fetch(): Promise; - } - - class Easing { - static bezier(x1: number, y1: number, x2: number, y2: number): ((input: number) => number); - static linear(): ((input: number) => number); - } - - interface AnimationConfig { - isInteraction?: boolean; - useNativeDriver?: boolean; - } - - interface AnimatedTimingConfig extends AnimationConfig { - toValue: number; - duration?: number; - delay?: number - easing?: (input: number) => number; - } - - interface CompositeAnimation { - start(callback?: AnimatedEndCallback): void; - stop: () => void; - } - - type AnimatedEndResult = { finished: boolean }; - type AnimatedEndCallback = (result: AnimatedEndResult) => void; - - module Animated { - function createAnimatedComponent(Component: any, notCollapsable?: boolean): any; - function delay(time: number): CompositeAnimation; - function timing(value: Animated.Value, config: AnimatedTimingConfig): CompositeAnimation; - function parallel(animations: CompositeAnimation[]): CompositeAnimation - function sequence(animations: CompositeAnimation[]): CompositeAnimation - class Value { - constructor(val: number); - setValue(value: number): void; - addListener(callback: any): string; - removeListener(id: string): void; - removeAllListeners(): void; - interpolate(config: any): Value; - } - class View extends ReactNativeBaseComponent { } - class Image extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - } - - interface IUpdateLayoutAnimationConfig { - duration?: number; - delay?: number; - - springDamping?: number; - initialVelocity?: number; - - type?: string; - } - - interface ICreateLayoutAnimationConfig extends IUpdateLayoutAnimationConfig { - property?: string; - } - - interface ILayoutAnimationConfig { - duration: number; - create?: ICreateLayoutAnimationConfig; - update?: IUpdateLayoutAnimationConfig; - } - - module LayoutAnimation { - function configureNext(config: ILayoutAnimationConfig): void; - - module Types { - var spring: string; - var linear: string; - var easeInEaseOut: string; - var easeIn: string; - var easeOut: string; - var keyboard: string; - } - - module Properties { - var opacity: string; - var scaleXY: string; - } - } - - class DeviceEventSubscription { - remove(): void; - } - - class NativeAppEventEmitter { - static addListener(eventId: string, callback: Function): DeviceEventSubscription; - } - - module DeviceEventEmitter{ - function addListener(name: string, callback: Function): void; - } - - module AppState { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module AppStateIOS { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module Touchable { - type RectOffset = { - top: number, - left: number, - right: number, - bottom: number - } - - interface State { - touchable: any - } - - interface TouchableMixin extends React.Mixin { - touchableGetInitialState: () => State - touchableHandleStartShouldSetResponder: () => {} - touchableHandleResponderTerminationRequest: () => {} - touchableHandleResponderGrant: (e: React.SyntheticEvent, dispatchID: string) => {} - touchableHandleResponderMove: (e: React.SyntheticEvent) => {} - touchableHandleResponderRelease: (e: React.SyntheticEvent) => {} - touchableHandleResponderTerminate: (e: React.SyntheticEvent) => {} - touchableHandleActivePressIn?: (e: React.SyntheticEvent) => {} - touchableHandleActivePressOut?: (e: React.SyntheticEvent) => {} - touchableHandlePress?: (e: React.SyntheticEvent) => {} - touchableHandleLongPress?: (e: React.SyntheticEvent) => {} - touchableGetHighlightDelayMS?: () => number - touchableGetPressRectOffset?: () => RectOffset - } - - var Mixin: TouchableMixin; - } - - class EmitterSubscription { - remove(): void; - } - - module Keyboard { - function addListener(eventType: string, listener: Function, context?: any): EmitterSubscription; - function removeAllListeners(eventType: string): void; - function removeSubscription(subscription: EmitterSubscription): void; - } - - module PixelRatio { - /** - * Returns the device pixel density. Some examples: - * - * - PixelRatio.get() === 1 - * - mdpi Android devices (160 dpi) - * - PixelRatio.get() === 1.5 - * - hdpi Android devices (240 dpi) - * - PixelRatio.get() === 2 - * - iPhone 4, 4S - * - iPhone 5, 5c, 5s - * - iPhone 6 - * - xhdpi Android devices (320 dpi) - * - PixelRatio.get() === 3 - * - iPhone 6 plus - * - xxhdpi Android devices (480 dpi) - * - PixelRatio.get() === 3.5 - * - Nexus 6 - **/ - function get(): number; - - /** - * Returns the scaling factor for font sizes. This is the ratio that is used to calculate the - * absolute font size, so any elements that heavily depend on that should use this to do - * calculations. - * - * If a font scale is not set, this returns the device pixel ratio. - * - * Currently this is only implemented on Android and reflects the user preference set in - * Settings > Display > Font size, on iOS it will always return the default pixel ratio. - * @platform android - **/ - function getFontScale(): number; - - /** - * Converts a layout size (dp) to pixel size (px). - * - * Guaranteed to return an integer number. - **/ - function getPixelSizeForLayoutSize(layoutSize: number): number; - - /** - * Rounds a layout size (dp) to the nearest layout size that corresponds to - * an integer number of pixels. For example, on a device with a PixelRatio - * of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to - * exactly (8.33 * 3) = 25 pixels. - **/ - function roundToNearestPixel(layoutSize: number): number; - } - - interface IncrementalProps extends ComponentPropsStyleBase { - onDone?: () => void; - name: string; - children?: any; - } - - interface IncrementalPresenterProps extends ComponentPropsStyleBase { - name: string; - disabled?: boolean; - onDone?: () => void; - onLayout?: (event: Object) => void; - style?: any; - children?: any; - } - - class Incremental extends ReactNativeBaseComponent { - } - - class IncrementalGroup extends ReactNativeBaseComponent{ - } - - class IncrementalPresenter extends ReactNativeBaseComponent { - } - - module JSEventLoopWatchdog { - function install(obj: any): void; - } - - module InteractionManager { - function setDeadline(deadline: number): void; - } - - interface I18nManager { - isRTL: boolean - allowRTL: (allowRTL: boolean) => {} - forceRTL: (forceRTL: boolean) => {} - } - - export var I18nManager: I18nManager; -} - -interface GeoConfiguration { - skipPermissionRequests: boolean; -} - -interface Geolocation { - // React Native addition to navigator.geolocation - setRNConfiguration(config: GeoConfiguration): void; -} - diff --git a/extensions/navigation/src/web/Navigator.tsx b/extensions/navigation/src/web/Navigator.tsx index bef9618b1..826619ab6 100644 --- a/extensions/navigation/src/web/Navigator.tsx +++ b/extensions/navigation/src/web/Navigator.tsx @@ -1,33 +1,31 @@ /* -* Navigator.tsx -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Web specific implementation of Navigator. This is inspired from React.Navigator. -* This component is set with props, which are callback methods. It is primarily driven -* by state updates instigated by its public helpers like immediatelyResetRouteStack, push, -* pop, which update the state and cause transitions. -*/ - -import _ = require('../common/lodashMini'); -import React = require('react'); -import ReactDOM = require('react-dom'); -import RX = require('reactxp'); + * Navigator.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Web specific implementation of Navigator. This is inspired from React.Navigator. + * This component is set with props, which are callback methods. It is primarily driven + * by state updates instigated by its public helpers like immediatelyResetRouteStack, push, + * pop, which update the state and cause transitions. + */ + +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import * as RX from 'reactxp'; +import * as rebound from 'rebound'; import { Styles, View } from 'reactxp'; -import rebound = require('rebound'); - -import { NavigatorSceneConfigFactory } from './NavigatorSceneConfigFactory'; -import { NavigatorSceneConfig } from './NavigatorSceneConfigFactory'; +import * as _ from '../common/lodashMini'; +import * as Types from '../common/Types'; import { - Navigator as NavigatorBase, NavigatorDelegateSelector as DelegateSelector, + NavigatorState as BaseNavigatorState, + Navigator as NavigatorBase, NavigatorProps, - NavigatorState as BaseNavigatorState } from '../common/Types'; -import Types = require('../common/Types'); +import { NavigatorSceneConfigFactory, NavigatorSceneConfig } from './NavigatorSceneConfigFactory'; // [Bug:506870] Move web navigator to RX animated API export interface SpringSystem { @@ -51,14 +49,14 @@ const _styles = { flex: 1, flexDirection: 'column', alignSelf: 'stretch', - overflow: 'hidden' + overflow: 'hidden', }), defaultSceneStyle: Styles.createViewStyle({ position: 'absolute', left: 0, right: 0, bottom: 0, - top: 0 + top: 0, }), baseScene: Styles.createViewStyle({ position: 'absolute', @@ -66,26 +64,26 @@ const _styles = { left: 0, right: 0, bottom: 0, - top: 0 + top: 0, }), disabledScene: Styles.createViewStyle({ top: 0, bottom: 0, - flex: 1 + flex: 1, }), transitioner: Styles.createViewStyle( { flex: 1, flexDirection: 'column', backgroundColor: 'transparent', overflow: 'hidden', - alignItems: 'stretch' + alignItems: 'stretch', }), sceneStyle: Styles.createViewStyle({ flex: 1, shadowOffset: { height: 0, width: 0 }, shadowRadius: 40, - shadowColor: 'rgba(0, 0, 0, 0.2)' - }) + shadowColor: 'rgba(0, 0, 0, 0.2)', + }), }; // Transition types @@ -129,6 +127,10 @@ export class NavigatorImpl extends NavigatorBase { // Keep a map of all rendered scenes, keyed off their routeId private _renderedSceneMap: { [routeId: number]: JSX.Element } = {}; + // References to mounted components. + private _containerRef: RX.View | null; + private _sceneRefs: { [sceneIndex: string]: RX.View } = {}; + // Save a public reference to the parent navigator if one was given in props. navigatorReference: Navigator; @@ -150,11 +152,11 @@ export class NavigatorImpl extends NavigatorBase { routeStack: [], presentedIndex: 0, transitionFromIndex: undefined, - transitionQueue: [] + transitionQueue: [], }; } - componentWillMount() { + UNSAFE_componentWillMount() { this.springSystem = new rebound.SpringSystem(); this.spring = this.springSystem.createSpring(); this.spring.setRestSpeedThreshold(0.05); @@ -165,7 +167,7 @@ export class NavigatorImpl extends NavigatorBase { }, onSpringAtRest: () => { this._completeTransition(); - } + }, }); } @@ -179,7 +181,7 @@ export class NavigatorImpl extends NavigatorBase { } render() { - let newRenderedSceneMap: { [routeId: number]: JSX.Element } = {}; + const newRenderedSceneMap: { [routeId: number]: JSX.Element } = {}; let scenes: JSX.Element[]; if (this.state.routeStack.length > 0) { @@ -210,7 +212,7 @@ export class NavigatorImpl extends NavigatorBase { > { scenes } @@ -241,12 +243,12 @@ export class NavigatorImpl extends NavigatorBase { const nextStack = activeStack.concat([route]); const destIndex = nextStack.length - 1; const nextAnimationConfigStack: NavigatorSceneConfig [] = activeAnimationConfigStack.concat([ - this._getSceneConfigFromRoute(route) + this._getSceneConfigFromRoute(route), ]); this.setState({ routeStack: nextStack, - sceneConfigStack: nextAnimationConfigStack + sceneConfigStack: nextAnimationConfigStack, }, () => { this._enableScene(destIndex); this._transitionTo(destIndex); @@ -262,7 +264,7 @@ export class NavigatorImpl extends NavigatorBase { routeStack: nextRouteStack, presentedIndex: destIndex, transitionFromIndex: undefined, - transitionQueue: [] + transitionQueue: [], }, () => { this._handleSpringUpdate(); if (destIndex >= 0) { @@ -297,14 +299,14 @@ export class NavigatorImpl extends NavigatorBase { return; } - let nextRouteStack = this.state.routeStack.slice(0, index + 1); - let nextAnimationModeStack = this.state.sceneConfigStack.slice(0, index + 1); + const nextRouteStack = this.state.routeStack.slice(0, index + 1); + const nextAnimationModeStack = this.state.sceneConfigStack.slice(0, index + 1); nextRouteStack[index] = route; nextAnimationModeStack[index] = this._getSceneConfigFromRoute(route); this.setState({ routeStack: nextRouteStack, - sceneConfigStack: nextAnimationModeStack + sceneConfigStack: nextAnimationModeStack, }); } @@ -342,12 +344,20 @@ export class NavigatorImpl extends NavigatorBase { return this.state.routeStack.slice(); } + private _onMountContainer = (comp: RX.View | null) => { + this._containerRef = comp; + }; + private _updateDimensionsCache() { - const transitioner = ReactDOM.findDOMNode(this.refs['transitioner']) as HTMLElement; - this._dimensions = { - width: transitioner.offsetWidth, - height: transitioner.offsetHeight - }; + if (this._containerRef) { + const transitioner = ReactDOM.findDOMNode(this._containerRef) as HTMLElement | null; + if (transitioner) { + this._dimensions = { + width: transitioner.offsetWidth, + height: transitioner.offsetHeight, + }; + } + } } // Helper method to extract Navigator's Scene config from the route @@ -361,8 +371,7 @@ export class NavigatorImpl extends NavigatorBase { // Render a scene for the navigator private _renderNavigatorScene(route: Types.NavigatorRoute, index: number): JSX.Element { - let styles: RX.Types.ViewStyleRuleSet[] = [_styles.baseScene, _styles.sceneStyle, - _styles.defaultSceneStyle]; + const styles: RX.Types.ViewStyleRuleSet[] = [_styles.baseScene, _styles.sceneStyle, _styles.defaultSceneStyle]; if (index !== this.state.presentedIndex) { // update styles @@ -373,7 +382,7 @@ export class NavigatorImpl extends NavigatorBase { return ( this._onMountScene(comp, index) } style={ styles } > { this.props.renderScene(route) } @@ -381,12 +390,24 @@ export class NavigatorImpl extends NavigatorBase { ); } + private _onMountScene(comp: RX.View | null, sceneIndex: number) { + const sceneId = 'scene_' + sceneIndex; + + if (!comp) { + delete this._sceneRefs[sceneId]; + } else { + this._sceneRefs[sceneId] = comp; + } + } + // Push a scene below the others so they don't block touches sent to the presented scenes. private _disableScene(sceneIndex: number) { - if (this.refs['scene_' + sceneIndex]) { - this._setNativeStyles(this.refs['scene_' + sceneIndex], { + const sceneId = 'scene_' + sceneIndex; + + if (this._sceneRefs[sceneId]) { + this._setNativeStyles(this._sceneRefs[sceneId], { opacity: 0, - zIndex: -10 + zIndex: -10, }); } } @@ -394,17 +415,17 @@ export class NavigatorImpl extends NavigatorBase { // Add styles on the scene - At this time, the scene should be mounted and sitting in the // DOM. We are just adding giving styles to this current scene. private _enableScene(sceneIndex: number, force = false) { - let sceneStyle = Styles.combine([_styles.baseScene, _styles.sceneStyle, _styles.defaultSceneStyle]) as any; + const sceneStyle = Styles.combine([_styles.baseScene, _styles.sceneStyle, _styles.defaultSceneStyle]) as any; // Then restore the top value for this scene. const enabledSceneNativeProps = { style: { - top: sceneStyle['top'], - bottom: sceneStyle['bottom'], + top: sceneStyle.top, + bottom: sceneStyle.bottom, opacity: 1, zIndex: 0, - transform: '' - } + transform: '', + }, }; if (!force && sceneIndex !== this.state.transitionFromIndex && @@ -414,8 +435,9 @@ export class NavigatorImpl extends NavigatorBase { (enabledSceneNativeProps.style as any).opacity = 0; } - if (this.refs['scene_' + sceneIndex]) { - this._setNativeStyles(this.refs['scene_' + sceneIndex], enabledSceneNativeProps.style); + const sceneId = 'scene_' + sceneIndex; + if (this._sceneRefs[sceneId]) { + this._setNativeStyles(this._sceneRefs[sceneId], enabledSceneNativeProps.style); } } @@ -427,11 +449,11 @@ export class NavigatorImpl extends NavigatorBase { // If we're already transitioning to another index, queue this one. if (this.state.transitionFromIndex !== undefined) { - let newTransitionQueue = _.cloneDeep(this.state.transitionQueue); + const newTransitionQueue = _.cloneDeep(this.state.transitionQueue); newTransitionQueue.push({ destIndex: destIndex, velocity: velocity, - transitionFinished: cb + transitionFinished: cb, }); // set new transition queue this.setState ({ transitionQueue: newTransitionQueue }); @@ -442,7 +464,7 @@ export class NavigatorImpl extends NavigatorBase { this.setState({ transitionFromIndex: this.state.presentedIndex, presentedIndex: destIndex, - transitionFinished: cb + transitionFinished: cb, }); // Grab the scene config from the route we're leaving. @@ -466,17 +488,17 @@ export class NavigatorImpl extends NavigatorBase { } private _completeTransition() { - let newState: NavigatorState = {}; + const newState: NavigatorState = {}; this.setState({ - transitionFromIndex: undefined + transitionFromIndex: undefined, }); this.spring.setCurrentValue(0).setAtRest(); this._hideScenes(); // Do we have pending transitions? trigger transitions then if (this.state.transitionQueue.length) { - let newTransitionQueue = _.cloneDeep(this.state.transitionQueue); + const newTransitionQueue = _.cloneDeep(this.state.transitionQueue); const queuedTransition = newTransitionQueue.shift(); // add styles on the scene we are about to transition to @@ -486,7 +508,7 @@ export class NavigatorImpl extends NavigatorBase { queuedTransition.destIndex, queuedTransition.velocity, undefined, - queuedTransition.transitionFinished + queuedTransition.transitionFinished, ); if (this.state.transitionFinished) { @@ -528,13 +550,14 @@ export class NavigatorImpl extends NavigatorBase { this._transitionBetween( this.state.transitionFromIndex, this.state.presentedIndex, - this.spring.getCurrentValue() + this.spring.getCurrentValue(), ); } } private _transitionSceneStyle(fromIndex: number, toIndex: number, progress: number, index: number) { - const viewAtIndex = this.refs['scene_' + index]; + const sceneId = 'scene_' + index; + const viewAtIndex = this._sceneRefs[sceneId]; if (viewAtIndex === undefined) { return; } @@ -548,7 +571,7 @@ export class NavigatorImpl extends NavigatorBase { sceneConfig = this.state.sceneConfigStack[sceneConfigIndex - 1]; } - let styleToUse: RX.Types.ViewStyleRuleSet = {}; + const styleToUse: RX.Types.ViewStyleRuleSet = {}; const useFn = index < fromIndex || index < toIndex ? sceneConfig.animationInterpolators.out : sceneConfig.animationInterpolators.into; @@ -597,9 +620,7 @@ export class NavigatorImpl extends NavigatorBase { popIndex, undefined, // default velocity undefined, // no spring jumping - () => { - this._cleanScenesPastIndex(popIndex); - } + () => this._cleanScenesPastIndex(popIndex), ); } @@ -610,7 +631,7 @@ export class NavigatorImpl extends NavigatorBase { if (newStackLength < this.state.routeStack.length) { this.setState({ sceneConfigStack: this.state.sceneConfigStack.slice(0, newStackLength), - routeStack: this.state.routeStack.slice(0, newStackLength) + routeStack: this.state.routeStack.slice(0, newStackLength), }); } } @@ -631,15 +652,17 @@ export class NavigatorImpl extends NavigatorBase { // setNativeProps. private _setNativeStyles(component: React.ReactInstance, currentStyles: any) { // Grab the actual element from the DOM. - let element = ReactDOM.findDOMNode(component) as HTMLElement; - const flatStyles: RX.Types.ViewStyleRuleSet = _.isArray(currentStyles) ? _.flatten(currentStyles) : currentStyles; + const element = ReactDOM.findDOMNode(component) as HTMLElement|null; + if (element) { + const flatStyles: RX.Types.ViewStyleRuleSet = Array.isArray(currentStyles) ? _.flatten(currentStyles) : currentStyles; - // Modify styles - _.assign(element.style, flatStyles); + // Modify styles + _.assign(element.style, flatStyles); + } } } export default NavigatorImpl; export const Navigator = NavigatorImpl; export const NavigatorDelegateSelector: DelegateSelector = undefined; -export import Types = Types; +export { Types }; diff --git a/extensions/navigation/src/web/NavigatorSceneConfigFactory.tsx b/extensions/navigation/src/web/NavigatorSceneConfigFactory.tsx index 8d1686051..8f98b1ee0 100644 --- a/extensions/navigation/src/web/NavigatorSceneConfigFactory.tsx +++ b/extensions/navigation/src/web/NavigatorSceneConfigFactory.tsx @@ -1,30 +1,31 @@ /** -* NavigatorSceneConfigFactory.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* NavigatorSceneConfigFactory creates an 'object' of type NavigatorSceneConfig, -* which is consumed by the Navigator. This object contains properties to execute -* spring animation for transition between scenes. NavigatorSceneConfigFactory and -* NavigatorSceneConfig are both exported. -*/ - -import _ = require('../common/lodashMini'); - -import { Types } from 'reactxp'; -import NavigationTypes = require('../common/Types'); + * NavigatorSceneConfigFactory.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * NavigatorSceneConfigFactory creates an 'object' of type NavigatorSceneConfig, + * which is consumed by the Navigator. This object contains properties to execute + * spring animation for transition between scenes. NavigatorSceneConfigFactory and + * NavigatorSceneConfig are both exported. + */ + +import * as RX from 'reactxp'; + +import * as _ from '../common/lodashMini'; +import * as Types from '../common/Types'; // Interpolator type, which accepts a combination of these types and returns a interpolated/calculated result // Interpolator wrapper, which is given as a callback method to Navigator to call the animation interpolator -export type Interpolator = (progress: number, dimension?: Types.Dimensions) => number; -export type InterpolatorWrapper = (previousStyleSet: Types.ViewStyleRuleSet, dimensions: Types.Dimensions, progress: number) => boolean; +export type Interpolator = (progress: number, dimension?: RX.Types.Dimensions) => number; +export type InterpolatorWrapper = (previousStyleSet: RX.Types.ViewStyleRuleSet, + dimensions: RX.Types.Dimensions, progress: number) => boolean; // Interface to define the transition styles for multiple views export interface TransitionStyle { - translateX?: (progress: number, dimension: Types.Dimensions) => string; - translateY?: (progress: number, dimension: Types.Dimensions) => string; - translateZ?: (progress: number, dimension: Types.Dimensions) => string; + translateX?: (progress: number, dimension: RX.Types.Dimensions) => string; + translateY?: (progress: number, dimension: RX.Types.Dimensions) => string; + translateZ?: (progress: number, dimension: RX.Types.Dimensions) => string; // Note: Weird type: Either a 'function type' or a 'number' opacity?: ((progress: number) => number) | number; rotateX?: ((progress: number) => number) | number; @@ -38,78 +39,77 @@ export interface TransitionStyle { // Defined style interpolators for each transition type class SceneConfigStyles { static fadeToTheLeft: TransitionStyle = { - translateX: (t, dimensions) => { return (t * -dimensions.width * 0.3) + 'px'; }, - opacity: 1 + translateX: (t, dimensions) =>(t * -dimensions.width * 0.3) + 'px', + opacity: 1, }; static fadeToTheRight: TransitionStyle = { - translateX: (t, dimensions) => { return (t * dimensions.width * 0.3) + 'px'; }, - opacity: 1 + translateX: (t, dimensions) => (t * dimensions.width * 0.3) + 'px', + opacity: 1, }; static fadeIn: TransitionStyle = { - opacity: t => { return (t); } + opacity: t => t, }; static fadeOut: TransitionStyle = { - opacity: t => { return (1 - t); } + opacity: t => 1 - t, }; static fadeOutToTop: TransitionStyle = { - opacity: t => { return (1 - t); }, - translateY: (t, dimensions) => { return (t * -0.1 * dimensions.height) + 'px'; } + opacity: t => 1 - t, + translateY: (t, dimensions) => (t * -0.1 * dimensions.height) + 'px', }; static toTheLeft: TransitionStyle = { - translateX: (t, dimensions) => { return (t * -dimensions.width) + 'px'; } + translateX: (t, dimensions) => (t * -dimensions.width) + 'px', }; static toTheUp: TransitionStyle = { - translateY: (t, dimensions) => { return (t * -dimensions.height) + 'px'; } + translateY: (t, dimensions) => (t * -dimensions.height) + 'px', }; static toTheDown: TransitionStyle = { - translateY: (t, dimensions) => { return (t * dimensions.height) + 'px'; } + translateY: (t, dimensions) => (t * dimensions.height) + 'px', }; static fromTheRight: TransitionStyle = { opacity: 1, - translateX: (t, dimensions) => { return (dimensions.width - (t * dimensions.width)) + 'px'; } + translateX: (t, dimensions) => (dimensions.width - (t * dimensions.width)) + 'px', }; static fromTheLeft: TransitionStyle = { opacity: 1, - translateX: (t, dimensions) => { return (-dimensions.width + (t * dimensions.width)) + 'px'; } + translateX: (t, dimensions) => (-dimensions.width + (t * dimensions.width)) + 'px', }; static fromTheDown: TransitionStyle = { - translateY: (t, dimensions) => { return (dimensions.height - t * dimensions.height) + 'px'; } + translateY: (t, dimensions) => (dimensions.height - t * dimensions.height) + 'px', }; static fromTheUp: TransitionStyle = { opacity: 1, - translateY: (t, dimensions) => { return (-dimensions.height + t * dimensions.height) + 'px'; } + translateY: (t, dimensions) => (-dimensions.height + t * dimensions.height) + 'px', }; static fromTheFront: TransitionStyle = { opacity: 1, - translateY: (t, dimensions) => { return (dimensions.height - t * dimensions.height) + 'px'; } + translateY: (t, dimensions) => (dimensions.height - t * dimensions.height) + 'px', }; static toTheBack: TransitionStyle = { - scaleX: t => { return (1 - (t * 0.05)); }, - scaleY: t => { return (1 - (t * 0.05)); }, - opacity: 1 + scaleX: t => (1 - (t * 0.05)), + scaleY: t => (1 - (t * 0.05)), + opacity: 1, }; - /* tslint:enable:no-unused-variable */ // CSS requires all transforms to be combined into one transform property. bundleCompoundStyles searches a style // definition for separate transforms and melts it down to a "transform" property. - public static bundleCompoundStyles(styles: { [name: string]: string | number }): any { - let transforms: { [name: string]: string | number } = { }; - let remaining: { [name: string]: string | number } = { }; + static bundleCompoundStyles(styles: { [name: string]: string | number }): any { + const transforms: { [name: string]: string | number } = { }; + const remaining: { [name: string]: string | number } = { }; - for (let name in styles) { + for (const name in styles) { if (styles.hasOwnProperty(name)) { switch (name) { case 'translateX': @@ -133,7 +133,7 @@ class SceneConfigStyles { // Add transforms into remaining object if (!_.isEmpty(transforms)) { - remaining['transform'] = _.map(transforms, (val, key) => { return key + '(' + val + ')'; }).join(' '); + remaining.transform = _.map(transforms, (val, key) => key + '(' + val + ')').join(' '); } return remaining; @@ -143,37 +143,36 @@ class SceneConfigStyles { // Navigator config class. Navigator works on the instances of this class export class NavigatorSceneConfig { // Rebound spring parameters when transitioning FROM this scene - public springFriction: number = 26; - public springTension: number = 200; + springFriction = 26; + springTension = 200; // Velocity to start at when transitioning without gesture - public defaultTransitionVelocity: number = 1.5; + defaultTransitionVelocity = 1.5; // Returns an object of functions that return a function - public animationInterpolators: { + animationInterpolators: { into: InterpolatorWrapper; out: InterpolatorWrapper; }; - constructor (intoStyle: TransitionStyle, outStyle: TransitionStyle) { + constructor(intoStyle: TransitionStyle, outStyle: TransitionStyle) { // Into, Out interpolators are required to do a scene transition this.animationInterpolators = { into: this._styleInterpolator(intoStyle), - out: this._styleInterpolator(outStyle) + out: this._styleInterpolator(outStyle), }; } // Private method that hangs as a callback on animationInterpolator object // It calculates new styles and updates the previousStyles object sent to decide // if the animation triggered or not in the component that calls it - private _styleInterpolator (styles: TransitionStyle): InterpolatorWrapper { - return (previousStyleSet: Types.ViewStyleRuleSet, dimensions: Types.Dimensions, progress: number): boolean => { + private _styleInterpolator(styles: TransitionStyle): InterpolatorWrapper { + return (previousStyleSet: RX.Types.ViewStyleRuleSet, dimensions: RX.Types.Dimensions, progress: number): boolean => { // Calls the interpolator method for each type and calculates - const interpolatedValues: { [name: string]: number|string } = {}; const newStyleSet = SceneConfigStyles.bundleCompoundStyles( - _.mapValues(styles, (interpolator: Interpolator | number) => { - return _.isNumber(interpolator) ? interpolator : interpolator(progress, dimensions); - }) as any); + _.mapValues(styles, (interpolator: Interpolator | number) => ( + _.isNumber(interpolator) ? interpolator : interpolator(progress, dimensions) + )) as any); // Check if anything has changed since last frame. if (_.isEqual(previousStyleSet, newStyleSet)) { @@ -181,7 +180,7 @@ export class NavigatorSceneConfig { } // Copy the new props into the previous object. - for (let prop in newStyleSet) { + for (const prop in newStyleSet) { if (newStyleSet.hasOwnProperty(prop)) { _.assign(previousStyleSet, {[prop]: _.get(newStyleSet, prop)}); } @@ -196,21 +195,21 @@ export class NavigatorSceneConfig { export class NavigatorSceneConfigFactory { // Helper method that creates a new Animation config for a scene - public static createConfig (configType: NavigationTypes.NavigatorSceneConfigType): NavigatorSceneConfig { + static createConfig(configType: Types.NavigatorSceneConfigType): NavigatorSceneConfig { switch (configType) { - case NavigationTypes.NavigatorSceneConfigType.FloatFromRight: - return new NavigatorSceneConfig(SceneConfigStyles.fromTheRight, SceneConfigStyles.fadeToTheLeft); + case Types.NavigatorSceneConfigType.FloatFromRight: + return new NavigatorSceneConfig(SceneConfigStyles.fromTheRight, SceneConfigStyles.fadeToTheLeft); - case NavigationTypes.NavigatorSceneConfigType.FloatFromLeft: - return new NavigatorSceneConfig(SceneConfigStyles.fromTheLeft, SceneConfigStyles.fadeToTheRight); + case Types.NavigatorSceneConfigType.FloatFromLeft: + return new NavigatorSceneConfig(SceneConfigStyles.fromTheLeft, SceneConfigStyles.fadeToTheRight); - case NavigationTypes.NavigatorSceneConfigType.FloatFromBottom: + case Types.NavigatorSceneConfigType.FloatFromBottom: return new NavigatorSceneConfig(SceneConfigStyles.fromTheFront, SceneConfigStyles.toTheBack); - case NavigationTypes.NavigatorSceneConfigType.Fade: + case Types.NavigatorSceneConfigType.Fade: return new NavigatorSceneConfig(SceneConfigStyles.fadeIn, SceneConfigStyles.fadeOut); - case NavigationTypes.NavigatorSceneConfigType.FadeWithSlide: + case Types.NavigatorSceneConfigType.FadeWithSlide: return new NavigatorSceneConfig(SceneConfigStyles.fadeIn, SceneConfigStyles.fadeOutToTop); default: diff --git a/extensions/navigation/tsconfig.json b/extensions/navigation/tsconfig.json index a3bcf0010..81d3784b0 100644 --- a/extensions/navigation/tsconfig.json +++ b/extensions/navigation/tsconfig.json @@ -1,18 +1,15 @@ { "compilerOptions": { + "experimentalDecorators": true, + "noImplicitAny": true, + "skipLibCheck": true, "declaration": true, "noResolve": false, - "jsx": "react", "module": "commonjs", "target": "es5", - "experimentalDecorators": true, - "noImplicitAny": true, - "outDir": "dist/", - "lib": [ - "es5", - "dom" - ], - "types" : ["lodash", "node", "react", "react-dom"] + "outDir": "dist", + "jsx": "react", + "lib": ["es5", "dom"] }, "include": [ @@ -20,8 +17,7 @@ ], "exclude": [ - "dist", "node_modules", - "website" + "dist" ] } diff --git a/extensions/navigation/tslint.json b/extensions/navigation/tslint.json deleted file mode 100644 index 654334e61..000000000 --- a/extensions/navigation/tslint.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "rules": { - "align": [true, "statements"], - "class-name": true, - "curly": true, - "eofline": true, - "forin": true, - "indent": [true, "spaces"], - "interface-name": [true, "never-prefix"], - "label-position": true, - "max-line-length": [ true, 140 ], - "no-arg": true, - "no-bitwise": false, - "no-consecutive-blank-lines": true, - "no-string-throw": true, - "no-construct": true, - "no-debugger": true, - "no-duplicate-variable": true, - "no-empty": true, - "no-eval": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": false, - "no-unused-expression": true, - "one-line": [true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "quotemark": [true, "single", "jsx-single"], - "radix": true, - "semicolon": [true, "always"], - "triple-equals": [true, "allow-null-check"], - "variable-name": false, - "whitespace": [true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - } -} diff --git a/extensions/netinfo/.eslintrc.json b/extensions/netinfo/.eslintrc.json new file mode 100644 index 000000000..711dab2bf --- /dev/null +++ b/extensions/netinfo/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "parserOptions": { + "project": "./tsconfig.json" + }, + "extends": ["skype"], + "rules": {}, + "overrides": [ + { + "files": [ + "*.tsx" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + { + "files": [ + "PluginBaseChecker.ts" + ], + "rules": { + "@typescript-eslint/no-unused-vars": "off" + } + } + ] +} diff --git a/extensions/netinfo/.gitignore b/extensions/netinfo/.gitignore new file mode 100644 index 000000000..ca4806a3a --- /dev/null +++ b/extensions/netinfo/.gitignore @@ -0,0 +1,20 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependency directories +node_modules +package-lock.json + +# Optional npm cache directory +.npm + +# Build artifacts +**/dist + +# Miscellaneous user files +*.user +.vscode +.DS_STORE + diff --git a/extensions/netinfo/.npmignore b/extensions/netinfo/.npmignore new file mode 100644 index 000000000..85109f294 --- /dev/null +++ b/extensions/netinfo/.npmignore @@ -0,0 +1,5 @@ +/node_modules +/src/.vs +/src/bin +/src/obj +*.user diff --git a/extensions/netinfo/README.md b/extensions/netinfo/README.md new file mode 100644 index 000000000..1c629fa0e --- /dev/null +++ b/extensions/netinfo/README.md @@ -0,0 +1,21 @@ +# reactxp-netinfo +This module provides cross-platform support for detecting network ionformation within the [ReactXP](https://microsoft.github.io/reactxp/) library. This used to be a part of ReactXP core, but was extracted to be a standalone module inline with React Native `Lean Core` initiative. This exists as a standalone module to prevent users of ReactXP from having to link native modules when getting started. + +## Getting Started +This module relies on [@react-native-community/netinfo](https://www.npmjs.com/packages/@react-native-community/netinfo) and will need to be linked into the react-native project. +This can be done by following the linking instructions in the React Native documentation or by running +```react-native link @react-native-community/netinfo``` + +## Documentation +For detailed documentation, look [here](https://microsoft.github.io/reactxp/docs/extensions/netinfo.html). + +### Prerequisites +* [ReactXP](https://github.com/microsoft/reactxp/) + +## Contributing +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +You must sign a Contribution License Agreement (CLA) before your PR will be merged. This a one-time requirement for Microsoft projects in GitHub. You can read more about [Contribution License Agreements (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia. You can sign the Microsoft Contribution License Agreement by visiting https://cla.microsoft.com/. Use your GitHub account to login. + +## License +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details diff --git a/extensions/netinfo/index.android.js b/extensions/netinfo/index.android.js new file mode 100644 index 000000000..3c29e9213 --- /dev/null +++ b/extensions/netinfo/index.android.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./dist/android/PluginBase.js'); diff --git a/extensions/netinfo/index.ios.js b/extensions/netinfo/index.ios.js new file mode 100644 index 000000000..fb6e2f768 --- /dev/null +++ b/extensions/netinfo/index.ios.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./dist/ios/PluginBase.js'); diff --git a/extensions/netinfo/index.js b/extensions/netinfo/index.js new file mode 100644 index 000000000..37981c96b --- /dev/null +++ b/extensions/netinfo/index.js @@ -0,0 +1,4 @@ +'use strict'; + +// Export web by default. Other platforms have custom index.[platform].js files +module.exports = require('./dist/web/PluginBase.js'); diff --git a/extensions/netinfo/index.macos.js b/extensions/netinfo/index.macos.js new file mode 100644 index 000000000..53dc20057 --- /dev/null +++ b/extensions/netinfo/index.macos.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./dist/macos/PluginBase.js'); \ No newline at end of file diff --git a/extensions/netinfo/index.windows.js b/extensions/netinfo/index.windows.js new file mode 100644 index 000000000..b80a5b5c5 --- /dev/null +++ b/extensions/netinfo/index.windows.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./dist/windows/PluginBase.js'); diff --git a/extensions/netinfo/package.json b/extensions/netinfo/package.json new file mode 100644 index 000000000..d36a03964 --- /dev/null +++ b/extensions/netinfo/package.json @@ -0,0 +1,29 @@ +{ + "name": "reactxp-netinfo", + "version": "2.0.0", + "description": "Plugin for ReactXP that provides information about network connectivity", + "author": "ReactXP Team ", + "license": "MIT", + "scripts": { + "build": "tsc", + "lint": "eslint --ext .ts,.tsx src", + "lint:fix": "npm run lint -- --fix" + }, + "dependencies": { + "@react-native-community/netinfo": "^4.6.1" + }, + "peerDependencies": { + "reactxp": "^2.0.0", + "react-native": ">=0.57", + "react-native-windows": "^0.57.1" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "2.15.0", + "eslint": "6.8.0", + "eslint-config-skype": "1.5.0", + "eslint-plugin-import": "2.19.1", + "reactxp": "^2.0.0", + "typescript": "3.7.4" + }, + "types": "dist/web/PluginBase.d.ts" +} diff --git a/extensions/netinfo/src/android/PluginBase.tsx b/extensions/netinfo/src/android/PluginBase.tsx new file mode 100644 index 000000000..cd74d23a3 --- /dev/null +++ b/extensions/netinfo/src/android/PluginBase.tsx @@ -0,0 +1,13 @@ +/* + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Android implementation of the plugin. + */ + +import * as Types from '../common/Types'; +import NetInfo from '../native-common/NetInfo'; + +export { NetInfo as default, Types }; diff --git a/extensions/netinfo/src/common/Interfaces.ts b/extensions/netinfo/src/common/Interfaces.ts new file mode 100644 index 000000000..665e69f99 --- /dev/null +++ b/extensions/netinfo/src/common/Interfaces.ts @@ -0,0 +1,25 @@ +/* + * Interfaces.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Interface definition for cross-platform ReactXP plugin for gathering network/connectivity + * info. This was extracted from the reactxp core + */ + +import SubscribableEvent from 'subscribableevent'; + +import * as Types from './Types'; + +export abstract class NetInfo { + abstract isConnected(): Promise; + abstract getType(): Promise; + connectivityChangedEvent = new SubscribableEvent<(isConnected: boolean) => void>(); +} + +export interface PluginInterface { + Types: typeof Types; + + default: NetInfo; +} diff --git a/extensions/netinfo/src/common/PluginBaseChecker.ts b/extensions/netinfo/src/common/PluginBaseChecker.ts new file mode 100644 index 000000000..35d090f0a --- /dev/null +++ b/extensions/netinfo/src/common/PluginBaseChecker.ts @@ -0,0 +1,22 @@ +/* + * PluginBaseChecker.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type check all the pluginbase exports against the desired interface. + */ + +import * as AndroidPlugin from '../android/PluginBase'; +import * as iOSPlugin from '../ios/PluginBase'; +import * as macOSPlugin from '../macos/PluginBase'; +import * as WebPlugin from '../web/PluginBase'; +import * as WindowsPlugin from '../windows/PluginBase'; + +import * as Interfaces from './Interfaces'; + +const _typeCheckerAndroid: Interfaces.PluginInterface = AndroidPlugin; +const _typeCheckeriOS: Interfaces.PluginInterface = iOSPlugin; +const _typeCheckermacOS: Interfaces.PluginInterface = macOSPlugin; +const _typeCheckerWeb: Interfaces.PluginInterface = WebPlugin; +const _typeCheckerWindows: Interfaces.PluginInterface = WindowsPlugin; diff --git a/extensions/netinfo/src/common/Types.ts b/extensions/netinfo/src/common/Types.ts new file mode 100644 index 000000000..5aac2037d --- /dev/null +++ b/extensions/netinfo/src/common/Types.ts @@ -0,0 +1,17 @@ +/* + * Types.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type definitions to support the plugin. + */ + +export enum DeviceNetworkType { + Unknown, + None, + Wifi, + Mobile2G, + Mobile3G, + Mobile4G +} diff --git a/extensions/netinfo/src/ios/PluginBase.tsx b/extensions/netinfo/src/ios/PluginBase.tsx new file mode 100644 index 000000000..0d3e7dfbc --- /dev/null +++ b/extensions/netinfo/src/ios/PluginBase.tsx @@ -0,0 +1,13 @@ +/* + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the iOS implementation of the plugin. + */ + +import * as Types from '../common/Types'; +import NetInfo from '../native-common/NetInfo'; + +export { NetInfo as default, Types }; diff --git a/extensions/netinfo/src/macos/PluginBase.tsx b/extensions/netinfo/src/macos/PluginBase.tsx new file mode 100644 index 000000000..e02af00bc --- /dev/null +++ b/extensions/netinfo/src/macos/PluginBase.tsx @@ -0,0 +1,13 @@ +/* + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Mac implementation of the plugin. + */ + +import * as Types from '../common/Types'; +import NetInfo from '../native-common/NetInfo'; + +export { NetInfo as default, Types }; diff --git a/extensions/netinfo/src/native-common/NetInfo.tsx b/extensions/netinfo/src/native-common/NetInfo.tsx new file mode 100644 index 000000000..a3e8efcf0 --- /dev/null +++ b/extensions/netinfo/src/native-common/NetInfo.tsx @@ -0,0 +1,61 @@ +/** + * NetInfo.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Native implementation of network information APIs. + */ + +import * as RNNetInfo from '@react-native-community/netinfo'; + +import * as Types from '../common/Types'; +import * as Interfaces from '../common/Interfaces'; + +export class NetInfo extends Interfaces.NetInfo { + constructor() { + super(); + + const onEventOccurredHandler = (state: RNNetInfo.NetInfoState) => { + this.connectivityChangedEvent.fire(state.isConnected); + }; + + RNNetInfo.addEventListener(onEventOccurredHandler); + } + + isConnected(): Promise { + return RNNetInfo.fetch() + .then((state: RNNetInfo.NetInfoState) => state.isConnected) + .catch(() => Promise.reject('NetInfo.isConnected.fetch() failed')); + } + + getType(): Promise { + return RNNetInfo.fetch().then((state: RNNetInfo.NetInfoState) => NetInfo._getNetworkTypeFromConnectionInfo(state)); + } + + private static _getNetworkTypeFromConnectionInfo(state: RNNetInfo.NetInfoState): Types.DeviceNetworkType { + if (state.type === RNNetInfo.NetInfoStateType.cellular) { + if (state.details === null || state.details.cellularGeneration === null) { + return Types.DeviceNetworkType.Unknown; + } else if (state.details.cellularGeneration === '2g') { + return Types.DeviceNetworkType.Mobile2G; + } else if (state.details.cellularGeneration === '3g') { + return Types.DeviceNetworkType.Mobile3G; + } else if (state.details.cellularGeneration === '4g') { + return Types.DeviceNetworkType.Mobile4G; + } + } else if (state.type === RNNetInfo.NetInfoStateType.wifi ) { + return Types.DeviceNetworkType.Wifi; + } else if (state.type === RNNetInfo.NetInfoStateType.ethernet ) { + return Types.DeviceNetworkType.Wifi; + } else if (state.type === RNNetInfo.NetInfoStateType.wimax ) { + return Types.DeviceNetworkType.Wifi; + } else if (state.type === RNNetInfo.NetInfoStateType.none) { + return Types.DeviceNetworkType.None; + } + + return Types.DeviceNetworkType.Unknown; + } +} + +export default new NetInfo(); diff --git a/extensions/netinfo/src/web/NetInfo.tsx b/extensions/netinfo/src/web/NetInfo.tsx new file mode 100644 index 000000000..3751f1edf --- /dev/null +++ b/extensions/netinfo/src/web/NetInfo.tsx @@ -0,0 +1,37 @@ +/** + * Video.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Web-specific implementation of the cross-platform Video abstraction. + */ + +import * as Types from '../common/Types'; +import * as Interfaces from '../common/Interfaces'; + +export class NetInfo extends Interfaces.NetInfo { + constructor() { + super(); + + const onEventOccuredHandler = () => { + this.connectivityChangedEvent.fire(navigator.onLine); + }; + + // Avoid accessing window if it's not defined (for test environment). + if (typeof(window) !== 'undefined') { + window.addEventListener('online', onEventOccuredHandler); + window.addEventListener('offline', onEventOccuredHandler); + } + } + + isConnected(): Promise { + return Promise.resolve(navigator.onLine); + } + + getType(): Promise { + return Promise.resolve(Types.DeviceNetworkType.Unknown); + } +} + +export default new NetInfo(); diff --git a/extensions/netinfo/src/web/PluginBase.ts b/extensions/netinfo/src/web/PluginBase.ts new file mode 100644 index 000000000..fd1412136 --- /dev/null +++ b/extensions/netinfo/src/web/PluginBase.ts @@ -0,0 +1,14 @@ +/* + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Web implementation of the plugin. + */ + +import * as Types from '../common/Types'; + +import NetInfo from './NetInfo'; + +export { NetInfo as default, Types }; diff --git a/extensions/netinfo/src/windows/PluginBase.ts b/extensions/netinfo/src/windows/PluginBase.ts new file mode 100644 index 000000000..89b138575 --- /dev/null +++ b/extensions/netinfo/src/windows/PluginBase.ts @@ -0,0 +1,13 @@ +/* + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Windows implementation of the plugin. + */ + +import * as Types from '../common/Types'; +import NetInfo from '../native-common/NetInfo'; + +export { NetInfo as default, Types }; diff --git a/extensions/netinfo/tsconfig.json b/extensions/netinfo/tsconfig.json new file mode 100644 index 000000000..13411a6b8 --- /dev/null +++ b/extensions/netinfo/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "strictPropertyInitialization": true, + "experimentalDecorators": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "noImplicitThis": true, + "noImplicitAny": true, + "skipLibCheck": true, + "declaration": true, + "noResolve": false, + "target": "es5", + "module": "commonjs", + "outDir": "dist", + "jsx": "react", + "lib": ["es2015.promise", "es5", "DOM"] + }, + + "include": [ + "src/**/*" + ], + + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/extensions/video/.eslintrc.json b/extensions/video/.eslintrc.json new file mode 100644 index 000000000..3ff892a96 --- /dev/null +++ b/extensions/video/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "parserOptions": { + "project": "./tsconfig.json" + }, + "extends": ["skype", "skype/react"], + "rules": {}, + "overrides": [ + { + "files": [ + "*.tsx" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + }, + { + "files": [ + "PluginBaseChecker.ts" + ], + "rules": { + "@typescript-eslint/no-unused-vars": "off" + } + } + ] +} diff --git a/extensions/video/package.json b/extensions/video/package.json index c6af060db..35eed01be 100644 --- a/extensions/video/package.json +++ b/extensions/video/package.json @@ -1,28 +1,37 @@ { "name": "reactxp-video", - "version": "1.2.0", + "version": "2.0.0", "description": "Plugin for ReactXP that provides a video player component for all platforms", "author": "ReactXP Team ", "license": "MIT", "scripts": { - "build": "npm run tslint && tsc", - "tslint": "tslint -p tsconfig.json -r tslint.json -r ./node_modules/tslint-microsoft-contrib --fix || true" + "build": "tsc", + "lint": "eslint --ext .ts,.tsx src", + "lint:fix": "npm run lint -- --fix" }, "dependencies": { - "@types/lodash": "^4.14.80", - "lodash": "^4.17.4", - "react-native-video": "^2.0.0", - "reactxp": "^1.2.0" + "lodash": "^4.17.15", + "react-native-video": "^5.0.2" }, "peerDependencies": { - "react-dom": "16.2.0", - "react-native": "^0.51.0", - "react-native-windows": "^0.51.0" + "react": "^16.3.0", + "reactxp": "^2.0.0", + "react-dom": "^16.3.0", + "react-native": ">=0.57", + "react-native-windows": "^0.57.1" }, "devDependencies": { - "typescript": "2.8.3", - "tslint": "5.10.0", - "tslint-microsoft-contrib": "5.0.3" + "@types/lodash": "^4.14.149", + "@types/react-dom": "^16.9.4", + "@types/react-native": "^0.60.23", + "@typescript-eslint/eslint-plugin": "2.15.0", + "eslint": "6.8.0", + "eslint-config-skype": "1.5.0", + "eslint-plugin-import": "2.19.1", + "eslint-plugin-react": "7.17.0", + "react": "^16.3.0", + "reactxp": "^2.0.0", + "typescript": "3.7.4" }, "types": "dist/web/PluginBase.d.ts" } diff --git a/extensions/video/src/android/PluginBase.tsx b/extensions/video/src/android/PluginBase.tsx index e36ad4cb3..eae576b75 100644 --- a/extensions/video/src/android/PluginBase.tsx +++ b/extensions/video/src/android/PluginBase.tsx @@ -1,13 +1,13 @@ /* -* PluginBase.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the Android implementation of the plugin. -*/ + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the Android implementation of the plugin. + */ +import * as Types from '../common/Types'; import Video from '../native-common/Video'; -import Types = require('../common/Types'); export { Video as default, Types }; diff --git a/extensions/video/src/common/Interfaces.ts b/extensions/video/src/common/Interfaces.ts index c9f2603ee..42583f93a 100644 --- a/extensions/video/src/common/Interfaces.ts +++ b/extensions/video/src/common/Interfaces.ts @@ -1,18 +1,18 @@ /* -* Interfaces.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Interface definition for cross-platform ReactXP plugin for -* display videos and controlling video playback. -*/ + * Interfaces.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Interface definition for cross-platform ReactXP plugin for + * display videos and controlling video playback. + */ -import RX = require('reactxp'); +import * as RX from 'reactxp'; -import Types = require('./Types'); +import * as Types from './Types'; -export abstract class Video extends RX.Component { +export abstract class Video extends RX.Component { abstract seek(position: number): void; abstract play(): void; abstract pause(): void; diff --git a/extensions/video/src/common/PluginBaseChecker.ts b/extensions/video/src/common/PluginBaseChecker.ts index 55df195e8..35d090f0a 100644 --- a/extensions/video/src/common/PluginBaseChecker.ts +++ b/extensions/video/src/common/PluginBaseChecker.ts @@ -1,24 +1,22 @@ /* -* PluginBaseChecker.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type check all the pluginbase exports against the desired interface. -*/ + * PluginBaseChecker.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type check all the pluginbase exports against the desired interface. + */ -import Interfaces = require('./Interfaces'); +import * as AndroidPlugin from '../android/PluginBase'; +import * as iOSPlugin from '../ios/PluginBase'; +import * as macOSPlugin from '../macos/PluginBase'; +import * as WebPlugin from '../web/PluginBase'; +import * as WindowsPlugin from '../windows/PluginBase'; -import AndroidPlugin = require('../android/PluginBase'); -import iOSPlugin = require('../ios/PluginBase'); -import macOSPlugin = require('../macos/PluginBase'); -import WebPlugin = require('../web/PluginBase'); -import WindowsPlugin = require('../windows/PluginBase'); +import * as Interfaces from './Interfaces'; -/* tslint:disable:no-unused-variable */ const _typeCheckerAndroid: Interfaces.PluginInterface = AndroidPlugin; const _typeCheckeriOS: Interfaces.PluginInterface = iOSPlugin; const _typeCheckermacOS: Interfaces.PluginInterface = macOSPlugin; const _typeCheckerWeb: Interfaces.PluginInterface = WebPlugin; const _typeCheckerWindows: Interfaces.PluginInterface = WindowsPlugin; -/* tslint:enable:no-unused-variable */ diff --git a/extensions/video/src/common/Types.ts b/extensions/video/src/common/Types.ts index df750e28c..8a877b219 100644 --- a/extensions/video/src/common/Types.ts +++ b/extensions/video/src/common/Types.ts @@ -1,12 +1,13 @@ /* -* Types.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definitions to support the plugin. -*/ + * Types.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type definitions to support the plugin. + */ +import * as React from 'react'; import { Types as RXTypes } from 'reactxp'; // Video interfaces from react-native-video @@ -26,8 +27,8 @@ export interface VideoInfo { }; } -export interface VideoProps extends RXTypes.CommonStyledProps { - source: string; +export interface VideoProps extends RXTypes.CommonStyledProps { + source: string | number; accessibilityLabel?: string; showControls?: boolean; preload?: 'auto'|'metadata'|'none'; @@ -45,3 +46,5 @@ export interface VideoProps extends RXTypes.CommonStyledProps void; onProgress?: (progress: VideoProgress) => void; } + +export abstract class Video extends React.Component {} diff --git a/extensions/video/src/ios/PluginBase.tsx b/extensions/video/src/ios/PluginBase.tsx index 0c8008027..2630b7b58 100644 --- a/extensions/video/src/ios/PluginBase.tsx +++ b/extensions/video/src/ios/PluginBase.tsx @@ -1,13 +1,13 @@ -/* -* PluginBase.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the iOS implementation of the plugin. -*/ +/** + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the iOS implementation of the plugin. + */ +import * as Types from '../common/Types'; import Video from '../native-common/Video'; -import Types = require('../common/Types'); export { Video as default, Types }; diff --git a/extensions/video/src/macos/PluginBase.tsx b/extensions/video/src/macos/PluginBase.tsx index 170dd4d4a..a0467893e 100644 --- a/extensions/video/src/macos/PluginBase.tsx +++ b/extensions/video/src/macos/PluginBase.tsx @@ -1,13 +1,13 @@ -/* -* PluginBase.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Base export for the MacOS implementation of the plugin. -*/ +/** + * PluginBase.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Base export for the MacOS implementation of the plugin. + */ +import * as Types from '../common/Types'; import Video from '../native-common/Video'; -import Types = require('../common/Types'); export { Video as default, Types }; diff --git a/extensions/video/src/native-common/Video.tsx b/extensions/video/src/native-common/Video.tsx index 0a5a38d7b..5a770d990 100644 --- a/extensions/video/src/native-common/Video.tsx +++ b/extensions/video/src/native-common/Video.tsx @@ -1,18 +1,17 @@ -/* -* Video.tsx -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* RN-specific implementation of the cross-platform Video abstraction. -*/ - -import React = require('react'); +/** + * Video.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * RN-specific implementation of the cross-platform Video abstraction. + */ + +import * as React from 'react'; +import * as RX from 'reactxp'; import { default as RNVideo, VideoInfo, VideoBufferInfo } from 'react-native-video'; -import RX = require('reactxp'); -import Interfaces = require('../common/Interfaces'); -import Types = require('../common/Types'); +import * as Types from '../common/Types'; export interface VideoState { isPlaying?: boolean; @@ -28,11 +27,14 @@ class Video extends RX.Component { this.state = { isPlaying: false, - isMuted: false + isMuted: false, }; } render() { + const source = typeof this.props.source === 'number' + ? this.props.source + : { uri: this.props.source }; return ( { paused={ !this.state.isPlaying } muted={ this.state.isMuted } repeat={ this.props.loop } - source={ { uri: this.props.source } } + source={ source } style={ this.props.style } + useTextureView={ false } onEnd={ this._onEnd } onBuffer={ this._onBuffer } - onLoadStart={ this.props.onLoadStart} + onLoadStart={ this.props.onLoadStart } onProgress={ this.props.onProgress } onReadyForDisplay={ this._onLoad } onLoad={ this._onLoadData } @@ -56,7 +59,7 @@ class Video extends RX.Component { private _onMount = (component: any) => { this._mountedComponent = component as RNVideo; - } + }; private _onError = () => { if (!this._mountedComponent) { @@ -66,7 +69,7 @@ class Video extends RX.Component { if (this.props.onError) { this.props.onError(); } - } + }; private _onLoad = () => { if (!this._mountedComponent) { @@ -78,7 +81,7 @@ class Video extends RX.Component { if (!this.props.showControls && this.props.onCanPlay) { this.props.onCanPlay(); } - } + }; private _onLoadData = (loadInfo: VideoInfo) => { if (!this._mountedComponent) { @@ -96,7 +99,7 @@ class Video extends RX.Component { } this.setState({ duration: loadInfo.duration }); - } + }; private _onBuffer = (bufferInfo: VideoBufferInfo) => { if (!this._mountedComponent) { @@ -112,7 +115,7 @@ class Video extends RX.Component { this.props.onCanPlayThrough(); } } - } + }; private _onEnd = () => { if (!this._mountedComponent) { @@ -130,7 +133,7 @@ class Video extends RX.Component { if (this.props.onEnded) { this.props.onEnded(); } - } + }; seek(position: number) { if (this._mountedComponent) { @@ -140,7 +143,9 @@ class Video extends RX.Component { seekPercent(percentage: number) { if (this._mountedComponent) { - this._mountedComponent.seek(this.state.duration * percentage); + if (this.state.duration) { + this._mountedComponent.seek(this.state.duration * percentage); + } } } diff --git a/extensions/video/src/typings/node.d.ts b/extensions/video/src/typings/node.d.ts deleted file mode 100644 index b7edca1f7..000000000 --- a/extensions/video/src/typings/node.d.ts +++ /dev/null @@ -1,2079 +0,0 @@ -// Type definitions for Node.js v0.12.0 -// Project: http://nodejs.org/ -// Definitions by: Microsoft TypeScript , DefinitelyTyped -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/************************************************ -* * -* Node.js v0.12.0 API * -* * -************************************************/ - -// compat for TypeScript 1.5.3 -// if you use with --target es3 or --target es5 and use below definitions, -// use the lib.es6.d.ts that is bundled with TypeScript 1.5.3. -interface MapConstructor {} -interface WeakMapConstructor {} -interface SetConstructor {} -interface WeakSetConstructor {} - -/************************************************ -* * -* GLOBAL * -* * -************************************************/ -declare var process: NodeJS.Process; -declare var global: NodeJS.Global; - -declare var __filename: string; -declare var __dirname: string; - -declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearTimeout(timeoutId: NodeJS.Timer): void; -declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearInterval(intervalId: NodeJS.Timer): void; -declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; -declare function clearImmediate(immediateId: any): void; - -interface NodeRequireFunction { - (id: string): any; -} - -interface NodeRequire extends NodeRequireFunction { - resolve(id:string): string; - cache: any; - extensions: any; - main: any; -} - -declare var require: NodeRequire; - -interface NodeModule { - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: any; - children: any[]; -} - -declare var module: NodeModule; - -// Same as module.exports -declare var exports: any; -declare var SlowBuffer: { - new (str: string, encoding?: string): Buffer; - new (size: number): Buffer; - new (size: Uint8Array): Buffer; - new (array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; -}; - - -// Buffer class -interface Buffer extends NodeBuffer {} - -/** - * Raw data is stored in instances of the Buffer class. - * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. - * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - */ -declare var Buffer: { - /** - * Allocates a new buffer containing the given {str}. - * - * @param str String to store in buffer. - * @param encoding encoding to use, optional. Default is 'utf8' - */ - new (str: string, encoding?: string): Buffer; - /** - * Allocates a new buffer of {size} octets. - * - * @param size count of octets to allocate. - */ - new (size: number): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: Uint8Array): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: any[]): Buffer; - prototype: Buffer; - /** - * Returns true if {obj} is a Buffer - * - * @param obj object to test. - */ - isBuffer(obj: any): boolean; - /** - * Returns true if {encoding} is a valid encoding argument. - * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - * - * @param encoding string to test. - */ - isEncoding(encoding: string): boolean; - /** - * Gives the actual byte length of a string. encoding defaults to 'utf8'. - * This is not the same as String.prototype.length since that returns the number of characters in a string. - * - * @param string string to test. - * @param encoding encoding used to evaluate (defaults to 'utf8') - */ - byteLength(string: string, encoding?: string): number; - /** - * Returns a buffer which is the result of concatenating all the buffers in the list together. - * - * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. - * If the list has exactly one item, then the first item of the list is returned. - * If the list has more than one item, then a new Buffer is created. - * - * @param list An array of Buffer objects to concatenate - * @param totalLength Total length of the buffers when concatenated. - * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. - */ - concat(list: Buffer[], totalLength?: number): Buffer; - /** - * The same as buf1.compare(buf2). - */ - compare(buf1: Buffer, buf2: Buffer): number; -}; - -/************************************************ -* * -* GLOBAL INTERFACES * -* * -************************************************/ -declare module NodeJS { - export interface ErrnoException extends Error { - errno?: number; - code?: string; - path?: string; - syscall?: string; - stack?: string; - } - - export interface EventEmitter { - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - } - - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): string|Buffer; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): ReadableStream; - } - - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface ReadWriteStream extends ReadableStream, WritableStream {} - - export interface Process extends EventEmitter { - stdout: WritableStream; - stderr: WritableStream; - stdin: ReadableStream; - argv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - env: any; - exit(code?: number): void; - getgid(): number; - setgid(id: number): void; - setgid(id: string): void; - getuid(): number; - setuid(id: number): void; - setuid(id: string): void; - version: string; - versions: { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - openssl: string; - }; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid: number, signal?: string): void; - pid: number; - title: string; - arch: string; - platform: string; - memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; - nextTick(callback: Function): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?:number[]): number[]; - - // Worker - send?(message: any, sendHandle?: any): void; - } - - export interface Global { - Array: typeof Array; - ArrayBuffer: typeof ArrayBuffer; - Boolean: typeof Boolean; - Buffer: typeof Buffer; - DataView: typeof DataView; - Date: typeof Date; - Error: typeof Error; - EvalError: typeof EvalError; - Float32Array: typeof Float32Array; - Float64Array: typeof Float64Array; - Function: typeof Function; - GLOBAL: Global; - Infinity: typeof Infinity; - Int16Array: typeof Int16Array; - Int32Array: typeof Int32Array; - Int8Array: typeof Int8Array; - Intl: typeof Intl; - JSON: typeof JSON; - Map: MapConstructor; - Math: typeof Math; - NaN: typeof NaN; - Number: typeof Number; - Object: typeof Object; - Promise: Function; - RangeError: typeof RangeError; - ReferenceError: typeof ReferenceError; - RegExp: typeof RegExp; - Set: SetConstructor; - String: typeof String; - Symbol: Function; - SyntaxError: typeof SyntaxError; - TypeError: typeof TypeError; - URIError: typeof URIError; - Uint16Array: typeof Uint16Array; - Uint32Array: typeof Uint32Array; - Uint8Array: typeof Uint8Array; - Uint8ClampedArray: Function; - WeakMap: WeakMapConstructor; - WeakSet: WeakSetConstructor; - clearImmediate: (immediateId: any) => void; - clearInterval: (intervalId: NodeJS.Timer) => void; - clearTimeout: (timeoutId: NodeJS.Timer) => void; - console: typeof console; - decodeURI: typeof decodeURI; - decodeURIComponent: typeof decodeURIComponent; - encodeURI: typeof encodeURI; - encodeURIComponent: typeof encodeURIComponent; - escape: (str: string) => string; - eval: typeof eval; - global: Global; - isFinite: typeof isFinite; - isNaN: typeof isNaN; - parseFloat: typeof parseFloat; - parseInt: typeof parseInt; - process: Process; - root: Global; - setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; - setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - undefined: typeof undefined; - unescape: (str: string) => string; - gc: () => void; - } - - export interface Timer { - ref() : void; - unref() : void; - } -} - -/** - * @deprecated - */ -interface NodeBuffer { - [index: number]: number; - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): any; - length: number; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAsset?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - writeUInt8(value: number, offset: number, noAssert?: boolean): void; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeInt8(value: number, offset: number, noAssert?: boolean): void; - writeInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeFloatLE(value: number, offset: number, noAssert?: boolean): void; - writeFloatBE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; - fill(value: any, offset?: number, end?: number): void; -} - -/************************************************ -* * -* MODULES * -* * -************************************************/ -declare module "buffer" { - export var INSPECT_MAX_BYTES: number; -} - -declare module "querystring" { - export function stringify(obj: any, sep?: string, eq?: string): string; - export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; - export function escape(str: string): string; - export function unescape(str: string): string; -} - -declare module "events" { - export class EventEmitter implements NodeJS.EventEmitter { - static listenerCount(emitter: EventEmitter, event: string): number; - - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - } -} - -declare module "http" { - import * as events from "events"; - import * as net from "net"; - import * as stream from "stream"; - - export interface Server extends events.EventEmitter { - listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; - listen(port: number, hostname?: string, callback?: Function): Server; - listen(path: string, callback?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(cb?: any): Server; - address(): { port: number; family: string; address: string; }; - maxHeadersCount: number; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ServerRequest extends IncomingMessage { - connection: net.Socket; - } - export interface ServerResponse extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - writeContinue(): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; - writeHead(statusCode: number, headers?: any): void; - statusCode: number; - statusMessage: string; - setHeader(name: string, value: string): void; - sendDate: boolean; - getHeader(name: string): string; - removeHeader(name: string): void; - write(chunk: any, encoding?: string): any; - addTrailers(headers: any): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientRequest extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - write(chunk: any, encoding?: string): void; - abort(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface IncomingMessage extends events.EventEmitter, stream.Readable { - httpVersion: string; - headers: any; - rawHeaders: string[]; - trailers: any; - rawTrailers: any; - setTimeout(msecs: number, callback: Function): NodeJS.Timer; - /** - * Only valid for request obtained from http.Server. - */ - method?: string; - /** - * Only valid for request obtained from http.Server. - */ - url?: string; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusCode?: number; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusMessage?: string; - socket: net.Socket; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ClientResponse extends IncomingMessage { } - - export interface AgentOptions { - /** - * Keep sockets around in a pool to be used by other requests in the future. Default = false - */ - keepAlive?: boolean; - /** - * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. - * Only relevant if keepAlive is set to true. - */ - keepAliveMsecs?: number; - /** - * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity - */ - maxSockets?: number; - /** - * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. - */ - maxFreeSockets?: number; - } - - export class Agent { - maxSockets: number; - sockets: any; - requests: any; - - constructor(opts?: AgentOptions); - - /** - * Destroy any sockets that are currently in use by the agent. - * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, - * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, - * sockets may hang open for quite a long time before the server terminates them. - */ - destroy(): void; - } - - export var METHODS: string[]; - - export var STATUS_CODES: { - [errorCode: number]: string; - [errorCode: string]: string; - }; - export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; - export function createClient(port?: number, host?: string): any; - export function request(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; - export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; - export var globalAgent: Agent; -} - -declare module "cluster" { - import * as child from "child_process"; - import * as events from "events"; - - export interface ClusterSettings { - exec?: string; - args?: string[]; - silent?: boolean; - } - - export class Worker extends events.EventEmitter { - id: string; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any): void; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - } - - export var settings: ClusterSettings; - export var isMaster: boolean; - export var isWorker: boolean; - export function setupMaster(settings?: ClusterSettings): void; - export function fork(env?: any): Worker; - export function disconnect(callback?: Function): void; - export var worker: Worker; - export var workers: Worker[]; - - // Event emitter - export function addListener(event: string, listener: Function): void; - export function on(event: string, listener: Function): any; - export function once(event: string, listener: Function): void; - export function removeListener(event: string, listener: Function): void; - export function removeAllListeners(event?: string): void; - export function setMaxListeners(n: number): void; - export function listeners(event: string): Function[]; - export function emit(event: string, ...args: any[]): boolean; -} - -declare module "zlib" { - import * as stream from "stream"; - export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } - - export interface Gzip extends stream.Transform { } - export interface Gunzip extends stream.Transform { } - export interface Deflate extends stream.Transform { } - export interface Inflate extends stream.Transform { } - export interface DeflateRaw extends stream.Transform { } - export interface InflateRaw extends stream.Transform { } - export interface Unzip extends stream.Transform { } - - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; - - export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function deflateSync(buf: Buffer, options?: ZlibOptions): any; - export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gzipSync(buf: Buffer, options?: ZlibOptions): any; - export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; - export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflateSync(buf: Buffer, options?: ZlibOptions): any; - export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function unzipSync(buf: Buffer, options?: ZlibOptions): any; - - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; - export var Z_NULL: number; -} - -declare module "os" { - export function tmpdir(): string; - export function hostname(): string; - export function type(): string; - export function platform(): string; - export function arch(): string; - export function release(): string; - export function uptime(): number; - export function loadavg(): number[]; - export function totalmem(): number; - export function freemem(): number; - export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; - export function networkInterfaces(): any; - export var EOL: string; -} - -declare module "https" { - import * as tls from "tls"; - import * as events from "events"; - import * as http from "http"; - - export interface ServerOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - crl?: any; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; - SNICallback?: (servername: string) => any; - } - - export interface RequestOptions { - host?: string; - hostname?: string; - port?: number; - path?: string; - method?: string; - headers?: any; - auth?: string; - agent?: any; - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - } - - export interface Agent { - maxSockets: number; - sockets: any; - requests: any; - } - export var Agent: { - new (options?: RequestOptions): Agent; - }; - export interface Server extends tls.Server { } - export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; - export var globalAgent: Agent; -} - -declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): string; - encode(codePoints: number[]): string; - } - export var version: any; -} - -declare module "repl" { - import * as stream from "stream"; - import * as events from "events"; - - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - } - export function start(options: ReplOptions): events.EventEmitter; -} - -declare module "readline" { - import * as events from "events"; - import * as stream from "stream"; - - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: Function): void; - pause(): void; - resume(): void; - close(): void; - write(data: any, key?: any): void; - } - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output: NodeJS.WritableStream; - completer?: Function; - terminal?: boolean; - } - export function createInterface(options: ReadLineOptions): ReadLine; -} - -declare module "vm" { - export interface Context { } - export interface Script { - runInThisContext(): void; - runInNewContext(sandbox?: Context): void; - } - export function runInThisContext(code: string, filename?: string): void; - export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; - export function runInContext(code: string, context: Context, filename?: string): void; - export function createContext(initSandbox?: Context): Context; - export function createScript(code: string, filename?: string): Script; -} - -declare module "child_process" { - import * as events from "events"; - import * as stream from "stream"; - - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - pid: number; - kill(signal?: string): void; - send(message: any, sendHandle?: any): void; - disconnect(): void; - unref(): void; - } - - export function spawn(command: string, args?: string[], options?: { - cwd?: string; - stdio?: any; - custom?: any; - env?: any; - detached?: boolean; - }): ChildProcess; - export function exec(command: string, options: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, - callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, args?: string[], - callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, args?: string[], options?: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: string; - killSignal?: string; - }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function fork(modulePath: string, args?: string[], options?: { - cwd?: string; - env?: any; - encoding?: string; - }): ChildProcess; - export function execSync(command: string, options?: { - cwd?: string; - input?: string|Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - encoding?: string; - }): ChildProcess; - export function execFileSync(command: string, args?: string[], options?: { - cwd?: string; - input?: string|Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - encoding?: string; - }): ChildProcess; -} - -declare module "url" { - export interface Url { - href: string; - protocol: string; - auth: string; - hostname: string; - port: string; - host: string; - pathname: string; - search: string; - query: any; // string | Object - slashes: boolean; - hash?: string; - path?: string; - } - - export interface UrlOptions { - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: any; - hash?: string; - path?: string; - } - - export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; - export function format(url: UrlOptions): string; - export function resolve(from: string, to: string): string; -} - -declare module "dns" { - export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; - export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; - export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; -} - -declare module "net" { - import * as stream from "stream"; - - export interface Socket extends stream.Duplex { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - connect(port: number, host?: string, connectionListener?: Function): void; - connect(path: string, connectionListener?: Function): void; - bufferSize: number; - setEncoding(encoding?: string): void; - write(data: any, encoding?: string, callback?: Function): void; - destroy(): void; - pause(): void; - resume(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setKeepAlive(enable?: boolean, initialDelay?: number): void; - address(): { port: number; family: string; address: string; }; - unref(): void; - ref(): void; - - remoteAddress: string; - remoteFamily: string; - remotePort: number; - localAddress: string; - localPort: number; - bytesRead: number; - bytesWritten: number; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - - export var Socket: { - new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; - }; - - export interface Server extends Socket { - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - maxConnections: number; - connections: number; - } - export function createServer(connectionListener?: (socket: Socket) =>void ): Server; - export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; - export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; -} - -declare module "dgram" { - import * as events from "events"; - - interface RemoteInfo { - address: string; - port: number; - size: number; - } - - interface AddressInfo { - address: string; - family: string; - port: number; - } - - export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - - interface Socket extends events.EventEmitter { - send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; - bind(port: number, address?: string, callback?: () => void): void; - close(): void; - address(): AddressInfo; - setBroadcast(flag: boolean): void; - setMulticastTTL(ttl: number): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - } -} - -declare module "fs" { - import * as stream from "stream"; - import * as events from "events"; - - interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atime: Date; - mtime: Date; - ctime: Date; - } - - interface FSWatcher extends events.EventEmitter { - close(): void; - } - - export interface ReadStream extends stream.Readable { - close(): void; - } - export interface WriteStream extends stream.Writable { - close(): void; - bytesWritten: number; - } - - /** - * Asynchronous rename. - * @param oldPath - * @param newPath - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /** - * Synchronous rename - * @param oldPath - * @param newPath - */ - export function renameSync(oldPath: string, newPath: string): void; - export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncateSync(path: string, len?: number): void; - export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncateSync(fd: number, len?: number): void; - export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chownSync(path: string, uid: number, gid: number): void; - export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchownSync(fd: number, uid: number, gid: number): void; - export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchownSync(path: string, uid: number, gid: number): void; - export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmodSync(path: string, mode: number): void; - export function chmodSync(path: string, mode: string): void; - export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmodSync(fd: number, mode: number): void; - export function fchmodSync(fd: number, mode: string): void; - export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmodSync(path: string, mode: number): void; - export function lchmodSync(path: string, mode: string): void; - export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function statSync(path: string): Stats; - export function lstatSync(path: string): Stats; - export function fstatSync(fd: number): Stats; - export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function linkSync(srcpath: string, dstpath: string): void; - export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; - export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; - export function readlinkSync(path: string): string; - export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; - export function realpathSync(path: string, cache?: { [path: string]: string }): string; - /* - * Asynchronous unlink - deletes the file specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous unlink - deletes the file specified in {path} - * - * @param path - */ - export function unlinkSync(path: string): void; - /* - * Asynchronous rmdir - removes the directory specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous rmdir - removes the directory specified in {path} - * - * @param path - */ - export function rmdirSync(path: string): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: number): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: string): void; - export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdirSync(path: string): string[]; - export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function closeSync(fd: number): void; - export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function openSync(path: string, flags: string, mode?: number): number; - export function openSync(path: string, flags: string, mode?: string): number; - export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimesSync(path: string, atime: number, mtime: number): void; - export function utimesSync(path: string, atime: Date, mtime: Date): void; - export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimesSync(fd: number, atime: number, mtime: number): void; - export function futimesSync(fd: number, atime: Date, mtime: Date): void; - export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fsyncSync(fd: number): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; - export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - */ - export function readFileSync(filename: string, encoding: string): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; - export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; - export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; - export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; - export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; - export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; - export function exists(path: string, callback?: (exists: boolean) => void): void; - export function existsSync(path: string): boolean; - /** Constant for fs.access(). File is visible to the calling process. */ - export var F_OK: number; - /** Constant for fs.access(). File can be read by the calling process. */ - export var R_OK: number; - /** Constant for fs.access(). File can be written by the calling process. */ - export var W_OK: number; - /** Constant for fs.access(). File can be executed by the calling process. */ - export var X_OK: number; - /** Tests a user's permissions for the file specified by path. */ - export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; - export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; - /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ - export function accessSync(path: string, mode ?: number): void; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: string; - mode?: number; - bufferSize?: number; - }): ReadStream; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: string; - mode?: string; - bufferSize?: number; - }): ReadStream; - export function createWriteStream(path: string, options?: { - flags?: string; - encoding?: string; - string?: string; - }): WriteStream; -} - -declare module "path" { - - /** - * A parsed path object generated by path.parse() or consumed by path.format(). - */ - export interface ParsedPath { - /** - * The root of the path such as '/' or 'c:\' - */ - root: string; - /** - * The full directory path such as '/home/user/dir' or 'c:\path\dir' - */ - dir: string; - /** - * The file name including extension (if any) such as 'index.html' - */ - base: string; - /** - * The file extension (if any) such as '.html' - */ - ext: string; - /** - * The file name without extension (if any) such as 'index' - */ - name: string; - } - - /** - * Normalize a string path, reducing '..' and '.' parts. - * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. - * - * @param p string path to normalize. - */ - export function normalize(p: string): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: any[]): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: string[]): string; - /** - * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. - * - * Starting from leftmost {from} paramter, resolves {to} to an absolute path. - * - * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. - * - * @param pathSegments string paths to join. Non-string arguments are ignored. - */ - export function resolve(...pathSegments: any[]): string; - /** - * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. - * - * @param path path to test. - */ - export function isAbsolute(path: string): boolean; - /** - * Solve the relative path from {from} to {to}. - * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. - * - * @param from - * @param to - */ - export function relative(from: string, to: string): string; - /** - * Return the directory name of a path. Similar to the Unix dirname command. - * - * @param p the path to evaluate. - */ - export function dirname(p: string): string; - /** - * Return the last portion of a path. Similar to the Unix basename command. - * Often used to extract the file name from a fully qualified path. - * - * @param p the path to evaluate. - * @param ext optionally, an extension to remove from the result. - */ - export function basename(p: string, ext?: string): string; - /** - * Return the extension of the path, from the last '.' to end of string in the last portion of the path. - * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string - * - * @param p the path to evaluate. - */ - export function extname(p: string): string; - /** - * The platform-specific file separator. '\\' or '/'. - */ - export var sep: string; - /** - * The platform-specific file delimiter. ';' or ':'. - */ - export var delimiter: string; - /** - * Returns an object from a path string - the opposite of format(). - * - * @param pathString path to evaluate. - */ - export function parse(pathString: string): ParsedPath; - /** - * Returns a path string from an object - the opposite of parse(). - * - * @param pathString path to evaluate. - */ - export function format(pathObject: ParsedPath): string; - - export module posix { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } - - export module win32 { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } -} - -declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - detectIncompleteChar(buffer: Buffer): number; - } - export var StringDecoder: { - new (encoding: string): NodeStringDecoder; - }; -} - -declare module "tls" { - import * as crypto from "crypto"; - import * as net from "net"; - import * as stream from "stream"; - - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; - - export interface TlsOptions { - pfx?: any; //string or buffer - key?: any; //string or buffer - passphrase?: string; - cert?: any; - ca?: any; //string or buffer - crl?: any; //string or string array - ciphers?: string; - honorCipherOrder?: any; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; //array or Buffer; - SNICallback?: (servername: string) => any; - } - - export interface ConnectionOptions { - host?: string; - port?: number; - socket?: net.Socket; - pfx?: any; //string | Buffer - key?: any; //string | Buffer - passphrase?: string; - cert?: any; //string | Buffer - ca?: any; //Array of string | Buffer - rejectUnauthorized?: boolean; - NPNProtocols?: any; //Array of string | Buffer - servername?: string; - } - - export interface Server extends net.Server { - // Extended base methods - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - - listen(port: number, host?: string, callback?: Function): Server; - close(): Server; - address(): { port: number; family: string; address: string; }; - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; - maxConnections: number; - connections: number; - } - - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } - - export interface SecurePair { - encrypted: any; - cleartext: any; - } - - export interface SecureContextOptions { - pfx?: any; //string | buffer - key?: any; //string | buffer - passphrase?: string; - cert?: any; // string | buffer - ca?: any; // string | buffer - crl?: any; // string | string[] - ciphers?: string; - honorCipherOrder?: boolean; - } - - export interface SecureContext { - context: any; - } - - export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; - export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; - export function createSecureContext(details: SecureContextOptions): SecureContext; -} - -declare module "crypto" { - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: any; //string | string array - crl: any; //string | string array - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string): Hmac; - export function createHmac(algorithm: string, key: Buffer): Hmac; - interface Hash { - update(data: any, input_encoding?: string): Hash; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - interface Hmac { - update(data: any, input_encoding?: string): Hmac; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - interface Cipher { - update(data: Buffer): Buffer; - update(data: string, input_encoding?: string, output_encoding?: string): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - } - export function createDecipher(algorithm: string, password: any): Decipher; - export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - interface Decipher { - update(data: Buffer): Buffer; - update(data: string, input_encoding?: string, output_encoding?: string): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - } - export function createSign(algorithm: string): Signer; - interface Signer extends NodeJS.WritableStream { - update(data: any): void; - sign(private_key: string, output_format: string): string; - } - export function createVerify(algorith: string): Verify; - interface Verify extends NodeJS.WritableStream { - update(data: any): void; - verify(object: string, signature: string, signature_format?: string): boolean; - } - export function createDiffieHellman(prime_length: number): DiffieHellman; - export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; - interface DiffieHellman { - generateKeys(encoding?: string): string; - computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; - getPrime(encoding?: string): string; - getGenerator(encoding: string): string; - getPublicKey(encoding?: string): string; - getPrivateKey(encoding?: string): string; - setPublicKey(public_key: string, encoding?: string): void; - setPrivateKey(public_key: string, encoding?: string): void; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; - export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number, digest: string) : Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; -} - -declare module "stream" { - import * as events from "events"; - - export interface Stream extends events.EventEmitter { - pipe(destination: T, options?: { end?: boolean; }): T; - } - - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - } - - export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): string|Buffer; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - } - - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - } - - export class Writable extends events.EventEmitter implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - } - - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements NodeJS.ReadWriteStream { - writable: boolean; - constructor(opts?: DuplexOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface TransformOptions extends ReadableOptions, WritableOptions {} - - // Note: Transform lacks the _read and _write methods of Readable/Writable. - export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { - readable: boolean; - writable: boolean; - constructor(opts?: TransformOptions); - _transform(chunk: Buffer, encoding: string, callback: Function): void; - _transform(chunk: string, encoding: string, callback: Function): void; - _flush(callback: Function): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export class PassThrough extends Transform {} -} - -declare module "util" { - export interface InspectOptions { - showHidden?: boolean; - depth?: number; - colors?: boolean; - customInspect?: boolean; - } - - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; - export function inspect(object: any, options: InspectOptions): string; - export function isArray(object: any): boolean; - export function isRegExp(object: any): boolean; - export function isDate(object: any): boolean; - export function isError(object: any): boolean; - export function inherits(constructor: any, superConstructor: any): void; -} - -declare module "assert" { - function internal (value: any, message?: string): void; - module internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; - - constructor(options?: {message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function}); - } - - export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export var throws: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export var doesNotThrow: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export function ifError(value: any): void; - } - - export = internal; -} - -declare module "tty" { - import * as net from "net"; - - export function isatty(fd: number): boolean; - export interface ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - } - export interface WriteStream extends net.Socket { - columns: number; - rows: number; - } -} - -declare module "domain" { - import * as events from "events"; - - export class Domain extends events.EventEmitter { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - - addListener(event: string, listener: Function): Domain; - on(event: string, listener: Function): Domain; - once(event: string, listener: Function): Domain; - removeListener(event: string, listener: Function): Domain; - removeAllListeners(event?: string): Domain; - } - - export function create(): Domain; -} - -declare module "constants" { - export var E2BIG: number; - export var EACCES: number; - export var EADDRINUSE: number; - export var EADDRNOTAVAIL: number; - export var EAFNOSUPPORT: number; - export var EAGAIN: number; - export var EALREADY: number; - export var EBADF: number; - export var EBADMSG: number; - export var EBUSY: number; - export var ECANCELED: number; - export var ECHILD: number; - export var ECONNABORTED: number; - export var ECONNREFUSED: number; - export var ECONNRESET: number; - export var EDEADLK: number; - export var EDESTADDRREQ: number; - export var EDOM: number; - export var EEXIST: number; - export var EFAULT: number; - export var EFBIG: number; - export var EHOSTUNREACH: number; - export var EIDRM: number; - export var EILSEQ: number; - export var EINPROGRESS: number; - export var EINTR: number; - export var EINVAL: number; - export var EIO: number; - export var EISCONN: number; - export var EISDIR: number; - export var ELOOP: number; - export var EMFILE: number; - export var EMLINK: number; - export var EMSGSIZE: number; - export var ENAMETOOLONG: number; - export var ENETDOWN: number; - export var ENETRESET: number; - export var ENETUNREACH: number; - export var ENFILE: number; - export var ENOBUFS: number; - export var ENODATA: number; - export var ENODEV: number; - export var ENOENT: number; - export var ENOEXEC: number; - export var ENOLCK: number; - export var ENOLINK: number; - export var ENOMEM: number; - export var ENOMSG: number; - export var ENOPROTOOPT: number; - export var ENOSPC: number; - export var ENOSR: number; - export var ENOSTR: number; - export var ENOSYS: number; - export var ENOTCONN: number; - export var ENOTDIR: number; - export var ENOTEMPTY: number; - export var ENOTSOCK: number; - export var ENOTSUP: number; - export var ENOTTY: number; - export var ENXIO: number; - export var EOPNOTSUPP: number; - export var EOVERFLOW: number; - export var EPERM: number; - export var EPIPE: number; - export var EPROTO: number; - export var EPROTONOSUPPORT: number; - export var EPROTOTYPE: number; - export var ERANGE: number; - export var EROFS: number; - export var ESPIPE: number; - export var ESRCH: number; - export var ETIME: number; - export var ETIMEDOUT: number; - export var ETXTBSY: number; - export var EWOULDBLOCK: number; - export var EXDEV: number; - export var WSAEINTR: number; - export var WSAEBADF: number; - export var WSAEACCES: number; - export var WSAEFAULT: number; - export var WSAEINVAL: number; - export var WSAEMFILE: number; - export var WSAEWOULDBLOCK: number; - export var WSAEINPROGRESS: number; - export var WSAEALREADY: number; - export var WSAENOTSOCK: number; - export var WSAEDESTADDRREQ: number; - export var WSAEMSGSIZE: number; - export var WSAEPROTOTYPE: number; - export var WSAENOPROTOOPT: number; - export var WSAEPROTONOSUPPORT: number; - export var WSAESOCKTNOSUPPORT: number; - export var WSAEOPNOTSUPP: number; - export var WSAEPFNOSUPPORT: number; - export var WSAEAFNOSUPPORT: number; - export var WSAEADDRINUSE: number; - export var WSAEADDRNOTAVAIL: number; - export var WSAENETDOWN: number; - export var WSAENETUNREACH: number; - export var WSAENETRESET: number; - export var WSAECONNABORTED: number; - export var WSAECONNRESET: number; - export var WSAENOBUFS: number; - export var WSAEISCONN: number; - export var WSAENOTCONN: number; - export var WSAESHUTDOWN: number; - export var WSAETOOMANYREFS: number; - export var WSAETIMEDOUT: number; - export var WSAECONNREFUSED: number; - export var WSAELOOP: number; - export var WSAENAMETOOLONG: number; - export var WSAEHOSTDOWN: number; - export var WSAEHOSTUNREACH: number; - export var WSAENOTEMPTY: number; - export var WSAEPROCLIM: number; - export var WSAEUSERS: number; - export var WSAEDQUOT: number; - export var WSAESTALE: number; - export var WSAEREMOTE: number; - export var WSASYSNOTREADY: number; - export var WSAVERNOTSUPPORTED: number; - export var WSANOTINITIALISED: number; - export var WSAEDISCON: number; - export var WSAENOMORE: number; - export var WSAECANCELLED: number; - export var WSAEINVALIDPROCTABLE: number; - export var WSAEINVALIDPROVIDER: number; - export var WSAEPROVIDERFAILEDINIT: number; - export var WSASYSCALLFAILURE: number; - export var WSASERVICE_NOT_FOUND: number; - export var WSATYPE_NOT_FOUND: number; - export var WSA_E_NO_MORE: number; - export var WSA_E_CANCELLED: number; - export var WSAEREFUSED: number; - export var SIGHUP: number; - export var SIGINT: number; - export var SIGILL: number; - export var SIGABRT: number; - export var SIGFPE: number; - export var SIGKILL: number; - export var SIGSEGV: number; - export var SIGTERM: number; - export var SIGBREAK: number; - export var SIGWINCH: number; - export var SSL_OP_ALL: number; - export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; - export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; - export var SSL_OP_CISCO_ANYCONNECT: number; - export var SSL_OP_COOKIE_EXCHANGE: number; - export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; - export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; - export var SSL_OP_EPHEMERAL_RSA: number; - export var SSL_OP_LEGACY_SERVER_CONNECT: number; - export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; - export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; - export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; - export var SSL_OP_NETSCAPE_CA_DN_BUG: number; - export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; - export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NO_COMPRESSION: number; - export var SSL_OP_NO_QUERY_MTU: number; - export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; - export var SSL_OP_NO_SSLv2: number; - export var SSL_OP_NO_SSLv3: number; - export var SSL_OP_NO_TICKET: number; - export var SSL_OP_NO_TLSv1: number; - export var SSL_OP_NO_TLSv1_1: number; - export var SSL_OP_NO_TLSv1_2: number; - export var SSL_OP_PKCS1_CHECK_1: number; - export var SSL_OP_PKCS1_CHECK_2: number; - export var SSL_OP_SINGLE_DH_USE: number; - export var SSL_OP_SINGLE_ECDH_USE: number; - export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; - export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; - export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; - export var SSL_OP_TLS_D5_BUG: number; - export var SSL_OP_TLS_ROLLBACK_BUG: number; - export var ENGINE_METHOD_DSA: number; - export var ENGINE_METHOD_DH: number; - export var ENGINE_METHOD_RAND: number; - export var ENGINE_METHOD_ECDH: number; - export var ENGINE_METHOD_ECDSA: number; - export var ENGINE_METHOD_CIPHERS: number; - export var ENGINE_METHOD_DIGESTS: number; - export var ENGINE_METHOD_STORE: number; - export var ENGINE_METHOD_PKEY_METHS: number; - export var ENGINE_METHOD_PKEY_ASN1_METHS: number; - export var ENGINE_METHOD_ALL: number; - export var ENGINE_METHOD_NONE: number; - export var DH_CHECK_P_NOT_SAFE_PRIME: number; - export var DH_CHECK_P_NOT_PRIME: number; - export var DH_UNABLE_TO_CHECK_GENERATOR: number; - export var DH_NOT_SUITABLE_GENERATOR: number; - export var NPN_ENABLED: number; - export var RSA_PKCS1_PADDING: number; - export var RSA_SSLV23_PADDING: number; - export var RSA_NO_PADDING: number; - export var RSA_PKCS1_OAEP_PADDING: number; - export var RSA_X931_PADDING: number; - export var RSA_PKCS1_PSS_PADDING: number; - export var POINT_CONVERSION_COMPRESSED: number; - export var POINT_CONVERSION_UNCOMPRESSED: number; - export var POINT_CONVERSION_HYBRID: number; - export var O_RDONLY: number; - export var O_WRONLY: number; - export var O_RDWR: number; - export var S_IFMT: number; - export var S_IFREG: number; - export var S_IFDIR: number; - export var S_IFCHR: number; - export var S_IFLNK: number; - export var O_CREAT: number; - export var O_EXCL: number; - export var O_TRUNC: number; - export var O_APPEND: number; - export var F_OK: number; - export var R_OK: number; - export var W_OK: number; - export var X_OK: number; - export var UV_UDP_REUSEADDR: number; -} diff --git a/extensions/video/src/typings/react-native-video.d.ts b/extensions/video/src/typings/react-native-video.d.ts index 1963a2535..b399e72f5 100644 --- a/extensions/video/src/typings/react-native-video.d.ts +++ b/extensions/video/src/typings/react-native-video.d.ts @@ -1,18 +1,17 @@ -/* -* react-native-video.d.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definition for the React Native implementation -* of video player: -* https://github.com/brentvatne/react-native-video -*/ +/** + * react-native-video.d.ts + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Type definition for the React Native implementation + * of video player: + * https://github.com/brentvatne/react-native-video + */ declare module 'react-native-video' { - - import React = require('react'); - import RN = require('react-native'); + import * as React from 'react'; + import * as RN from 'react-native'; interface VideoProgress { atValue: number; @@ -41,7 +40,7 @@ declare module 'react-native-video' { // Some versions of react-native-video may not support this option. authToken?: string; - }; + } | number; resizeMode?: string; poster?: string; @@ -57,6 +56,7 @@ declare module 'react-native-video' { controls?: boolean; currentTime?: number; progressUpdateInterval?: number; + useTextureView?: boolean; onLoadStart?: () => void; onLoad?: (info: VideoInfo) => void; onBuffer?: (bufferInfo: VideoBufferInfo) => void; @@ -75,7 +75,7 @@ declare module 'react-native-video' { onAudioFocusChanged?: () => void; onAudioBecomingNoisy?: () => void; - style?: any + style?: any; } export default class Video extends React.Component { diff --git a/extensions/video/src/typings/react-native.d.ts b/extensions/video/src/typings/react-native.d.ts deleted file mode 100644 index f6587f177..000000000 --- a/extensions/video/src/typings/react-native.d.ts +++ /dev/null @@ -1,1091 +0,0 @@ -/** -* react-native.d.ts -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Type definition file for React Native, based on the React.js definition file -* on https://github.com/borisyankov/DefinitelyTyped. -*/ - -declare module 'react-native' { - // - // React - // ---------------------------------------------------------------------- - - import React = require('react'); - - // BT: Adding ProgressBarAndroid. It's not part of the DefinitelyTyped definitions. - class ProgressBarAndroid extends React.Component {} - - type ReactElement = React.ReactElement; - type ReactNode = React.ReactNode; - - function createElement

( - type: string, - props?: P, - ...children: React.ReactNode[]): React.ReactElement

; - - function cloneElement

( - element: P, - props ?: any - ): React.ReactElement

; - - interface SyntheticEvent extends React.SyntheticEvent {} - - function isValidElement(object: {}): boolean; - function findNodeHandle(componentOrHandle: any): number; - - var Children: React.ReactChildren; - - type PlatformString = 'android'|'ios'|'windows'; - var Platform: { - OS: PlatformString, - Version?: number - }; - - // - // Component base - // ---------------------------------------------------------------------- - - abstract class ReactNativeBaseComponent extends React.Component { - setNativeProps(nativeProps: P): void; - focus(): void; - blur(): void; - measure(callback: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void)): void; - measureLayout(relativeToNativeNode: number, onSuccess: ((x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void), onFail: () => void): void; - refs: { - [key: string]: ReactNativeBaseComponent; - } - } - - // - // Style rules - // ---------------------------------------------------------------------- - - type StyleRuleSet = Object | Object[]; - - // - // Specific components - // ---------------------------------------------------------------------- - - interface ComponentPropsBase { - ref?: string | ((obj: ReactNativeBaseComponent) => void); - key?: string | number; - } - - interface ComponentPropsStyleBase extends ComponentPropsBase { - style?: StyleRuleSet | StyleRuleSet[]; - } - - interface ImageSource { - uri: string; - headers?: {[header: string]: string}; - } - - interface ImageProps extends ComponentPropsStyleBase { - onLayout?: Function; - resizeMode?: string; - resizeMethod?: string; // android only prop: 'auto' | 'resize' | 'scale' - source?: ImageSource | number; - testID?: string; - - // iOS - accessibilityLabel?: string; - shouldRasterizeIOS?: boolean; - accessible?: boolean; - capInsets?: Object; - defaultSource?: Object; - onError?: Function; - onLoad?: Function; - onLoadEnd?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - onProgress?: Function; - - // Android - fadeDuration?: number; - } - - interface ActivityIndicatorProps extends ComponentPropsBase { - animating?: boolean; - color?: string; - onLayout?: Function; - size?: string; // enum { 'small', 'large' } - } - - interface TextProps extends ComponentPropsStyleBase { - importantForAccessibility?: string; // 'auto' | 'yes' | 'no' | 'no-hide-descendants'; - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - children? : React.ReactNode; - numberOfLines? : number; - ellipsizeMode? : 'head' | 'middle' | 'tail' // There's also 'clip' but it is iOS only - onLayout? : Function; - onPress? : Function; - onLongPress? : Function; - selectable? : boolean; // only on android, windows - testID? : string; - - // iOS - suppressHighlighting?: boolean; - - // Android - textBreakStrategy?: 'highQuality' | 'simple'| 'balanced'; - elevation?: number; - } - - export interface PickerProps extends ComponentPropsStyleBase { - - /** - * Callback for when an item is selected. This is called with the - * following parameters: - * - itemValue: the value prop of the item that was selected - * - itemPosition: the index of the selected item in this picker - * @param itemValue - * @param itemPosition - */ - onValueChange?: ( itemValue: any, itemPosition: number ) => void - - /** - * Value matching value of one of the items. - * Can be a string or an integer. - */ - selectedValue?: any - - style?: StyleRuleSet | StyleRuleSet[] - - /** - * Used to locate this view in end-to-end tests. - */ - testId?: string - - ref?: string | ((obj: ReactNativeBaseComponent) => void); - } - - interface TouchableWithoutFeedbackProps extends ComponentPropsBase { - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - accessible?: boolean; - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - delayLongPress?: number; - delayPressIn?: number; - delayPressOut?: number; - onLayout?: Function; - onLongPress?: Function; - onPress?: Function; - onPressIn?: Function; - onPressOut?: Function - } - - interface TouchableHighlightProps extends TouchableWithoutFeedbackProps, ComponentPropsStyleBase { - activeOpacity? : number; - children? : React.ReactNode; - onHideUnderlay?: Function; - onShowUnderlay?: Function; - underlayColor? : string; - } - - interface ResponderProps { - onMoveShouldSetResponder? : Function; - onResponderGrant? : Function; - onResponderMove? : Function; - onResponderReject? : Function; - onResponderRelease? : Function; - onResponderTerminate? : Function; - onResponderTerminationRequest? : Function; - onStartShouldSetResponder? : Function; - onStartShouldSetResponderCapture?: Function; - } - - interface ViewOnLayoutEvent { - nativeEvent: { - layout: { - x: number, - y: number, - width: number, - height: number - } - } - } - - type ViewLayerType = 'none' | 'software' | 'hardware'; - - interface CommonAccessibilityProps { - accessibilityLabel? : string; - accessible? : boolean; - onAcccessibilityTap? : Function; - - // android - accessibilityComponentType? : string; //enum ( 'none', 'button', 'radiobutton_checked', 'radiobutton_unchecked' ) - accessibilityLiveRegion? : string; //enum ( 'none', 'polite', 'assertive' ) - importantForAccessibility? : string; //enum( 'auto', 'yes', 'no', 'no-hide-descendants' ) - - // iOS - accessibilityTraits?: string | string[]; //enum( 'none', 'button', 'link', 'header', 'search', 'image', 'selected', 'plays', 'key', 'text', 'summary', 'disabled', 'frequentUpdates', 'startsMedia', 'adjustable', 'allowsDirectInteraction', 'pageTurn' ) - } - - interface ViewProps extends ComponentPropsBase, ResponderProps, ComponentPropsStyleBase, CommonAccessibilityProps { - children? : any; - onLayout? : ((ev: ViewOnLayoutEvent) => void); - onMagicTap? : Function; - pointerEvents? : string; //enum( 'box-none', 'none', 'box-only', 'auto' ); - removeClippedSubviews? : boolean; - testID? : string; - - // android - collapsable? : boolean; - needsOffscreenAlphaCompositing?: boolean; - renderToHardwareTextureAndroid?: boolean; - viewLayerTypeAndroid? : ViewLayerType; - elevation? : number; - - // iOS - onAccessibilityTapIOS?: Function; - shouldRasterizeIOS? : boolean; - } - - interface ScrollViewProps extends ViewProps { - children?: any; - - contentContainerStyle?: StyleRuleSet | StyleRuleSet[]; - horizontal?: boolean; - keyboardDismissMode?: 'none' | 'interactive' | 'on-drag'; - keyboardShouldPersistTaps?: 'always' | 'never' | 'handled'; - onScroll?: Function; - onScrollBeginDrag?: Function; - onScrollEndDrag?: Function; - onContentSizeChange?: (width: number, height: number) => void; - showsHorizontalScrollIndicator?: boolean; - showsVerticalScrollIndicator?: boolean; - removeClippedSubviews?: boolean; - - // iOS - automaticallyAdjustContentInsets?: boolean; - //contentInset?: EdgeInsetsPropType; - //contentOffset?: PointPropType; - bounces?: boolean; - bouncesZoom?: boolean; - alwaysBounceHorizontal?: boolean; - alwaysBounceVertical?: boolean; - centerContent?: boolean; - decelerationRate?: number; - directionalLockEnabled?: boolean; - canCancelContentTouches?: boolean; - maximumZoomScale?: number; - minimumZoomScale?: number; - onScrollAnimationEnd?: Function; - pagingEnabled?: boolean; - scrollEnabled?: boolean; - scrollEventThrottle?: number; - scrollsToTop?: boolean; - stickyHeaderIndices?: [number]; - snapToInterval?: number; - snapToAlignment?: string; // enum( 'start', 'center', 'end' ) - zoomScale?: number; - overScrollMode?: string; //enum( 'always', 'always-if-content-scrolls', 'never' ) - // iOS - scrollIndicatorInsets?: {top: number, left: number, bottom: number, right: number }; - } - - interface ListViewDataSourceCallback { - rowHasChanged: (r1: T, r2: T) => boolean; - } - - interface ListViewDataSource { - new (onAsset: ListViewDataSourceCallback): ListViewDataSource; - cloneWithRows(rowList: T[]): void; - } - - interface ListViewProps extends ScrollViewProps { - dataSource: Object; //PropTypes.instanceOf(ListViewDataSource).isRequired - renderSeparator?: Function; - renderRow: Function; - initialListSize?: number; - onEndReached?: (e: React.SyntheticEvent) => void; - onEndReachedThreshold?: number; - pageSize?: number; - renderFooter?: Function; - renderHeader?: Function; - renderSectionHeader?: Function; - renderScrollComponent: Function; - scrollRenderAheadDistance?: number; - onChangeVisibleRows?: Function; - removeClippedSubviews?: boolean; - } - - interface ModalProps extends ComponentPropsBase { - animationType?: string; // enum( 'none', 'slide', 'fade' ) - onDismiss?: Function; - transparent?: boolean; - onRequestClose: () => void; - } - - interface TextInputProps extends ComponentPropsStyleBase, CommonAccessibilityProps { - autoCapitalize?: string; // enum('none', 'sentences', 'words', 'characters') - autoCorrect?: boolean; - autoFocus?: boolean; - blurOnSubmit?: boolean; - defaultValue?: string; - editable?: boolean; - keyboardType?: string; // enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search') - multiline?: boolean; - onBlur?: ((e: React.FocusEvent) => void); - onKeyPress?: (e: SyntheticEvent) => void; - onChange?: Function; - onChangeText?: ((changedText: string) => void); - onSelectionChange?: ((selection: SyntheticEvent) => void); - onEndEditing?: Function; - onFocus?: ((e: React.FocusEvent) => void); - onLayout?: ((props: { x: number, y: number, width: number, height: number }) => void); - onSubmitEditing?: Function; - onScroll?: Function; - placeholder?: string; - placeholderTextColor?: string; - returnKeyType?: string; // enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call') - secureTextEntry?: boolean; - testID?: string; - textAlign?: string; // enum('auto' | 'left' | 'right' | 'center' | 'justify') - allowFontScaling?: boolean; - maxContentSizeMultiplier?: number; - selection?: { start: number, end: number }; - - //iOS and android - selectionColor?: string; - - value: string; - //iOS - clearButtonMode?: string; // enum('never', 'while-editing', 'unless-editing', 'always') - clearTextOnFocus?: boolean; - enablesReturnKeyAutomatically?: boolean; - keyboardAppearance?: string; // enum ('default', 'light', 'dark') - maxLength?: number; - numberOfLines?: number; - selectTextOnFocus?: boolean; - selectionState?: any; // see DocumentSelectionState.js - spellCheck?: boolean; - //android - textAlignVertical?: string; // enum('top', 'center', 'bottom') - textAlignVerticalAndroid?: string; // enum('top', 'center', 'bottom') - textAlignAndroid?: string; - underlineColorAndroid?: string; - disableFullscreenUI?: boolean; - textBreakStrategy?: 'highQuality' | 'simple' | 'balanced'; - } - - interface TextInputState { - currentlyFocusedField(): number; - focusTextInput(textFieldID?: number): void; - blurTextInput(textFieldID?: number): void; - } - - interface WebViewProps extends ComponentPropsStyleBase { - automaticallyAdjustContentInsets?: boolean; - bounces?: boolean; - contentInset?: {top: number, left: number, bottom: number, right: number }; - injectedJavaScript?: string; - javaScriptEnabled?: boolean; - domStorageEnabled?: boolean; - onShouldStartLoadWithRequest?: Function; - onNavigationStateChange?: Function; - onLoad?: (e: SyntheticEvent) => void; - onLoadStart?: Function; - renderError?: Function; - onError?: Function; - renderLoading?: Function; - scalesPageToFit?: boolean; - scrollEnabled?: boolean; - startInLoadingState?: boolean; - source?: { uri: string; method?: string; headers?: Object; body?: string; } | { html: string; baseUrl?: string; }; - } - - interface DatePickerIOSProps extends ComponentPropsStyleBase { - date?: Date; - maximumDate?: Date; - minimumDate?: Date; - minuteInterval?: number; - mode?: string; - timeZoneOffsetInMinutes?: number; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerIOS extends ReactNativeBaseComponent { - } - - interface DatePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class DatePickerAndroid extends ReactNativeBaseComponent { - static open(options: { date: Date, maxDate: Date, minDate: Date }): Promise; - static dateSetAction: Function; - static dismissedAction: Function; - } - - interface TimePickerAndroidProps extends ComponentPropsStyleBase { - date?: Date; - maxDate?: Date; - minDate?: Date; - - onDateChange?: (newDate: Date) => void; - } - - class TimePickerAndroid extends ReactNativeBaseComponent { - static open(options: { hour: number, minute: number, is24Hour: boolean }): Promise; - static timeSetAction: Function; - static dismissedAction: Function; - } - - type DatePickerAction = { - action: Function; - day: number; - month: number; - year: number; - } - - type TimePickerAction = { - action: Function; - hour: number; - minute: number; - } - - class Image extends ReactNativeBaseComponent { - static prefetch(url: string): Promise; - } - class ActivityIndicator extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - class Picker extends ReactNativeBaseComponent { - static Item: any; - } - class TouchableHighlight extends ReactNativeBaseComponent { } - class TouchableWithoutFeedback extends ReactNativeBaseComponent { } - class View extends ReactNativeBaseComponent { } - class ScrollView extends ReactNativeBaseComponent { - getInnerViewNode(): number; - // TODO: Define ScrollResponder type - scrollTo(val: { x?: number; y?: number; animated?: boolean; }): void; - scrollBy(val: { deltaX?: number; deltaY?: number; animated?: boolean; }): void; - } - class ListView extends ReactNativeBaseComponent { - static DataSource: ListViewDataSource; - } - class Modal extends ReactNativeBaseComponent { } - class TextInput extends ReactNativeBaseComponent { - static State: TextInputState; - } - class WebView extends ReactNativeBaseComponent { - reload() : void; - goBack() : void; - goForward() : void; - } - - interface ActionSheetOptions { - options: string[]; - cancelButtonIndex?: number; - destructiveButtonIndex?: number; - title?: string; - message?: string; - } - - interface ShareActionSheetOptions { - message?: string; - url?: string; - subject?: string; - excludedActivityTypes?: string[]; - } - - class ActionSheetIOS { - static showActionSheetWithOptions(options: ActionSheetOptions, callback: (buttonIndex: number) => void): void; - static showShareActionSheetWithOptions(options: ShareActionSheetOptions, failureCallback: (error: string) => void, successCallback: (success: boolean, method: string) => void): void; - } - - class BackAndroid { - static addEventListener(eventName: string, callback: () => boolean): void; - static removeEventListener(eventName: string, callback: () => boolean): void; - } - - interface NavigatorIOSRoute { - component: any; - title: string; - passProps?: any; - backButtonTitle?: string; - backButtonIcon?: any; - leftButtonTitle?: string; - leftButtonIcon?: any; - onLeftButtonPress?: () => void; - rightButtonTitle?: string; - rightButtonIcon?: any; - onRightButtonPress?: () => void; - wrapperStyle?: any; - } - - interface NavigatorIOSProps extends ComponentPropsBase { - barTintColor?: string; - initialRoute: NavigatorIOSRoute; - itemWrapperStyle?: StyleRuleSet | StyleRuleSet[]; - navigationBarHidden?: boolean; - shadowHidden?: boolean; - style?:any; - tintColor?: string; - titleTextColor?: string; - translucent?: boolean; - interactivePopGestureEnabled?: boolean; - } - - class StatusBar { - // Native - static setHidden(hidden: boolean, animation?: string): void; //'none'|'fade'|'slide'; - - // iOS - static setBarStyle(barStyle: string, animated: boolean): void; //'default'|'light-content'; - static setNetworkActivityIndicatorVisible(value: boolean): void; - - // Android - static setBackgroundColor(color: string, animated?: boolean): void; - static setTranslucent(translucent: boolean): void; - } - - interface EventSubscription { - remove(): void; - } - - interface NavigatorIOSNavigationContext { - addListener(event: string, callback: (route: NavigatorIOSRoute) => void): EventSubscription; - } - - interface NavigatorIOSState { - observedTopOfStack: number; - requestedTopOfStack: number; - routeStack: NavigatorIOSRoute[]; - } - - class NavigatorIOS extends ReactNativeBaseComponent { - navigationContext: NavigatorIOSNavigationContext; - push(route: NavigatorIOSRoute): void; - pop(): void; - popN(n: number): void; - replace(route: NavigatorIOSRoute): void; - replacePrevious(route: NavigatorIOSRoute): void; - replacePreviousAndPop(route: NavigatorIOSRoute): void; - resetTo(route: NavigatorIOSRoute): void; - popToRoute(route: NavigatorIOSRoute): void; - popToTop(): void; - } - - // StyleSheet - class StyleSheet { - static create(obj: { [key: string]: any }): any; - static flatten: (s: StyleSheet) => { [key: string]: any }; - } - - class AppRegistry { - static registerComponent(appKey: string, getComponentFunc: Function): any; - } - - type CameraRollProps = { - /** - * The number of photos wanted in reverse order of the photo application - * (i.e. most recent first for SavedPhotos). - */ - first: number, - - /** - * A cursor that matches `page_info { end_cursor }` returned from a previous - * call to `getPhotos` - */ - after?: string, - - /** - * Specifies which group types to filter the results to. - */ - groupTypes?: string, // enum { 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream', 'SavedPhotos', // default }, - - /** - * Specifies filter on group names, like 'Recent Photos' or custom album - * titles. - */ - groupName?: string, - - /** - * Specifies filter on asset type - */ - assetType?: string; // enum { 'All', 'Videos', 'Photos', // default }, - - } - - type GetPhotosCallbackPropNode = { - node: { - type: string, - group_name: string, - image: { - uri: string, - height: number, - width: number, - isStored?: boolean, - }, - timestamp: number, - location?: { - latitude?: number, - longitude?: number, - altitude?: number, - heading?: number, - speed?: number, - } - } - } - - type GetPhotosCallbackProps = { - edges: GetPhotosCallbackPropNode[], - page_info: { - has_next_page: boolean, - start_cursor?: string, - end_cursor?: string, - } - } - - class Clipboard { - static setString(content: string): void; - static getString(): Promise; - } - - class CameraRoll { - static saveImageWithTag(tag: string, successCallback: Function, errorCallback: Function): void; - static getPhotos(params: CameraRollProps, callback: ((props: GetPhotosCallbackProps) => void), errorCallback: Function): void; - } - - class Linking { - static getInitialURL(): Promise; - static openURL(url: string): Promise; - static canOpenURL(url: string): Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - } - - class AccessibilityInfo { - static fetch: () => Promise; - static addEventListener(type: string, handler: (event: any) => void): void; - static removeEventListener(type: string, handler: (event: any) => void): void; - static announceForAccessibility(announcement: string): void; - static setAccessibilityFocus(reactTag: number): void; - } - - interface AlertButtonSpec { - text?: string; - onPress?: () => void; - style?: string; // enum {default', 'cancel', 'destructive'} - } - - class Alert { - static alert( - title: string, - message?: string, - buttons?: AlertButtonSpec[], - type?: string // enum { 'default', 'plain-text', 'secure-text', 'login-password'} - ): void; - } - - class PushNotificationIOS { - static presentLocalNotification(details: { category: string, alertBody: string, soundName?: string}): void; - static scheduleLocalNotification(details: {alertBody: string, fireDate: Date}): void; - - static getApplicationIconBadgeNumber(callback: (badgeCount:number) => void): void; - static setApplicationIconBadgeNumber(number: number): void; - - static addEventListener(type: string, handler: (event: any) => void): void; - - static requestPermissions(permissions?: {alert?: boolean, badge?: boolean, sound?: boolean}): void; - static abandonPermissions(): void; - static checkPermissions(callback: (permissions: {alert: boolean, badge: boolean, sound: boolean}) => void): void; - - static getInitialNotification(): Promise; - - getMessage(): string; - getSound(): string; - getAlert(): any; - getBadgeCount(): number; - getData(): any; - } - - interface PanResponderGestureState { - stateID: number; - moveX: number; - moveY: number; - x0: number; - y0: number; - dx: number; - dy: number; - vx: number; - vy: number; - numberActiveTouches: number; - } - - interface ResponderSyntheticEvent extends React.SyntheticEvent { - touchHistory: Function; - } - - type PanResponderCreateConfig = { - onMoveShouldSetPanResponder?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean, - onMoveShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onStartShouldSetPanResponderCapture?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderReject?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderGrant?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderStart?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderEnd?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderRelease?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderMove?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminate?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onPanResponderTerminationRequest?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), - onShouldBlockNativeResponder?: ((e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void | boolean), // android only - onStartShouldSetResponderCapture?: (e: ResponderSyntheticEvent, gestureState: PanResponderGestureState) => void, - - } - - class PanResponder { - static create(config: PanResponderCreateConfig): PanResponder; - panHandlers: ResponderProps; - } - - type DimensionType = { - width: number, - height: number, - scale: number, - fontScale: number, - } - - class Dimensions { - static set(obj: any): boolean; - static get(key: string): DimensionType; - } - - type RCTAppStateData = { app_state: string } - type RCTAppState = { - getCurrentAppState(successCallback: (appStateData: RCTAppStateData) => void, failureCallback: () => void): void; - } - - type FileInput = { - selectImage: Function; - } - - type SnapshotOptions = { - width?: number; - height?: number; - format?: 'png' | 'jpeg'; - quality?: number; - } - - type UIManager = { - measure: Function; - measureInWindow: Function; - measureLayout: Function; - measureLayoutRelativeToParent: Function; - dispatchViewManagerCommand: Function; - - getMaxContentSizeMultiplier: Function; - setMaxContentSizeMultiplier: Function; - - // ios - takeSnapshot: (view: any, options?: SnapshotOptions) => Promise; - - // Android - sendAccessibilityEvent: Function; - } - - type AccessibilityManager = { - getMultiplier: Function; - announceForAccessibility (announcement: string): void; - } - - // We don't use this module, but need to be able to check its existance - type NativeAnimatedModule = { - - }; - - class ImagePickerManager { - showImagePicker: Function; - launchCamera: Function; - launchImageLibrary: Function; - } - - class NativeModules { - static AppState: RCTAppState; - static FileInput: FileInput; - static UIManager: UIManager; - static AccessibilityManager: AccessibilityManager; - static ImagePickerManager: ImagePickerManager; - static Networking: { - clearCookies(callback: (success: boolean) => void): void; - } - static ContextMenuAndroid: { - show(buttons: any, callback: (command: string) => void): void; - } - static NativeAnimation: NativeAnimatedModule; - } - - class AsyncStorage { - static getItem(key: string, callback: (error: any, result: string) => void): void; - static setItem(key: string, value: string, callback: (error: any) => void): void; - static removeItem(key: string, callback: (error: any) => void): void; - static clear(callback: (error: any) => void): void; - } - - class NetInfo { - static isConnected: { - addEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - removeEventListener: (eventName: string, handler: (isConnected: boolean) => void) => void; - fetch: () => Promise; - } - static fetch(): Promise; - } - - class Easing { - static bezier(x1: number, y1: number, x2: number, y2: number): ((input: number) => number); - static linear(): ((input: number) => number); - } - - interface AnimationConfig { - isInteraction?: boolean; - useNativeDriver?: boolean; - } - - interface AnimatedTimingConfig extends AnimationConfig { - toValue: number; - duration?: number; - delay?: number - easing?: (input: number) => number; - } - - interface CompositeAnimation { - start(callback?: AnimatedEndCallback): void; - stop: () => void; - } - - type AnimatedEndResult = { finished: boolean }; - type AnimatedEndCallback = (result: AnimatedEndResult) => void; - - module Animated { - function createAnimatedComponent(Component: any, notCollapsable?: boolean): any; - function delay(time: number): CompositeAnimation; - function timing(value: Animated.Value, config: AnimatedTimingConfig): CompositeAnimation; - function parallel(animations: CompositeAnimation[]): CompositeAnimation - function sequence(animations: CompositeAnimation[]): CompositeAnimation - class Value { - constructor(val: number); - setValue(value: number): void; - addListener(callback: any): string; - removeListener(id: string): void; - removeAllListeners(): void; - interpolate(config: any): Value; - } - class View extends ReactNativeBaseComponent { } - class Image extends ReactNativeBaseComponent { } - class Text extends ReactNativeBaseComponent { } - } - - interface IUpdateLayoutAnimationConfig { - duration?: number; - delay?: number; - - springDamping?: number; - initialVelocity?: number; - - type?: string; - } - - interface ICreateLayoutAnimationConfig extends IUpdateLayoutAnimationConfig { - property?: string; - } - - interface ILayoutAnimationConfig { - duration: number; - create?: ICreateLayoutAnimationConfig; - update?: IUpdateLayoutAnimationConfig; - } - - module LayoutAnimation { - function configureNext(config: ILayoutAnimationConfig): void; - - module Types { - var spring: string; - var linear: string; - var easeInEaseOut: string; - var easeIn: string; - var easeOut: string; - var keyboard: string; - } - - module Properties { - var opacity: string; - var scaleXY: string; - } - } - - class DeviceEventSubscription { - remove(): void; - } - - class NativeAppEventEmitter { - static addListener(eventId: string, callback: Function): DeviceEventSubscription; - } - - module DeviceEventEmitter{ - function addListener(name: string, callback: Function): void; - } - - module AppState { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module AppStateIOS { - var currentState: string; - function addEventListener(type: string, handler: Function): void; - function removeEventListener(type: string, handler: Function): void; - } - - module Touchable { - type RectOffset = { - top: number, - left: number, - right: number, - bottom: number - } - - interface State { - touchable: any - } - - interface TouchableMixin extends React.Mixin { - touchableGetInitialState: () => State - touchableHandleStartShouldSetResponder: () => {} - touchableHandleResponderTerminationRequest: () => {} - touchableHandleResponderGrant: (e: React.SyntheticEvent, dispatchID: string) => {} - touchableHandleResponderMove: (e: React.SyntheticEvent) => {} - touchableHandleResponderRelease: (e: React.SyntheticEvent) => {} - touchableHandleResponderTerminate: (e: React.SyntheticEvent) => {} - touchableHandleActivePressIn?: (e: React.SyntheticEvent) => {} - touchableHandleActivePressOut?: (e: React.SyntheticEvent) => {} - touchableHandlePress?: (e: React.SyntheticEvent) => {} - touchableHandleLongPress?: (e: React.SyntheticEvent) => {} - touchableGetHighlightDelayMS?: () => number - touchableGetPressRectOffset?: () => RectOffset - } - - var Mixin: TouchableMixin; - } - - class EmitterSubscription { - remove(): void; - } - - module Keyboard { - function addListener(eventType: string, listener: Function, context?: any): EmitterSubscription; - function removeAllListeners(eventType: string): void; - function removeSubscription(subscription: EmitterSubscription): void; - } - - module PixelRatio { - /** - * Returns the device pixel density. Some examples: - * - * - PixelRatio.get() === 1 - * - mdpi Android devices (160 dpi) - * - PixelRatio.get() === 1.5 - * - hdpi Android devices (240 dpi) - * - PixelRatio.get() === 2 - * - iPhone 4, 4S - * - iPhone 5, 5c, 5s - * - iPhone 6 - * - xhdpi Android devices (320 dpi) - * - PixelRatio.get() === 3 - * - iPhone 6 plus - * - xxhdpi Android devices (480 dpi) - * - PixelRatio.get() === 3.5 - * - Nexus 6 - **/ - function get(): number; - - /** - * Returns the scaling factor for font sizes. This is the ratio that is used to calculate the - * absolute font size, so any elements that heavily depend on that should use this to do - * calculations. - * - * If a font scale is not set, this returns the device pixel ratio. - * - * Currently this is only implemented on Android and reflects the user preference set in - * Settings > Display > Font size, on iOS it will always return the default pixel ratio. - * @platform android - **/ - function getFontScale(): number; - - /** - * Converts a layout size (dp) to pixel size (px). - * - * Guaranteed to return an integer number. - **/ - function getPixelSizeForLayoutSize(layoutSize: number): number; - - /** - * Rounds a layout size (dp) to the nearest layout size that corresponds to - * an integer number of pixels. For example, on a device with a PixelRatio - * of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to - * exactly (8.33 * 3) = 25 pixels. - **/ - function roundToNearestPixel(layoutSize: number): number; - } - - interface IncrementalProps extends ComponentPropsStyleBase { - onDone?: () => void; - name: string; - children?: any; - } - - interface IncrementalPresenterProps extends ComponentPropsStyleBase { - name: string; - disabled?: boolean; - onDone?: () => void; - onLayout?: (event: Object) => void; - style?: any; - children?: any; - } - - class Incremental extends ReactNativeBaseComponent { - } - - class IncrementalGroup extends ReactNativeBaseComponent{ - } - - class IncrementalPresenter extends ReactNativeBaseComponent { - } - - module JSEventLoopWatchdog { - function install(obj: any): void; - } - - module InteractionManager { - function setDeadline(deadline: number): void; - } - - interface I18nManager { - isRTL: boolean - allowRTL: (allowRTL: boolean) => {} - forceRTL: (forceRTL: boolean) => {} - } - - export var I18nManager: I18nManager; -} - -interface GeoConfiguration { - skipPermissionRequests: boolean; -} - -interface Geolocation { - // React Native addition to navigator.geolocation - setRNConfiguration(config: GeoConfiguration): void; -} - diff --git a/extensions/video/src/web/PluginBase.ts b/extensions/video/src/web/PluginBase.ts index 1b20b52b0..9cf5aee40 100644 --- a/extensions/video/src/web/PluginBase.ts +++ b/extensions/video/src/web/PluginBase.ts @@ -6,7 +6,8 @@ * Base export for the Web implementation of the plugin. */ +import * as Types from '../common/Types'; + import Video from './Video'; -import Types = require('../common/Types'); export { Video as default, Types }; diff --git a/extensions/video/src/web/Video.tsx b/extensions/video/src/web/Video.tsx index 788db1d43..493151405 100644 --- a/extensions/video/src/web/Video.tsx +++ b/extensions/video/src/web/Video.tsx @@ -1,33 +1,35 @@ -/* -* Video.tsx -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT license. -* -* Web-specific implementation of the cross-platform Video abstraction. -*/ +/** + * Video.tsx + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT license. + * + * Web-specific implementation of the cross-platform Video abstraction. + */ + +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import * as RX from 'reactxp'; import extend = require('lodash/extend'); -import React = require('react'); -import RX = require('reactxp'); -import ReactDOM = require('react-dom'); -import Interfaces = require('../common/Interfaces'); -import Types = require('../common/Types'); +import * as Types from '../common/Types'; class Video extends RX.Component { componentDidMount() { // We need to manually install the onEnded handler because. React doesn't support this. - let videoDOM = ReactDOM.findDOMNode(this) as HTMLVideoElement; - videoDOM.onended = () => { - if (this.props.onEnded) { - this.props.onEnded(); - } - }; + const videoDOM = ReactDOM.findDOMNode(this) as HTMLVideoElement | null; + if (videoDOM) { + videoDOM.onended = () => { + if (this.props.onEnded) { + this.props.onEnded(); + } + }; + } } componentWillUnmount() { - let videoDOM = ReactDOM.findDOMNode(this) as HTMLVideoElement; + const videoDOM = ReactDOM.findDOMNode(this) as HTMLVideoElement | null; if (videoDOM) { // Prevent Chrome based browsers to leak video elements videoDOM.src = ''; @@ -36,7 +38,7 @@ class Video extends RX.Component { render() { let combinedStyles = extend(RX.Styles.combine(this.props.style), { - display: 'flex' + display: 'flex', }); if (this.props.resizeMode === 'cover') { @@ -51,70 +53,75 @@ class Video extends RX.Component { WebkitTransform: 'translate(-50%,-50%)', MozTransform: 'translate(-50%,-50%)', msTransform: 'translate(-50%,-50%)', - transform: 'translate(-50%,-50%)' + transform: 'translate(-50%,-50%)', }); } else if (this.props.resizeMode === 'contain') { combinedStyles = extend(combinedStyles, { width: '100%', - height: '100%' + height: '100%', }); } else { combinedStyles = extend(combinedStyles, { width: 'auto', height: 'auto', maxWidth: '100%', - maxHeight: '100%' + maxHeight: '100%', }); } + // The HTML version of video doesn't support numeric-based source + // references, only string-based URIs. + const source = typeof this.props.source === 'string' ? this.props.source : ''; + return (