├── .gitignore ├── LICENSE ├── README.md ├── dist ├── index.d.ts └── index.js ├── ios ├── KeyCommands.xcodeproj │ └── project.pbxproj └── KeyCommands │ ├── RCTKeyCommandConstants.h │ ├── RCTKeyCommandConstants.m │ ├── RCTKeyCommandsManager.h │ ├── RCTKeyCommandsManager.m │ ├── RCTKeyCommandsView.h │ └── RCTKeyCommandsView.m ├── package.json ├── src └── index.tsx ├── tsconfig.json ├── tslint.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # Xcode 61 | # 62 | build/ 63 | *.pbxuser 64 | !default.pbxuser 65 | *.mode1v3 66 | !default.mode1v3 67 | *.mode2v3 68 | !default.mode2v3 69 | *.perspectivev3 70 | !default.perspectivev3 71 | xcuserdata 72 | *.xccheckout 73 | *.moved-aside 74 | DerivedData 75 | *.hmap 76 | *.ipa 77 | *.xcuserstate 78 | project.xcworkspace 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Envoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-key-commands 2 | iOS [UIKeyCommand](https://developer.apple.com/documentation/uikit/uikeycommand) native component for React Native 3 | 4 | ## Install 5 | 6 | ``` 7 | npm install @envoy/react-native-key-commands 8 | ``` 9 | 10 | or 11 | 12 | ``` 13 | yarn add @envoy/react-native-key-commands 14 | ``` 15 | 16 | then 17 | 18 | ``` 19 | react-native link 20 | ``` 21 | 22 | ## Usage 23 | 24 | ```JSX 25 | import React from 'react' 26 | import { NativeSyntheticEvent } from 'react-native' 27 | import KeyCommands, { 28 | KeyCommand, 29 | constants, 30 | } from '@envoy/react-native-key-commands' 31 | 32 | 33 | export default class MyComponent: React.Component { 34 | render () { 35 | return ( 36 | 53 | 54 | {/* .. other views.. */} 55 | 56 | 57 | ) 58 | } 59 | 60 | private onKeyCommand = (event: NativeSyntheticEvent) => { 61 | if (event.nativeEvent.input === '1' && event.keyModifiers === constants.keyModifierCommand) { 62 | // do something here 63 | } 64 | } 65 | } 66 | ``` 67 | 68 | To combine key modifiers, you can use `|` (bit-wise OR) operator, for example, you can define a shortcut `CMD + ALT + C` like this 69 | 70 | ```js 71 | { 72 | input: "c", 73 | keyModifier: constants.keyModifierCommand | constants.,keyModifierAlternate 74 | discoverabilityTitle: "Do something cool" 75 | } 76 | ``` 77 | 78 | ## Constants 79 | 80 | Constants are exposed as `constatns` under the package. You can import it via 81 | 82 | ``` 83 | import { constants } from '@envoy/react-native-key-commands' 84 | ``` 85 | 86 | Here's the value mapping from `constants` to iOS constant values 87 | 88 | - keyModifierShift: UIKeyModifierShift 89 | - keyModifierControl: UIKeyModifierControl 90 | - keyModifierAlternate: UIKeyModifierAlternate 91 | - keyModifierCommand: UIKeyModifierCommand 92 | - keyModifierNumericPad: UIKeyModifierNumericPad 93 | - keyInputUpArrow: UIKeyInputUpArrow 94 | - keyInputDownArrow: UIKeyInputDownArrow 95 | - keyInputLeftArrow: UIKeyInputLeftArrow 96 | - keyInputRightArrow: UIKeyInputRightArrow 97 | - keyInputEscape: UIKeyInputEscape 98 | 99 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { NativeSyntheticEvent, ViewStyle } from 'react-native'; 3 | import React from 'react'; 4 | export declare const constants: { 5 | keyModifierShift: number; 6 | keyModifierControl: number; 7 | keyModifierAlternate: number; 8 | keyModifierCommand: number; 9 | keyModifierNumericPad: number; 10 | keyInputUpArrow: string; 11 | keyInputDownArrow: string; 12 | keyInputLeftArrow: string; 13 | keyInputRightArrow: string; 14 | keyInputEscape: string; 15 | }; 16 | export interface KeyCommand { 17 | input: string; 18 | keyModifier?: number; 19 | discoverabilityTitle?: string; 20 | } 21 | export interface Props { 22 | style?: ViewStyle; 23 | keyCommands: Array; 24 | onKeyCommand?: (event: NativeSyntheticEvent) => void; 25 | testID?: string; 26 | } 27 | export default class KeyCommands extends React.Component { 28 | render(): JSX.Element; 29 | } 30 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | var __rest = (this && this.__rest) || function (s, e) { 2 | var t = {}; 3 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 4 | t[p] = s[p]; 5 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 6 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 7 | t[p[i]] = s[p[i]]; 8 | return t; 9 | }; 10 | import { NativeModules, StyleSheet, requireNativeComponent } from 'react-native'; 11 | import React from 'react'; 12 | const { KeyCommandConstants } = NativeModules; 13 | const RCTKeyCommands = requireNativeComponent('RCTKeyCommands'); 14 | const defaultStyles = StyleSheet.create({ 15 | main: { 16 | backgroundColor: 'transparent' 17 | } 18 | }); 19 | export const constants = { 20 | keyModifierShift: KeyCommandConstants.keyModifierShift, 21 | keyModifierControl: KeyCommandConstants.keyModifierControl, 22 | keyModifierAlternate: KeyCommandConstants.keyModifierAlternate, 23 | keyModifierCommand: KeyCommandConstants.keyModifierCommand, 24 | keyModifierNumericPad: KeyCommandConstants.keyModifierNumericPad, 25 | keyInputUpArrow: KeyCommandConstants.keyInputUpArrow, 26 | keyInputDownArrow: KeyCommandConstants.keyInputDownArrow, 27 | keyInputLeftArrow: KeyCommandConstants.keyInputLeftArrow, 28 | keyInputRightArrow: KeyCommandConstants.keyInputRightArrow, 29 | keyInputEscape: KeyCommandConstants.keyInputEscape, 30 | }; 31 | export default class KeyCommands extends React.Component { 32 | render() { 33 | const _a = this.props, { style } = _a, props = __rest(_a, ["style"]); 34 | return (); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ios/KeyCommands.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 78B1A2FF2058822E00873224 /* RCTKeyCommandsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 78B1A2FD2058822E00873224 /* RCTKeyCommandsView.m */; }; 11 | 78B1A3002058822E00873224 /* RCTKeyCommandsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 78B1A2FE2058822E00873224 /* RCTKeyCommandsManager.m */; }; 12 | 78B1A3062059A7E000873224 /* RCTKeyCommandConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 78B1A3042059A7E000873224 /* RCTKeyCommandConstants.m */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = "include/$(PRODUCT_NAME)"; 20 | dstSubfolderSpec = 16; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 134814201AA4EA6300B7C361 /* libKeyCommands.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKeyCommands.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 78B1A2FB2058822D00873224 /* RCTKeyCommandsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommandsManager.h; sourceTree = ""; }; 30 | 78B1A2FC2058822D00873224 /* RCTKeyCommandsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommandsView.h; sourceTree = ""; }; 31 | 78B1A2FD2058822E00873224 /* RCTKeyCommandsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommandsView.m; sourceTree = ""; }; 32 | 78B1A2FE2058822E00873224 /* RCTKeyCommandsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommandsManager.m; sourceTree = ""; }; 33 | 78B1A3042059A7E000873224 /* RCTKeyCommandConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommandConstants.m; sourceTree = ""; }; 34 | 78B1A3052059A7E000873224 /* RCTKeyCommandConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommandConstants.h; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 134814211AA4EA7D00B7C361 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 134814201AA4EA6300B7C361 /* libKeyCommands.a */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 58B511D21A9E6C8500147676 = { 57 | isa = PBXGroup; 58 | children = ( 59 | D8C1B0701F5F430E00053884 /* KeyCommands */, 60 | 134814211AA4EA7D00B7C361 /* Products */, 61 | ); 62 | indentWidth = 4; 63 | sourceTree = ""; 64 | tabWidth = 4; 65 | }; 66 | D8C1B0701F5F430E00053884 /* KeyCommands */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 78B1A3052059A7E000873224 /* RCTKeyCommandConstants.h */, 70 | 78B1A3042059A7E000873224 /* RCTKeyCommandConstants.m */, 71 | 78B1A2FB2058822D00873224 /* RCTKeyCommandsManager.h */, 72 | 78B1A2FE2058822E00873224 /* RCTKeyCommandsManager.m */, 73 | 78B1A2FC2058822D00873224 /* RCTKeyCommandsView.h */, 74 | 78B1A2FD2058822E00873224 /* RCTKeyCommandsView.m */, 75 | ); 76 | path = KeyCommands; 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXNativeTarget section */ 82 | 58B511DA1A9E6C8500147676 /* KeyCommands */ = { 83 | isa = PBXNativeTarget; 84 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "KeyCommands" */; 85 | buildPhases = ( 86 | 58B511D71A9E6C8500147676 /* Sources */, 87 | 58B511D81A9E6C8500147676 /* Frameworks */, 88 | 58B511D91A9E6C8500147676 /* CopyFiles */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = KeyCommands; 95 | productName = RCTDataManager; 96 | productReference = 134814201AA4EA6300B7C361 /* libKeyCommands.a */; 97 | productType = "com.apple.product-type.library.static"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 58B511D31A9E6C8500147676 /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastSwiftUpdateCheck = 0830; 106 | LastUpgradeCheck = 0610; 107 | ORGANIZATIONNAME = Envoy; 108 | TargetAttributes = { 109 | 58B511DA1A9E6C8500147676 = { 110 | CreatedOnToolsVersion = 6.1.1; 111 | LastSwiftMigration = 0830; 112 | }; 113 | }; 114 | }; 115 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "KeyCommands" */; 116 | compatibilityVersion = "Xcode 3.2"; 117 | developmentRegion = English; 118 | hasScannedForEncodings = 0; 119 | knownRegions = ( 120 | en, 121 | Base, 122 | ); 123 | mainGroup = 58B511D21A9E6C8500147676; 124 | productRefGroup = 58B511D21A9E6C8500147676; 125 | projectDirPath = ""; 126 | projectRoot = ""; 127 | targets = ( 128 | 58B511DA1A9E6C8500147676 /* KeyCommands */, 129 | ); 130 | }; 131 | /* End PBXProject section */ 132 | 133 | /* Begin PBXSourcesBuildPhase section */ 134 | 58B511D71A9E6C8500147676 /* Sources */ = { 135 | isa = PBXSourcesBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | 78B1A3062059A7E000873224 /* RCTKeyCommandConstants.m in Sources */, 139 | 78B1A2FF2058822E00873224 /* RCTKeyCommandsView.m in Sources */, 140 | 78B1A3002058822E00873224 /* RCTKeyCommandsManager.m in Sources */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXSourcesBuildPhase section */ 145 | 146 | /* Begin XCBuildConfiguration section */ 147 | 58B511ED1A9E6C8500147676 /* Debug */ = { 148 | isa = XCBuildConfiguration; 149 | buildSettings = { 150 | ALWAYS_SEARCH_USER_PATHS = NO; 151 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 152 | CLANG_CXX_LIBRARY = "libc++"; 153 | CLANG_ENABLE_MODULES = YES; 154 | CLANG_ENABLE_OBJC_ARC = YES; 155 | CLANG_WARN_BOOL_CONVERSION = YES; 156 | CLANG_WARN_CONSTANT_CONVERSION = YES; 157 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 158 | CLANG_WARN_EMPTY_BODY = YES; 159 | CLANG_WARN_ENUM_CONVERSION = YES; 160 | CLANG_WARN_INT_CONVERSION = YES; 161 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 162 | CLANG_WARN_UNREACHABLE_CODE = YES; 163 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 164 | COPY_PHASE_STRIP = NO; 165 | ENABLE_STRICT_OBJC_MSGSEND = YES; 166 | GCC_C_LANGUAGE_STANDARD = gnu99; 167 | GCC_DYNAMIC_NO_PIC = NO; 168 | GCC_OPTIMIZATION_LEVEL = 0; 169 | GCC_PREPROCESSOR_DEFINITIONS = ( 170 | "DEBUG=1", 171 | "$(inherited)", 172 | ); 173 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 174 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 175 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 176 | GCC_WARN_UNDECLARED_SELECTOR = YES; 177 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 178 | GCC_WARN_UNUSED_FUNCTION = YES; 179 | GCC_WARN_UNUSED_VARIABLE = YES; 180 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 181 | MTL_ENABLE_DEBUG_INFO = YES; 182 | ONLY_ACTIVE_ARCH = YES; 183 | SDKROOT = iphoneos; 184 | }; 185 | name = Debug; 186 | }; 187 | 58B511EE1A9E6C8500147676 /* Release */ = { 188 | isa = XCBuildConfiguration; 189 | buildSettings = { 190 | ALWAYS_SEARCH_USER_PATHS = NO; 191 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 192 | CLANG_CXX_LIBRARY = "libc++"; 193 | CLANG_ENABLE_MODULES = YES; 194 | CLANG_ENABLE_OBJC_ARC = YES; 195 | CLANG_WARN_BOOL_CONVERSION = YES; 196 | CLANG_WARN_CONSTANT_CONVERSION = YES; 197 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 198 | CLANG_WARN_EMPTY_BODY = YES; 199 | CLANG_WARN_ENUM_CONVERSION = YES; 200 | CLANG_WARN_INT_CONVERSION = YES; 201 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 202 | CLANG_WARN_UNREACHABLE_CODE = YES; 203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 204 | COPY_PHASE_STRIP = YES; 205 | ENABLE_NS_ASSERTIONS = NO; 206 | ENABLE_STRICT_OBJC_MSGSEND = YES; 207 | GCC_C_LANGUAGE_STANDARD = gnu99; 208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 210 | GCC_WARN_UNDECLARED_SELECTOR = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 212 | GCC_WARN_UNUSED_FUNCTION = YES; 213 | GCC_WARN_UNUSED_VARIABLE = YES; 214 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 215 | MTL_ENABLE_DEBUG_INFO = NO; 216 | SDKROOT = iphoneos; 217 | VALIDATE_PRODUCT = YES; 218 | }; 219 | name = Release; 220 | }; 221 | 58B511F01A9E6C8500147676 /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | CLANG_ENABLE_MODULES = YES; 225 | HEADER_SEARCH_PATHS = ( 226 | "$(inherited)", 227 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 228 | "$(SRCROOT)/../../React/**", 229 | "$(SRCROOT)/../../node_modules/react-native/React/**", 230 | ); 231 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 232 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 233 | OTHER_LDFLAGS = "-ObjC"; 234 | PRODUCT_NAME = KeyCommands; 235 | SKIP_INSTALL = YES; 236 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 237 | SWIFT_VERSION = 3.0; 238 | }; 239 | name = Debug; 240 | }; 241 | 58B511F11A9E6C8500147676 /* Release */ = { 242 | isa = XCBuildConfiguration; 243 | buildSettings = { 244 | CLANG_ENABLE_MODULES = YES; 245 | HEADER_SEARCH_PATHS = ( 246 | "$(inherited)", 247 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 248 | "$(SRCROOT)/../../React/**", 249 | ); 250 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 251 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 252 | OTHER_LDFLAGS = "-ObjC"; 253 | PRODUCT_NAME = KeyCommands; 254 | SKIP_INSTALL = YES; 255 | SWIFT_VERSION = 3.0; 256 | }; 257 | name = Release; 258 | }; 259 | /* End XCBuildConfiguration section */ 260 | 261 | /* Begin XCConfigurationList section */ 262 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "KeyCommands" */ = { 263 | isa = XCConfigurationList; 264 | buildConfigurations = ( 265 | 58B511ED1A9E6C8500147676 /* Debug */, 266 | 58B511EE1A9E6C8500147676 /* Release */, 267 | ); 268 | defaultConfigurationIsVisible = 0; 269 | defaultConfigurationName = Release; 270 | }; 271 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "KeyCommands" */ = { 272 | isa = XCConfigurationList; 273 | buildConfigurations = ( 274 | 58B511F01A9E6C8500147676 /* Debug */, 275 | 58B511F11A9E6C8500147676 /* Release */, 276 | ); 277 | defaultConfigurationIsVisible = 0; 278 | defaultConfigurationName = Release; 279 | }; 280 | /* End XCConfigurationList section */ 281 | }; 282 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 283 | } 284 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandConstants.h 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/14/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTKeyCommandConstants : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandConstants.m 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/14/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCTKeyCommandConstants.h" 11 | 12 | @implementation RCTKeyCommandConstants 13 | 14 | RCT_EXPORT_MODULE(); 15 | 16 | - (NSDictionary *)constantsToExport { 17 | return @{ 18 | @"keyModifierShift": @(UIKeyModifierAlphaShift), 19 | @"keyModifierControl": @(UIKeyModifierControl), 20 | @"keyModifierAlternate": @(UIKeyModifierAlternate), 21 | @"keyModifierCommand": @(UIKeyModifierCommand), 22 | @"keyModifierNumericPad": @(UIKeyModifierNumericPad), 23 | @"keyInputUpArrow": UIKeyInputUpArrow, 24 | @"keyInputDownArrow": UIKeyInputDownArrow, 25 | @"keyInputLeftArrow": UIKeyInputLeftArrow, 26 | @"keyInputRightArrow": UIKeyInputRightArrow, 27 | @"keyInputEscape": UIKeyInputEscape 28 | }; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandsManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandManager.h 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/13/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTKeyCommandsManager : RCTViewManager 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandsManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandManager.m 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/13/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import "RCTKeyCommandsManager.h" 10 | #import "RCTKeyCommandsView.h" 11 | 12 | @implementation RCTKeyCommandsManager 13 | 14 | RCT_EXPORT_MODULE(); 15 | 16 | RCT_EXPORT_VIEW_PROPERTY(onKeyCommand, RCTBubblingEventBlock) 17 | RCT_CUSTOM_VIEW_PROPERTY(keyCommands, NSArray, RCTKeyCommandsView) { 18 | [view setKeyCommandsWithJSON:json]; 19 | } 20 | 21 | - (UIView *)view { 22 | return [[RCTKeyCommandsView alloc] init]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandView.h 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/13/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTKeyCommandsView : UIView 13 | 14 | @property (nullable, copy) RCTBubblingEventBlock onKeyCommand; 15 | 16 | - (void) setKeyCommandsWithJSON:(id _Nullable)json; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ios/KeyCommands/RCTKeyCommandsView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyCommandsView.m 3 | // Envoy 4 | // 5 | // Created by Fang-Pen Lin on 3/13/18. 6 | // Copyright © 2018 Envoy Inc. All rights reserved. 7 | // 8 | 9 | #import "RCTKeyCommandsView.h" 10 | 11 | @implementation RCTKeyCommandsView { 12 | NSArray *currentKeyCommands; 13 | } 14 | 15 | -(instancetype) init { 16 | self = [super init]; 17 | if (self) { 18 | currentKeyCommands = @[]; 19 | } 20 | return self; 21 | } 22 | 23 | - (BOOL)canBecomeFirstResponder { 24 | return YES; 25 | } 26 | 27 | - (NSArray *)keyCommands { 28 | return currentKeyCommands; 29 | } 30 | 31 | - (void) setKeyCommandsWithJSON:(id)json { 32 | if (!json) { 33 | currentKeyCommands = @[]; 34 | } 35 | NSArray *commandsArray = json; 36 | NSMutableArray *keyCommands = [NSMutableArray array]; 37 | for (NSDictionary *commandJSON in commandsArray) { 38 | NSString *input = commandJSON[@"input"]; 39 | NSNumber *flags = commandJSON[@"modifierFlags"]; 40 | NSString *discoverabilityTitle = commandJSON[@"discoverabilityTitle"]; 41 | if (!flags) { 42 | flags = @0; 43 | } 44 | UIKeyCommand *command; 45 | if (discoverabilityTitle) { 46 | command = [UIKeyCommand keyCommandWithInput:input 47 | modifierFlags:[flags integerValue] 48 | action:@selector(onKeyCommand:) 49 | discoverabilityTitle:discoverabilityTitle]; 50 | } else { 51 | command = [UIKeyCommand keyCommandWithInput:input 52 | modifierFlags:[flags integerValue] 53 | action:@selector(onKeyCommand:)]; 54 | } 55 | [keyCommands addObject:command]; 56 | } 57 | currentKeyCommands = keyCommands; 58 | } 59 | 60 | - (void) onKeyCommand:(UIKeyCommand *)keyCommand { 61 | if (self.onKeyCommand) { 62 | self.onKeyCommand(@{ 63 | @"input": keyCommand.input, 64 | @"modifierFlags": [NSNumber numberWithInteger:keyCommand.modifierFlags], 65 | @"discoverabilityTitle": keyCommand.discoverabilityTitle ? keyCommand.discoverabilityTitle : [NSNull null] 66 | }); 67 | } 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@envoy/react-native-key-commands", 3 | "version": "0.0.5", 4 | "main": "dist/index.js", 5 | "types": "dist/index.d.ts", 6 | "keywords": ["react-native"], 7 | "license": "MIT", 8 | "author": { 9 | "name": "Fang-Pen Lin", 10 | "email": "hello@fangpenlin.com", 11 | "url": "https://fangpenlin.com" 12 | }, 13 | "rnpm": {}, 14 | "devDependencies": { 15 | "@types/node": "^8.0.26", 16 | "@types/react": "^16.0.5", 17 | "@types/react-native": "^0.47.8", 18 | "tslint": "^5.7.0", 19 | "tslint-config-standard": "^6.0.1", 20 | "tslint-react": "^3.2.0", 21 | "typescript": "^2.4.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | NativeModules, 3 | NativeSyntheticEvent, 4 | StyleSheet, 5 | ViewStyle, 6 | requireNativeComponent 7 | } from 'react-native' 8 | 9 | import React from 'react' 10 | 11 | const { KeyCommandConstants } = NativeModules 12 | const RCTKeyCommands = requireNativeComponent('RCTKeyCommands') 13 | const defaultStyles = StyleSheet.create({ 14 | main: { 15 | backgroundColor: 'transparent' 16 | } 17 | }) 18 | 19 | export const constants = { 20 | keyModifierShift: KeyCommandConstants.keyModifierShift as number, 21 | keyModifierControl: KeyCommandConstants.keyModifierControl as number, 22 | keyModifierAlternate: KeyCommandConstants.keyModifierAlternate as number, 23 | keyModifierCommand: KeyCommandConstants.keyModifierCommand as number, 24 | keyModifierNumericPad: KeyCommandConstants.keyModifierNumericPad as number, 25 | keyInputUpArrow: KeyCommandConstants.keyInputUpArrow as string, 26 | keyInputDownArrow: KeyCommandConstants.keyInputDownArrow as string, 27 | keyInputLeftArrow: KeyCommandConstants.keyInputLeftArrow as string, 28 | keyInputRightArrow: KeyCommandConstants.keyInputRightArrow as string, 29 | keyInputEscape: KeyCommandConstants.keyInputEscape as string, 30 | } 31 | 32 | export interface KeyCommand { 33 | /// The input key, could be something like '1' stands for '1' key, 34 | /// constatns like keyInputUpArrow and others can also be used here 35 | input: string 36 | /// Key modifier to be used along with the key press, like Command + Alt 37 | /// can be passed like 38 | /// 39 | /// constatns.keyModifierCommand | constants.keyModifierAlternate 40 | /// 41 | keyModifier?: number 42 | /// Title of discoverability to display, leave it as undefined means we 43 | /// don't want the key command to be displayed in discoverability overlayer 44 | /// UI 45 | discoverabilityTitle?: string 46 | } 47 | 48 | export interface Props { 49 | style?: ViewStyle 50 | /// Key commands 51 | keyCommands: Array 52 | /// Callback function to be called when key command event emits 53 | onKeyCommand?: (event: NativeSyntheticEvent) => void 54 | /// ID for UI automatic testing 55 | testID?: string 56 | } 57 | 58 | export default class KeyCommands extends React.Component { 59 | render () { 60 | const { style, ...props } = this.props 61 | return ( 62 | 65 | ) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "jsx": "react-native", 7 | "skipLibCheck": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strictNullChecks": true, 10 | "noUnusedLocals": true, 11 | "noUnusedParameters": true, 12 | "noImplicitReturns": true, 13 | "declaration": true, 14 | "outDir": "./dist" 15 | }, 16 | "types": ["jest", "node"] 17 | } 18 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint-config-standard", "tslint-react"], 3 | "rules": { 4 | "jsx-alignment": false, 5 | "jsx-boolean-value": [true, "never"], 6 | "jsx-no-multiline-js": false, 7 | "jsx-wrap-multiline": true, 8 | "no-unused-variable": false, 9 | "ter-indent": false, 10 | "object-literal-shorthand": true, 11 | "ter-arrow-body-style": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@^8.0.26": 6 | version "8.9.5" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976" 8 | 9 | "@types/react-native@^0.47.8": 10 | version "0.47.9" 11 | resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.47.9.tgz#7e7f3d8d25c46e8b6e8ad3b11d0222de0722f820" 12 | dependencies: 13 | "@types/react" "*" 14 | 15 | "@types/react@*", "@types/react@^16.0.5": 16 | version "16.0.40" 17 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.40.tgz#caabc2296886f40b67f6fc80f0f3464476461df9" 18 | 19 | ansi-regex@^2.0.0: 20 | version "2.1.1" 21 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 22 | 23 | ansi-styles@^2.2.1: 24 | version "2.2.1" 25 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 26 | 27 | ansi-styles@^3.2.1: 28 | version "3.2.1" 29 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 30 | dependencies: 31 | color-convert "^1.9.0" 32 | 33 | argparse@^1.0.7: 34 | version "1.0.10" 35 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 36 | dependencies: 37 | sprintf-js "~1.0.2" 38 | 39 | babel-code-frame@^6.22.0: 40 | version "6.26.0" 41 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 42 | dependencies: 43 | chalk "^1.1.3" 44 | esutils "^2.0.2" 45 | js-tokens "^3.0.2" 46 | 47 | balanced-match@^1.0.0: 48 | version "1.0.0" 49 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 50 | 51 | brace-expansion@^1.1.7: 52 | version "1.1.11" 53 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 54 | dependencies: 55 | balanced-match "^1.0.0" 56 | concat-map "0.0.1" 57 | 58 | builtin-modules@^1.1.1: 59 | version "1.1.1" 60 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 61 | 62 | chalk@^1.1.3: 63 | version "1.1.3" 64 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 65 | dependencies: 66 | ansi-styles "^2.2.1" 67 | escape-string-regexp "^1.0.2" 68 | has-ansi "^2.0.0" 69 | strip-ansi "^3.0.0" 70 | supports-color "^2.0.0" 71 | 72 | chalk@^2.3.0: 73 | version "2.3.2" 74 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" 75 | dependencies: 76 | ansi-styles "^3.2.1" 77 | escape-string-regexp "^1.0.5" 78 | supports-color "^5.3.0" 79 | 80 | color-convert@^1.9.0: 81 | version "1.9.1" 82 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 83 | dependencies: 84 | color-name "^1.1.1" 85 | 86 | color-name@^1.1.1: 87 | version "1.1.3" 88 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 89 | 90 | commander@^2.12.1: 91 | version "2.15.0" 92 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.0.tgz#ad2a23a1c3b036e392469b8012cec6b33b4c1322" 93 | 94 | concat-map@0.0.1: 95 | version "0.0.1" 96 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 97 | 98 | diff@^3.2.0: 99 | version "3.5.0" 100 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 101 | 102 | doctrine@^0.7.2: 103 | version "0.7.2" 104 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" 105 | dependencies: 106 | esutils "^1.1.6" 107 | isarray "0.0.1" 108 | 109 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 110 | version "1.0.5" 111 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 112 | 113 | esprima@^4.0.0: 114 | version "4.0.0" 115 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" 116 | 117 | esutils@^1.1.6: 118 | version "1.1.6" 119 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" 120 | 121 | esutils@^2.0.2: 122 | version "2.0.2" 123 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 124 | 125 | fs.realpath@^1.0.0: 126 | version "1.0.0" 127 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 128 | 129 | glob@^7.1.1: 130 | version "7.1.2" 131 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 132 | dependencies: 133 | fs.realpath "^1.0.0" 134 | inflight "^1.0.4" 135 | inherits "2" 136 | minimatch "^3.0.4" 137 | once "^1.3.0" 138 | path-is-absolute "^1.0.0" 139 | 140 | has-ansi@^2.0.0: 141 | version "2.0.0" 142 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 143 | dependencies: 144 | ansi-regex "^2.0.0" 145 | 146 | has-flag@^3.0.0: 147 | version "3.0.0" 148 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 149 | 150 | inflight@^1.0.4: 151 | version "1.0.6" 152 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 153 | dependencies: 154 | once "^1.3.0" 155 | wrappy "1" 156 | 157 | inherits@2: 158 | version "2.0.3" 159 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 160 | 161 | isarray@0.0.1: 162 | version "0.0.1" 163 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 164 | 165 | js-tokens@^3.0.2: 166 | version "3.0.2" 167 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 168 | 169 | js-yaml@^3.7.0: 170 | version "3.11.0" 171 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" 172 | dependencies: 173 | argparse "^1.0.7" 174 | esprima "^4.0.0" 175 | 176 | minimatch@^3.0.4: 177 | version "3.0.4" 178 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 179 | dependencies: 180 | brace-expansion "^1.1.7" 181 | 182 | once@^1.3.0: 183 | version "1.4.0" 184 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 185 | dependencies: 186 | wrappy "1" 187 | 188 | path-is-absolute@^1.0.0: 189 | version "1.0.1" 190 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 191 | 192 | path-parse@^1.0.5: 193 | version "1.0.5" 194 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 195 | 196 | resolve@^1.3.2: 197 | version "1.5.0" 198 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" 199 | dependencies: 200 | path-parse "^1.0.5" 201 | 202 | semver@^5.3.0: 203 | version "5.5.0" 204 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" 205 | 206 | sprintf-js@~1.0.2: 207 | version "1.0.3" 208 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 209 | 210 | strip-ansi@^3.0.0: 211 | version "3.0.1" 212 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 213 | dependencies: 214 | ansi-regex "^2.0.0" 215 | 216 | supports-color@^2.0.0: 217 | version "2.0.0" 218 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 219 | 220 | supports-color@^5.3.0: 221 | version "5.3.0" 222 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" 223 | dependencies: 224 | has-flag "^3.0.0" 225 | 226 | tslib@^1.0.0, tslib@^1.8.0, tslib@^1.8.1: 227 | version "1.9.0" 228 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" 229 | 230 | tslint-config-standard@^6.0.1: 231 | version "6.0.1" 232 | resolved "https://registry.yarnpkg.com/tslint-config-standard/-/tslint-config-standard-6.0.1.tgz#a04ba0a794759e877287056f549b081e47a56d6c" 233 | dependencies: 234 | tslint-eslint-rules "^4.0.0" 235 | 236 | tslint-eslint-rules@^4.0.0: 237 | version "4.1.1" 238 | resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz#7c30e7882f26bc276bff91d2384975c69daf88ba" 239 | dependencies: 240 | doctrine "^0.7.2" 241 | tslib "^1.0.0" 242 | tsutils "^1.4.0" 243 | 244 | tslint-react@^3.2.0: 245 | version "3.5.1" 246 | resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.5.1.tgz#a5ca48034bf583fb63b42763bb89fa23062d5390" 247 | dependencies: 248 | tsutils "^2.13.1" 249 | 250 | tslint@^5.7.0: 251 | version "5.9.1" 252 | resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" 253 | dependencies: 254 | babel-code-frame "^6.22.0" 255 | builtin-modules "^1.1.1" 256 | chalk "^2.3.0" 257 | commander "^2.12.1" 258 | diff "^3.2.0" 259 | glob "^7.1.1" 260 | js-yaml "^3.7.0" 261 | minimatch "^3.0.4" 262 | resolve "^1.3.2" 263 | semver "^5.3.0" 264 | tslib "^1.8.0" 265 | tsutils "^2.12.1" 266 | 267 | tsutils@^1.4.0: 268 | version "1.9.1" 269 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.9.1.tgz#b9f9ab44e55af9681831d5f28d0aeeaf5c750cb0" 270 | 271 | tsutils@^2.12.1, tsutils@^2.13.1: 272 | version "2.22.2" 273 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.22.2.tgz#0b9f3d87aa3eb95bd32d26ce2b88aa329a657951" 274 | dependencies: 275 | tslib "^1.8.1" 276 | 277 | typescript@^2.4.2: 278 | version "2.7.2" 279 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" 280 | 281 | wrappy@1: 282 | version "1.0.2" 283 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 284 | --------------------------------------------------------------------------------